Clean up the handing of operands in assemble.c

assemble.c was full of code containing ins->oprs[c - 0xxx] where 0xxx
was the base of the particular code block.  Verbose and error prone
when code is moved around.  Now we precompute opx = &ins->oprs[c & 3]
before dispatching, resulting in less code.
This commit is contained in:
H. Peter Anvin 2007-10-29 23:12:47 -07:00
parent 10e2727133
commit 839eca23e4

View File

@ -789,6 +789,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
uint8_t c;
int rex_mask = ~0;
ins->rex = 0; /* Ensure REX is reset */
struct operand *opx;
if (ins->prefixes[PPS_OSIZE] == P_O64)
ins->rex |= REX_W;
@ -796,8 +797,10 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
(void)segment; /* Don't warn that this parameter is unused */
(void)offset; /* Don't warn that this parameter is unused */
while (*codes)
switch (c = *codes++) {
while (*codes) {
c = *codes++;
opx = &ins->oprs[c & 3];
switch (c) {
case 01:
case 02:
case 03:
@ -814,7 +817,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 012:
case 013:
ins->rex |=
op_rexflags(&ins->oprs[c - 010], REX_B|REX_H|REX_P|REX_W);
op_rexflags(opx, REX_B|REX_H|REX_P|REX_W);
codes++, length++;
break;
case 014:
@ -845,8 +848,8 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 035:
case 036:
case 037:
if (ins->oprs[c - 034].type & (BITS16 | BITS32 | BITS64))
length += (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
if (opx->type & (BITS16 | BITS32 | BITS64))
length += (opx->type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
break;
@ -884,8 +887,8 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 065:
case 066:
case 067:
if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
if (opx->type & (BITS16 | BITS32 | BITS64))
length += (opx->type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
break;
@ -905,7 +908,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 0141:
case 0142:
case 0143:
length += is_sbyte(ins, c - 0140, 16) ? 1 : 2;
length += is_sbyte(ins, c & 3, 16) ? 1 : 2;
break;
case 0144:
case 0145:
@ -918,7 +921,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 0151:
case 0152:
case 0153:
length += is_sbyte(ins, c - 0150, 32) ? 1 : 4;
length += is_sbyte(ins, c & 3, 32) ? 1 : 4;
break;
case 0154:
case 0155:
@ -1003,7 +1006,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
" quantity of BSS space");
else
length += ins->oprs[0].offset << (c - 0340);
length += ins->oprs[0].offset << (c & 3);
break;
case 0364:
case 0365:
@ -1044,10 +1047,12 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
ins->rex |= ea_data.rex;
length += ea_data.size;
}
} else
} else {
errfunc(ERR_PANIC, "internal instruction table corrupt"
": instruction code 0x%02X given", c);
}
}
}
ins->rex &= rex_mask;
@ -1103,9 +1108,12 @@ static void gencode(int32_t segment, int32_t offset, int bits,
uint8_t bytes[4];
int32_t size;
int64_t data;
struct operand *opx;
while (*codes)
switch (c = *codes++) {
while (*codes) {
c = *codes++;
opx = &ins->oprs[c & 3];
switch (c) {
case 01:
case 02:
case 03:
@ -1160,7 +1168,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 012:
case 013:
EMIT_REX();
bytes[0] = *codes++ + ((regval(&ins->oprs[c - 010])) & 7);
bytes[0] = *codes++ + ((regval(opx)) & 7);
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
offset += 1;
break;
@ -1169,17 +1177,16 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 015:
case 016:
case 017:
if (ins->oprs[c - 014].offset < -128
|| ins->oprs[c - 014].offset > 127) {
if (opx->offset < -128 || opx->offset > 127) {
errfunc(ERR_WARNING, "signed byte value exceeds bounds");
}
if (ins->oprs[c - 014].segment != NO_SEG) {
data = ins->oprs[c - 014].offset;
if (opx->segment != NO_SEG) {
data = opx->offset;
out(offset, segment, &data, OUT_ADDRESS + 1,
ins->oprs[c - 014].segment, ins->oprs[c - 014].wrt);
opx->segment, opx->wrt);
} else {
bytes[0] = ins->oprs[c - 014].offset;
bytes[0] = opx->offset;
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
NO_SEG);
}
@ -1190,16 +1197,15 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 021:
case 022:
case 023:
if (ins->oprs[c - 020].offset < -256
|| ins->oprs[c - 020].offset > 255) {
if (opx->offset < -256 || opx->offset > 255) {
errfunc(ERR_WARNING, "byte value exceeds bounds");
}
if (ins->oprs[c - 020].segment != NO_SEG) {
data = ins->oprs[c - 020].offset;
if (opx->segment != NO_SEG) {
data = opx->offset;
out(offset, segment, &data, OUT_ADDRESS + 1,
ins->oprs[c - 020].segment, ins->oprs[c - 020].wrt);
opx->segment, opx->wrt);
} else {
bytes[0] = ins->oprs[c - 020].offset;
bytes[0] = opx->offset;
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
NO_SEG);
}
@ -1210,15 +1216,14 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 025:
case 026:
case 027:
if (ins->oprs[c - 024].offset < 0
|| ins->oprs[c - 024].offset > 255)
if (opx->offset < 0 || opx->offset > 255)
errfunc(ERR_WARNING, "unsigned byte value exceeds bounds");
if (ins->oprs[c - 024].segment != NO_SEG) {
data = ins->oprs[c - 024].offset;
if (opx->segment != NO_SEG) {
data = opx->offset;
out(offset, segment, &data, OUT_ADDRESS + 1,
ins->oprs[c - 024].segment, ins->oprs[c - 024].wrt);
opx->segment, opx->wrt);
} else {
bytes[0] = ins->oprs[c - 024].offset;
bytes[0] = opx->offset;
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
NO_SEG);
}
@ -1229,12 +1234,11 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 031:
case 032:
case 033:
data = ins->oprs[c - 030].offset;
if (ins->oprs[c - 030].segment == NO_SEG &&
ins->oprs[c - 030].wrt == NO_SEG)
data = opx->offset;
if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
warn_overflow(2, data);
out(offset, segment, &data, OUT_ADDRESS + 2,
ins->oprs[c - 030].segment, ins->oprs[c - 030].wrt);
opx->segment, opx->wrt);
offset += 2;
break;
@ -1242,16 +1246,15 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 035:
case 036:
case 037:
if (ins->oprs[c - 034].type & (BITS16 | BITS32))
size = (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
if (opx->type & (BITS16 | BITS32))
size = (opx->type & BITS16) ? 2 : 4;
else
size = (bits == 16) ? 2 : 4;
data = ins->oprs[c - 034].offset;
if (ins->oprs[c - 034].segment == NO_SEG &&
ins->oprs[c - 034].wrt == NO_SEG)
data = opx->offset;
if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
warn_overflow(size, data);
out(offset, segment, &data, OUT_ADDRESS + size,
ins->oprs[c - 034].segment, ins->oprs[c - 034].wrt);
opx->segment, opx->wrt);
offset += size;
break;
@ -1259,9 +1262,9 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 041:
case 042:
case 043:
data = ins->oprs[c - 040].offset;
data = opx->offset;
out(offset, segment, &data, OUT_ADDRESS + 4,
ins->oprs[c - 040].segment, ins->oprs[c - 040].wrt);
opx->segment, opx->wrt);
offset += 4;
break;
@ -1269,13 +1272,13 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 045:
case 046:
case 047:
data = ins->oprs[c - 044].offset;
data = opx->offset;
size = ins->addr_size >> 3;
if (ins->oprs[c - 044].segment == NO_SEG &&
ins->oprs[c - 044].wrt == NO_SEG)
if (opx->segment == NO_SEG &&
opx->wrt == NO_SEG)
warn_overflow(size, data);
out(offset, segment, &data, OUT_ADDRESS + size,
ins->oprs[c - 044].segment, ins->oprs[c - 044].wrt);
opx->segment, opx->wrt);
offset += size;
break;
@ -1283,10 +1286,10 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 051:
case 052:
case 053:
if (ins->oprs[c - 050].segment != segment)
if (opx->segment != segment)
errfunc(ERR_NONFATAL,
"short relative jump outside segment");
data = ins->oprs[c - 050].offset - insn_end;
data = opx->offset - insn_end;
if (data > 127 || data < -128)
errfunc(ERR_NONFATAL, "short jump is out of range");
bytes[0] = data;
@ -1298,9 +1301,9 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 055:
case 056:
case 057:
data = (int64_t)ins->oprs[c - 054].offset;
data = (int64_t)opx->offset;
out(offset, segment, &data, OUT_ADDRESS + 8,
ins->oprs[c - 054].segment, ins->oprs[c - 054].wrt);
opx->segment, opx->wrt);
offset += 8;
break;
@ -1308,13 +1311,13 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 061:
case 062:
case 063:
if (ins->oprs[c - 060].segment != segment) {
data = ins->oprs[c - 060].offset;
if (opx->segment != segment) {
data = opx->offset;
out(offset, segment, &data,
OUT_REL2ADR + insn_end - offset,
ins->oprs[c - 060].segment, ins->oprs[c - 060].wrt);
opx->segment, opx->wrt);
} else {
data = ins->oprs[c - 060].offset - insn_end;
data = opx->offset - insn_end;
out(offset, segment, &data,
OUT_ADDRESS + 2, NO_SEG, NO_SEG);
}
@ -1325,17 +1328,17 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 065:
case 066:
case 067:
if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
if (opx->type & (BITS16 | BITS32 | BITS64))
size = (opx->type & BITS16) ? 2 : 4;
else
size = (bits == 16) ? 2 : 4;
if (ins->oprs[c - 064].segment != segment) {
if (opx->segment != segment) {
int32_t reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR);
data = ins->oprs[c - 064].offset;
data = opx->offset;
out(offset, segment, &data, reltype + insn_end - offset,
ins->oprs[c - 064].segment, ins->oprs[c - 064].wrt);
opx->segment, opx->wrt);
} else {
data = ins->oprs[c - 064].offset - insn_end;
data = opx->offset - insn_end;
out(offset, segment, &data,
OUT_ADDRESS + size, NO_SEG, NO_SEG);
}
@ -1346,13 +1349,13 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 071:
case 072:
case 073:
if (ins->oprs[c - 070].segment != segment) {
data = ins->oprs[c - 070].offset;
if (opx->segment != segment) {
data = opx->offset;
out(offset, segment, &data,
OUT_REL4ADR + insn_end - offset,
ins->oprs[c - 070].segment, ins->oprs[c - 070].wrt);
opx->segment, opx->wrt);
} else {
data = ins->oprs[c - 070].offset - insn_end;
data = opx->offset - insn_end;
out(offset, segment, &data,
OUT_ADDRESS + 4, NO_SEG, NO_SEG);
}
@ -1363,13 +1366,13 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 075:
case 076:
case 077:
if (ins->oprs[c - 074].segment == NO_SEG)
if (opx->segment == NO_SEG)
errfunc(ERR_NONFATAL, "value referenced by FAR is not"
" relocatable");
data = 0L;
out(offset, segment, &data, OUT_ADDRESS + 2,
outfmt->segbase(1 + ins->oprs[c - 074].segment),
ins->oprs[c - 074].wrt);
outfmt->segbase(1 + opx->segment),
opx->wrt);
offset += 2;
break;
@ -1377,18 +1380,18 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 0141:
case 0142:
case 0143:
data = ins->oprs[c - 0140].offset;
if (is_sbyte(ins, c - 0140, 16)) {
data = opx->offset;
if (is_sbyte(ins, c & 3, 16)) {
bytes[0] = data;
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
NO_SEG);
offset++;
} else {
if (ins->oprs[c - 0140].segment == NO_SEG &&
ins->oprs[c - 0140].wrt == NO_SEG)
if (opx->segment == NO_SEG &&
opx->wrt == NO_SEG)
warn_overflow(2, data);
out(offset, segment, &data, OUT_ADDRESS + 2,
ins->oprs[c - 0140].segment, ins->oprs[c - 0140].wrt);
opx->segment, opx->wrt);
offset += 2;
}
break;
@ -1400,7 +1403,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
EMIT_REX();
codes++;
bytes[0] = *codes++;
if (is_sbyte(ins, c - 0144, 16))
if (is_sbyte(ins, c & 3, 16))
bytes[0] |= 2; /* s-bit */
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
offset++;
@ -1410,15 +1413,15 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 0151:
case 0152:
case 0153:
data = ins->oprs[c - 0150].offset;
if (is_sbyte(ins, c - 0150, 32)) {
data = opx->offset;
if (is_sbyte(ins, c & 3, 32)) {
bytes[0] = data;
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
NO_SEG);
offset++;
} else {
out(offset, segment, &data, OUT_ADDRESS + 4,
ins->oprs[c - 0150].segment, ins->oprs[c - 0150].wrt);
opx->segment, opx->wrt);
offset += 4;
}
break;
@ -1430,7 +1433,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
EMIT_REX();
codes++;
bytes[0] = *codes++;
if (is_sbyte(ins, c - 0154, 32))
if (is_sbyte(ins, c & 3, 32))
bytes[0] |= 2; /* s-bit */
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
offset++;
@ -1558,7 +1561,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
if (ins->oprs[0].segment != NO_SEG)
errfunc(ERR_PANIC, "non-constant BSS size in pass two");
else {
int32_t size = ins->oprs[0].offset << (c - 0340);
int32_t size = ins->oprs[0].offset << (c & 3);
if (size > 0)
out(offset, segment, NULL,
OUT_RESERVE + size, NO_SEG, NO_SEG);
@ -1659,10 +1662,12 @@ static void gencode(int32_t segment, int32_t offset, int bits,
break;
}
offset += s;
} else
} else {
errfunc(ERR_PANIC, "internal instruction table corrupt"
": instruction code 0x%02X given", c);
}
}
}
}
static int32_t regflag(const operand * o)