Skip to content

Commit

Permalink
don't warn for literal b with IFx
Browse files Browse the repository at this point in the history
  • Loading branch information
jonpovey committed Jun 4, 2012
1 parent b6f7b29 commit a7d6167
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 50 deletions.
38 changes: 20 additions & 18 deletions src/dasdefs.c
Expand Up @@ -15,9 +15,9 @@
* macro magic. use GCC designated initialisers to build a sparse array
* of strings indexed by opcode. special opcodes are offset by 0x20
*/
#define OP(val, op, count) [val] = #op
#define SOP(val, op, count) [val | SPECIAL_OPCODE] = #op
static char *opcodes[64] = { OPCODES SPECIAL_OPCODES };
#define OP(val, op, count, wb) [val] = { .name = #op, .warn_b = wb }
#define SOP(val, op, count) [val | SPECIAL_OPCODE] = { .name = #op }
static struct opcode opcodes[64] = { OPCODES SPECIAL_OPCODES };
#undef OP
#undef SOP

Expand All @@ -31,18 +31,6 @@ static char *opcodes[64] = { OPCODES SPECIAL_OPCODES };
static struct reg registers[] = { REGISTERS };
#undef REGISTER

int arrsearch(char *str, char **arr, int arrsize)
{
int i;

for (i = 0; i < arrsize; i++) {
if (arr[i] && 0 == strcasecmp(str, arr[i]))
return i;
}
fprintf(stderr, "BUG '%s' not found!\n", str);
return -1;
}

int valid_reg(int reg)
{
/* reg 0 is not valid, it means "no register" */
Expand All @@ -51,19 +39,26 @@ int valid_reg(int reg)

int valid_opcode(int op)
{
return op >= 0 && op < ARRAY_SIZE(opcodes) && opcodes[op];
return op >= 0 && op < ARRAY_SIZE(opcodes) && opcodes[op].name;
}

/* get op value for an opcode string */
int str2opcode(char *str)
{
return arrsearch(str, opcodes, ARRAY_SIZE(opcodes));
int i;

for (i = 0; i < ARRAY_SIZE(opcodes); i++) {
if (opcodes[i].name && 0 == strcasecmp(str, opcodes[i].name))
return i;
}
fprintf(stderr, "BUG opcode '%s' not found!\n", str);
return -1;
}

char* opcode2str(int op)
{
assert(valid_opcode(op));
return opcodes[op];
return opcodes[op].name;
}

u16 opcode2bits(int opcode)
Expand All @@ -84,6 +79,13 @@ int is_special(int opcode)
return opcode & SPECIAL_OPCODE;
}

int opcode_warn_b_literal(int opcode)
{
if (BUG_ON(!valid_opcode(opcode)))
return 0;
return opcodes[opcode].warn_b;
}

int str2reg(char *str)
{
int i;
Expand Down
62 changes: 34 additions & 28 deletions src/dasdefs.h
Expand Up @@ -8,6 +8,11 @@
typedef unsigned short u16;
typedef signed short s16;

struct opcode {
char *name;
int warn_b; /* warn if b is literal (discarded write) */
};

struct reg {
u16 valbits;
char *name;
Expand All @@ -18,6 +23,7 @@ int str2opcode(char *str);
char* opcode2str(int op);
u16 opcode2bits(int opcode);
int is_special(int opcode);
int opcode_warn_b_literal(int opcode);

int str2reg(char *str);
char* reg2str(int reg);
Expand All @@ -33,35 +39,35 @@ int sprint_cstring(char *buf, const unsigned char *str, int bytes);
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif // #ifndef ARRAY_SIZE

/* Opcodes: OP(opcode value, name, minimum cycle count) */
/* Opcodes: OP(opcode value, name, minimum cycle count, warn if b written) */
#define OPCODES \
OP(0x01, SET, 1), \
OP(0x02, ADD, 2), \
OP(0x03, SUB, 3), \
OP(0x04, MUL, 2), \
OP(0x05, MLI, 2), \
OP(0x06, DIV, 3), \
OP(0x07, DVI, 3), \
OP(0x08, MOD, 3), \
OP(0x09, MDI, 3), \
OP(0x0a, AND, 1), \
OP(0x0b, BOR, 1), \
OP(0x0c, XOR, 1), \
OP(0x0d, SHR, 2), \
OP(0x0e, ASR, 2), \
OP(0x0f, SHL, 2), \
OP(0x10, IFB, 2), \
OP(0x11, IFC, 2), \
OP(0x12, IFE, 2), \
OP(0x13, IFN, 2), \
OP(0x14, IFG, 2), \
OP(0x15, IFA, 2), \
OP(0x16, IFL, 2), \
OP(0x17, IFU, 2), \
OP(0x1a, ADX, 3), \
OP(0x1b, SBX, 3), \
OP(0x1e, STI, 2), \
OP(0x1f, STD, 2),
OP(0x01, SET, 1, 1), \
OP(0x02, ADD, 2, 1), \
OP(0x03, SUB, 3, 1), \
OP(0x04, MUL, 2, 1), \
OP(0x05, MLI, 2, 1), \
OP(0x06, DIV, 3, 1), \
OP(0x07, DVI, 3, 1), \
OP(0x08, MOD, 3, 1), \
OP(0x09, MDI, 3, 1), \
OP(0x0a, AND, 1, 1), \
OP(0x0b, BOR, 1, 1), \
OP(0x0c, XOR, 1, 1), \
OP(0x0d, SHR, 2, 1), \
OP(0x0e, ASR, 2, 1), \
OP(0x0f, SHL, 2, 1), \
OP(0x10, IFB, 2, 0), \
OP(0x11, IFC, 2, 0), \
OP(0x12, IFE, 2, 0), \
OP(0x13, IFN, 2, 0), \
OP(0x14, IFG, 2, 0), \
OP(0x15, IFA, 2, 0), \
OP(0x16, IFL, 2, 0), \
OP(0x17, IFU, 2, 0), \
OP(0x1a, ADX, 3, 1), \
OP(0x1b, SBX, 3, 1), \
OP(0x1e, STI, 2, 1), \
OP(0x1f, STD, 2, 1),

#define SPECIAL_OPCODES \
SOP(0x01, JSR, 3), \
Expand Down
8 changes: 4 additions & 4 deletions src/instruction.c
Expand Up @@ -63,7 +63,7 @@ int mask_constant(int value, s16 *bits)
}

/* validation pass checks on an operand */
int operand_validate(struct operand *o)
int operand_validate(struct operand *o, int warn_b_literal)
{
/* I'm going to use das_error kind of like stdlib errno now.
* This may be evil and hacky, not decided yet.
Expand Down Expand Up @@ -138,7 +138,7 @@ int operand_validate(struct operand *o)
if (o->reg == REG_POP) {
loc_err(o->loc, "POP not usable as destination ('b') operand");
}
if (o->expr && !o->reg && !o->indirect) {
if (warn_b_literal && o->expr && !o->reg && !o->indirect) {
/*
* literal destination will be ignored, warn. Maybe has valid use
* for arithmetic, EX things?
Expand Down Expand Up @@ -216,10 +216,10 @@ static int instruction_validate(void *private)
* validating operands individually?
*/
if (i->a) {
ret += operand_validate(i->a);
ret += operand_validate(i->a, 0);
}
if (i->b) {
ret += operand_validate(i->b);
ret += operand_validate(i->b, opcode_warn_b_literal(i->opcode));
}
return ret;
}
Expand Down

0 comments on commit a7d6167

Please sign in to comment.