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;
(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:
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:
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;
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;
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:
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:
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:
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;
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:
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;
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);
}
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);
}
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);
}
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;
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;
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;
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;
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;
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;
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);
}
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);
}
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);
}
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;
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;
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++;
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;
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++;
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);
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)