summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-07-25 17:25:11 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-07-25 17:25:11 -0700
commit65289e84ed2b9e7abff7e38164fe1ee133c7ff32 (patch)
tree897ca06f077ce3e73bdeb61f9623adb0cc299e90
parent2ec4ad8556d1ed70bc37eee7cd46021f806799c7 (diff)
downloadnasm-65289e84ed2b9e7abff7e38164fe1ee133c7ff32.tar.gz
assemble: replace random integers with an enum for match results
Match results were reported with random integers. Replace with an enum. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--assemble.c86
1 files changed, 53 insertions, 33 deletions
diff --git a/assemble.c b/assemble.c
index e8c28166..aafbee80 100644
--- a/assemble.c
+++ b/assemble.c
@@ -162,6 +162,23 @@
#include "insns.h"
#include "tables.h"
+enum match_result {
+ /*
+ * Matching errors. These should be sorted so that more specific
+ * errors come later in the sequence.
+ */
+ MERR_INVALOP,
+ MERR_OPSIZEMISSING,
+ MERR_OPSIZEMISMATCH,
+ MERR_BADCPU,
+ MERR_BADMODE,
+ /*
+ * Matching success; the conditional ones first
+ */
+ MOK_JUMP, /* Matching OK but needs jmp_match() */
+ MOK_GOOD /* Matching unconditionally OK */
+};
+
typedef struct {
int sib_present; /* is a SIB byte necessary? */
int bytes; /* # of bytes of offset needed */
@@ -178,7 +195,7 @@ static int64_t calcsize(int32_t, int64_t, int, insn *, const uint8_t *);
static void gencode(int32_t segment, int64_t offset, int bits,
insn * ins, const struct itemplate *temp,
int64_t insn_end);
-static int matches(const struct itemplate *, insn *, int bits);
+static enum match_result matches(const struct itemplate *, insn *, int bits);
static int32_t regflag(const operand *);
static int32_t regval(const operand *);
static int rexflags(int, int32_t, int);
@@ -306,12 +323,12 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits,
}
int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
- insn * instruction, struct ofmt *output, efunc error,
- ListGen * listgen)
+ insn * instruction, struct ofmt *output, efunc error,
+ ListGen * listgen)
{
const struct itemplate *temp;
int j;
- int size_prob;
+ enum match_result size_prob;
int64_t insn_end;
int32_t itimes;
int64_t start = offset;
@@ -482,16 +499,17 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
/* Check to see if we need an address-size prefix */
add_asp(instruction, bits);
- size_prob = 0;
+ size_prob = MERR_INVALOP;
- for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){
- int m = matches(temp, instruction, bits);
- if (m == 100 ||
- (m == 99 && jmp_match(segment, offset, bits,
- instruction, temp->code))) {
+ for (temp = nasm_instructions[instruction->opcode];
+ temp->opcode != -1; temp++){
+ enum match_result m = matches(temp, instruction, bits);
+ if (m == MOK_GOOD ||
+ (m == MOK_JUMP && jmp_match(segment, offset, bits,
+ instruction, temp->code))) {
/* Matches! */
int64_t insn_size = calcsize(segment, offset, bits,
- instruction, temp->code);
+ instruction, temp->code);
itimes = instruction->times;
if (insn_size < 0) /* shouldn't be, on pass two */
error(ERR_PANIC, "errors made it through from pass one");
@@ -624,16 +642,16 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
if (temp->opcode == -1) { /* didn't match any instruction */
switch (size_prob) {
- case 1:
+ case MERR_OPSIZEMISSING:
error(ERR_NONFATAL, "operation size not specified");
break;
- case 2:
+ case MERR_OPSIZEMISMATCH:
error(ERR_NONFATAL, "mismatch in operand sizes");
break;
- case 3:
+ case MERR_BADCPU:
error(ERR_NONFATAL, "no instruction for this cpu level");
break;
- case 4:
+ case MERR_BADMODE:
error(ERR_NONFATAL, "instruction not supported in %d-bit mode",
bits);
break;
@@ -647,7 +665,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
}
int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
- insn * instruction, efunc error)
+ insn * instruction, efunc error)
{
const struct itemplate *temp;
@@ -739,11 +757,12 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
/* Check to see if we need an address-size prefix */
add_asp(instruction, bits);
- for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++) {
- int m = matches(temp, instruction, bits);
- if (m == 100 ||
- (m == 99 && jmp_match(segment, offset, bits,
- instruction, temp->code))) {
+ for (temp = nasm_instructions[instruction->opcode];
+ temp->opcode != -1; temp++) {
+ enum match_result m = matches(temp, instruction, bits);
+ if (m == MOK_GOOD ||
+ (m == MOK_JUMP && jmp_match(segment, offset, bits,
+ instruction, temp->code))) {
/* we've matched an instruction. */
int64_t isize;
const uint8_t *codes = temp->code;
@@ -1967,30 +1986,31 @@ static int rexflags(int val, int32_t flags, int mask)
return rex & mask;
}
-static int matches(const struct itemplate *itemp, insn * instruction, int bits)
+static enum match_result matches(const struct itemplate *itemp,
+ insn *instruction, int bits)
{
int i, size[MAX_OPERANDS], asize, oprs, ret;
- ret = 100;
+ ret = MOK_GOOD;
/*
* Check the opcode
*/
if (itemp->opcode != instruction->opcode)
- return 0;
+ return MERR_INVALOP;
/*
* Count the operands
*/
if (itemp->operands != instruction->operands)
- return 0;
+ return MERR_INVALOP;
/*
* Check that no spurious colons or TOs are present
*/
for (i = 0; i < itemp->operands; i++)
if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
- return 0;
+ return MERR_INVALOP;
/*
* Process size flags
@@ -2088,15 +2108,15 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
int j = itemp->opd[i] & ~SAME_AS;
if (type != instruction->oprs[j].type ||
instruction->oprs[i].basereg != instruction->oprs[j].basereg)
- return 0;
+ return MERR_INVALOP;
} else if (itemp->opd[i] & ~type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ type) & SIZE_MASK))) {
if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
(type & SIZE_MASK))
- return 0;
+ return MERR_INVALOP;
else
- return 1;
+ return MERR_OPSIZEMISSING;
}
}
@@ -2121,26 +2141,26 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
for (i = 0; i < itemp->operands; i++) {
if (!(itemp->opd[i] & SIZE_MASK) &&
(instruction->oprs[i].type & SIZE_MASK & ~size[i]))
- return 2;
+ return MERR_OPSIZEMISMATCH;
}
/*
* Check template is okay at the set cpu level
*/
if (((itemp->flags & IF_PLEVEL) > cpu))
- return 3;
+ return MERR_BADCPU;
/*
* Verify the appropriate long mode flag.
*/
if ((itemp->flags & (bits == 64 ? IF_NOLONG : IF_LONG)))
- return 4;
+ return MERR_BADMODE;
/*
* Check if special handling needed for Jumps
*/
if ((uint8_t)(itemp->code[0]) >= 0370)
- return 99;
+ return MOK_JUMP;
return ret;
}