* \340 - reserve <operand 0> bytes of uninitialized storage.
* Operand 0 had better be a segmentless constant.
* \341 - this instruction needs a WAIT "prefix"
- * \344,\345 - the PUSH/POP (respectively) codes for CS, DS, ES, SS
- * (POP is never used for CS) depending on operand 0
- * \346,\347 - the second byte of PUSH/POP codes for FS, GS, depending
- * on operand 0
* \360 - no SSE prefix (== \364\331)
* \361 - 66 SSE prefix (== \366\331)
* \362 - F2 SSE prefix (== \364\332)
ins->prefixes[PPS_WAIT] = P_WAIT;
break;
- case4(0344):
- length++;
- break;
-
case 0360:
break;
case 0341:
break;
- case 0344:
- case 0345:
- bytes[0] = c & 1;
- switch (ins->oprs[0].basereg) {
- case R_CS:
- bytes[0] += 0x0E;
- break;
- case R_DS:
- bytes[0] += 0x1E;
- break;
- case R_ES:
- bytes[0] += 0x06;
- break;
- case R_SS:
- bytes[0] += 0x16;
- break;
- default:
- errfunc(ERR_PANIC,
- "bizarre 8086 segment register received");
- }
- out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
- offset++;
- break;
-
- case 0346:
- case 0347:
- bytes[0] = c & 1;
- switch (ins->oprs[0].basereg) {
- case R_FS:
- bytes[0] += 0xA0;
- break;
- case R_GS:
- bytes[0] += 0xA8;
- break;
- default:
- errfunc(ERR_PANIC,
- "bizarre 386 segment register received");
- }
- out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
- offset++;
- break;
-
case 0360:
break;
/* Important: regval must already have been adjusted for rex extensions */
static enum reg_enum whichreg(opflags_t regflags, int regval, int rex)
{
+ size_t i;
+
+ static const struct {
+ opflags_t flags;
+ enum reg_enum reg;
+ } specific_registers[] = {
+ {REG_AL, R_AL},
+ {REG_AX, R_AX},
+ {REG_EAX, R_EAX},
+ {REG_RAX, R_RAX},
+ {REG_DL, R_DL},
+ {REG_DX, R_DX},
+ {REG_EDX, R_EDX},
+ {REG_RDX, R_RDX},
+ {REG_CL, R_CL},
+ {REG_CX, R_CX},
+ {REG_ECX, R_ECX},
+ {REG_RCX, R_RCX},
+ {FPU0, R_ST0},
+ {XMM0, R_XMM0},
+ {YMM0, R_YMM0},
+ {REG_ES, R_ES},
+ {REG_CS, R_CS},
+ {REG_SS, R_SS},
+ {REG_DS, R_DS},
+ {REG_FS, R_FS},
+ {REG_GS, R_GS}
+ };
+
if (!(regflags & (REGISTER|REGMEM)))
return 0; /* Registers not permissible?! */
regflags |= REGISTER;
- if (!(REG_AL & ~regflags))
- return R_AL;
- if (!(REG_AX & ~regflags))
- return R_AX;
- if (!(REG_EAX & ~regflags))
- return R_EAX;
- if (!(REG_RAX & ~regflags))
- return R_RAX;
- if (!(REG_DL & ~regflags))
- return R_DL;
- if (!(REG_DX & ~regflags))
- return R_DX;
- if (!(REG_EDX & ~regflags))
- return R_EDX;
- if (!(REG_RDX & ~regflags))
- return R_RDX;
- if (!(REG_CL & ~regflags))
- return R_CL;
- if (!(REG_CX & ~regflags))
- return R_CX;
- if (!(REG_ECX & ~regflags))
- return R_ECX;
- if (!(REG_RCX & ~regflags))
- return R_RCX;
- if (!(FPU0 & ~regflags))
- return R_ST0;
- if (!(XMM0 & ~regflags))
- return R_XMM0;
- if (!(YMM0 & ~regflags))
- return R_YMM0;
- if (!(REG_CS & ~regflags))
- return (regval == 1) ? R_CS : 0;
- if (!(REG_DESS & ~regflags))
- return (regval == 0 || regval == 2
- || regval == 3 ? nasm_rd_sreg[regval] : 0);
- if (!(REG_FSGS & ~regflags))
- return (regval == 4 || regval == 5 ? nasm_rd_sreg[regval] : 0);
- if (!(REG_SEG67 & ~regflags))
- return (regval == 6 || regval == 7 ? nasm_rd_sreg[regval] : 0);
+ for (i = 0; i < ARRAY_SIZE(specific_registers); i++)
+ if (!(specific_registers[i].flags & ~regflags))
+ return specific_registers[i].reg;
/* All the entries below look up regval in an 16-entry array */
if (regval < 0 || regval > 15)
dwait = 0;
break;
- case4(0344):
- ins->oprs[0].basereg = (*data++ >> 3) & 7;
- break;
-
case 0360:
if (prefix->osp || prefix->rep)
return false;
POP rm16 [m: o16 8f /0] 8086
POP rm32 [m: o32 8f /0] 386,NOLONG
POP rm64 [m: o64nw 8f /0] X64
+POP reg_es [-: 07] 8086,NOLONG
POP reg_cs [-: 0f] 8086,UNDOC,ND
-POP reg_dess [-: popseg] 8086,NOLONG
-POP reg_fsgs [-: 0f popseg2] 386
+POP reg_ss [-: 17] 8086,NOLONG
+POP reg_ds [-: 1f] 8086,NOLONG
+POP reg_fs [-: 0f a1] 386
+POP reg_gs [-: 0f a9] 386
POPA void [ odf 61] 186,NOLONG
POPAD void [ o32 61] 386,NOLONG
POPAW void [ o16 61] 186,NOLONG
PUSH rm16 [m: o16 ff /6] 8086
PUSH rm32 [m: o32 ff /6] 386,NOLONG
PUSH rm64 [m: o64nw ff /6] X64
-PUSH reg_cs [-: pushseg] 8086,NOLONG
-PUSH reg_dess [-: pushseg] 8086,NOLONG
-PUSH reg_fsgs [-: 0f pushseg2] 386
+PUSH reg_es [-: 06] 8086,NOLONG
+PUSH reg_cs [-: 0e] 8086,NOLONG
+PUSH reg_ss [-: 16] 8086,NOLONG
+PUSH reg_ds [-: 1e] 8086,NOLONG
+PUSH reg_fs [-: 0f a0] 386
+PUSH reg_gs [-: 0f a8] 386
PUSH imm8 [i: 6a ib,s] 186
PUSH sbyteword16 [i: o16 6a ib,s] 186,AR0,SZ,ND
PUSH imm16 [i: o16 68 iw] 186,AR0,SZ
return addprefix($prefix, $c1..($c1+15));
} elsif ($c0 == 0 || $c0 == 0340) {
return $prefix;
- } elsif ($c0 == 0344) {
- return addprefix($prefix, 0x06, 0x0E, 0x16, 0x1E);
- } elsif ($c0 == 0345) {
- return addprefix($prefix, 0x07, 0x17, 0x1F);
- } elsif ($c0 == 0346) {
- return addprefix($prefix, 0xA0, 0xA8);
- } elsif ($c0 == 0347) {
- return addprefix($prefix, 0xA1, 0xA9);
} elsif (($c0 & ~3) == 0260 || $c0 == 0270) {
my $c,$m,$wlp;
$m = shift(@codes);
'!asp' => 0365,
'f2i' => 0332, # F2 prefix, but 66 for operand size is OK
'f3i' => 0333, # F3 prefix, but 66 for operand size is OK
- 'pushseg' => 0344,
- 'popseg' => 0345,
- 'pushseg2' => 0346,
- 'popseg2' => 0347,
'mustrep' => 0336,
'mustrepne' => 0337,
'rex.l' => 0334,
#define REG_DREG (GEN_SUBCLASS(2) | REG_CLASS_CDT | BITS32 | REGISTER) /* DRn */
#define REG_TREG (GEN_SUBCLASS(3) | REG_CLASS_CDT | BITS32 | REGISTER) /* TRn */
#define REG_SREG ( REG_CLASS_SREG | BITS16 | REGISTER) /* any segment register */
-#define REG_CS (GEN_SUBCLASS(1) | REG_CLASS_SREG | BITS16 | REGISTER) /* CS */
-#define REG_DESS (GEN_SUBCLASS(2) | REG_CLASS_SREG | BITS16 | REGISTER) /* DS, ES, SS */
-#define REG_FSGS (GEN_SUBCLASS(3) | REG_CLASS_SREG | BITS16 | REGISTER) /* FS, GS */
-#define REG_SEG67 (GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* Unimplemented segment registers */
+
+/* Segment registers */
+#define REG_ES (GEN_SUBCLASS(0) | GEN_SUBCLASS(2) | REG_CLASS_SREG | BITS16 | REGISTER) /* ES */
+#define REG_CS (GEN_SUBCLASS(1) | GEN_SUBCLASS(2) | REG_CLASS_SREG | BITS16 | REGISTER) /* CS */
+#define REG_SS (GEN_SUBCLASS(0) | GEN_SUBCLASS(3) | REG_CLASS_SREG | BITS16 | REGISTER) /* SS */
+#define REG_DS (GEN_SUBCLASS(1) | GEN_SUBCLASS(3) | REG_CLASS_SREG | BITS16 | REGISTER) /* DS */
+#define REG_FS (GEN_SUBCLASS(0) | GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* FS */
+#define REG_GS (GEN_SUBCLASS(1) | GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* GS */
+#define REG_FSGS ( GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* FS or GS */
+#define REG_SEG67 ( GEN_SUBCLASS(5) | REG_CLASS_SREG | BITS16 | REGISTER) /* Unimplemented segment registers */
/* Special GPRs */
#define REG_SMASK SUBCLASS_MASK /* a mask for the following */
r8-15 REG64NA reg64 8
# Segment registers
+es REG_ES sreg 0
cs REG_CS sreg 1
-ds REG_DESS sreg 3
-es REG_DESS sreg 0
-ss REG_DESS sreg 2
-fs REG_FSGS sreg 4
-gs REG_FSGS sreg 5
+ss REG_SS sreg 2
+ds REG_DS sreg 3
+fs REG_FS sreg 4
+gs REG_GS sreg 5
segr6-7 REG_SEG67 sreg 6
# Control registers