* \336-\337 are still listed as prefixes in the disassembler.
* \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
for (j = 0; j < MAXPREFIX; j++) {
uint8_t c = 0;
switch (instruction->prefixes[j]) {
+ case P_WAIT:
+ c = 0x9B;
+ break;
case P_LOCK:
c = 0xF0;
break;
length += ins->oprs[0].offset;
break;
+ case 0341:
+ if (!ins->prefixes[PPS_WAIT])
+ ins->prefixes[PPS_WAIT] = P_WAIT;
+ break;
+
case4(0344):
length++;
break;
}
break;
+ case 0341:
+ break;
+
case 0344:
case 0345:
bytes[0] = c & 1;
uint8_t asp; /* Address size prefix present */
uint8_t rep; /* Rep prefix present */
uint8_t seg; /* Segment override prefix present */
+ uint8_t wait; /* WAIT "prefix" present */
uint8_t lock; /* Lock prefix present */
uint8_t vex[3]; /* VEX prefix present */
uint8_t vex_m; /* VEX.M field */
uint8_t *origdata = data;
bool a_used = false, o_used = false;
enum prefixes drep = 0;
+ enum prefixes dwait = 0;
uint8_t lock = prefix->lock;
int osize = prefix->osize;
int asize = prefix->asize;
else if (prefix->rep == 0xF3)
drep = P_REP;
+ dwait = prefix->wait ? P_WAIT : 0;
+
while ((c = *r++) != 0) {
op1 = (c & 3) + ((opex & 1) << 2);
op2 = ((c >> 3) & 3) + ((opex & 2) << 1);
case 0340:
return false;
+ case 0341:
+ if (prefix->wait != 0x9B)
+ return false;
+ dwait = 0;
+ break;
+
case4(0344):
ins->oprs[0].basereg = (*data++ >> 3) & 7;
break;
return false;
ins->prefixes[PPS_LREP] = drep;
}
+ ins->prefixes[PPS_WAIT] = dwait;
if (!o_used) {
if (osize != ((segsize == 16) ? 16 : 32)) {
enum prefixes pfx = 0;
prefix.rep = *data++;
break;
+ case 0x9B:
+ prefix.wait = *data++;
+ break;
+
case 0xF0:
prefix.lock = *data++;
break;
* the return value is "sane." Maybe a macro wrapper could
* be used for that purpose.
*/
- for (i = 0; i < MAXPREFIX; i++)
- switch (ins.prefixes[i]) {
- case P_LOCK:
- slen += snprintf(output + slen, outbufsize - slen, "lock ");
- break;
- case P_REP:
- slen += snprintf(output + slen, outbufsize - slen, "rep ");
- break;
- case P_REPE:
- slen += snprintf(output + slen, outbufsize - slen, "repe ");
- break;
- case P_REPNE:
- slen += snprintf(output + slen, outbufsize - slen, "repne ");
- break;
- case P_A16:
- slen += snprintf(output + slen, outbufsize - slen, "a16 ");
- break;
- case P_A32:
- slen += snprintf(output + slen, outbufsize - slen, "a32 ");
- break;
- case P_A64:
- slen += snprintf(output + slen, outbufsize - slen, "a64 ");
- break;
- case P_O16:
- slen += snprintf(output + slen, outbufsize - slen, "o16 ");
- break;
- case P_O32:
- slen += snprintf(output + slen, outbufsize - slen, "o32 ");
- break;
- case P_O64:
- slen += snprintf(output + slen, outbufsize - slen, "o64 ");
- break;
- default:
- break;
- }
+ for (i = 0; i < MAXPREFIX; i++) {
+ const char *prefix = prefix_name(ins.prefixes[i]);
+ if (prefix)
+ slen += snprintf(output+slen, outbufsize-slen, "%s ", prefix);
+ }
i = (*p)->opcode;
if (i >= FIRST_COND_OPCODE)
FBSTP mem80 \1\xDF\206 8086,FPU
FBSTP mem \1\xDF\206 8086,FPU
FCHS void \2\xD9\xE0 8086,FPU
-FCLEX void \3\x9B\xDB\xE2 8086,FPU
+FCLEX void \341\2\xDB\xE2 8086,FPU
FCMOVB fpureg \1\xDA\10\xC0 P6,FPU
FCMOVB fpu0,fpureg \1\xDA\11\xC0 P6,FPU
FCMOVB void \2\xDA\xC1 P6,FPU,ND
FCOMPP void \2\xDE\xD9 8086,FPU
FCOS void \2\xD9\xFF 386,FPU
FDECSTP void \2\xD9\xF6 8086,FPU
-FDISI void \3\x9B\xDB\xE1 8086,FPU
+FDISI void \341\2\xDB\xE1 8086,FPU
FDIV mem32 \1\xD8\206 8086,FPU
FDIV mem64 \1\xDC\206 8086,FPU
FDIV fpureg|to \1\xDC\10\xF8 8086,FPU
FDIVRP fpureg,fpu0 \1\xDE\10\xF0 8086,FPU
FDIVRP void \2\xDE\xF1 8086,FPU,ND
FEMMS void \2\x0F\x0E PENT,3DNOW
-FENI void \3\x9B\xDB\xE0 8086,FPU
+FENI void \341\2\xDB\xE0 8086,FPU
FFREE fpureg \1\xDD\10\xC0 8086,FPU
FFREE void \2\xDD\xC1 8086,FPU
FFREEP fpureg \1\xDF\10\xC0 286,FPU,UNDOC
FIMUL mem32 \1\xDA\201 8086,FPU
FIMUL mem16 \1\xDE\201 8086,FPU
FINCSTP void \2\xD9\xF7 8086,FPU
-FINIT void \3\x9B\xDB\xE3 8086,FPU
+FINIT void \341\2\xDB\xE3 8086,FPU
FIST mem32 \1\xDB\202 8086,FPU
FIST mem16 \1\xDF\202 8086,FPU
FISTP mem32 \1\xDB\203 8086,FPU
FPTAN void \2\xD9\xF2 8086,FPU
FRNDINT void \2\xD9\xFC 8086,FPU
FRSTOR mem \1\xDD\204 8086,FPU
-FSAVE mem \2\x9B\xDD\206 8086,FPU
+FSAVE mem \341\1\xDD\206 8086,FPU
FSCALE void \2\xD9\xFD 8086,FPU
FSETPM void \2\xDB\xE4 286,FPU
FSIN void \2\xD9\xFE 386,FPU
FST mem64 \1\xDD\202 8086,FPU
FST fpureg \1\xDD\10\xD0 8086,FPU
FST void \2\xDD\xD1 8086,FPU,ND
-FSTCW mem \2\x9B\xD9\207 8086,FPU,SW
-FSTENV mem \2\x9B\xD9\206 8086,FPU
+FSTCW mem \341\1\xD9\207 8086,FPU,SW
+FSTENV mem \341\1\xD9\206 8086,FPU
FSTP mem32 \1\xD9\203 8086,FPU
FSTP mem64 \1\xDD\203 8086,FPU
FSTP mem80 \1\xDB\207 8086,FPU
FSTP fpureg \1\xDD\10\xD8 8086,FPU
FSTP void \2\xDD\xD9 8086,FPU,ND
-FSTSW mem \2\x9B\xDD\207 8086,FPU,SW
-FSTSW reg_ax \3\x9B\xDF\xE0 286,FPU
+FSTSW mem \341\1\xDD\207 8086,FPU,SW
+FSTSW reg_ax \341\2\xDF\xE0 286,FPU
FSUB mem32 \1\xD8\204 8086,FPU
FSUB mem64 \1\xDC\204 8086,FPU
FSUB fpureg|to \1\xDC\10\xE8 8086,FPU
VERW mem \2\x0F\x00\205 286,PROT
VERW mem16 \2\x0F\x00\205 286,PROT
VERW reg16 \2\x0F\x00\205 286,PROT
-WAIT void \1\x9B 8086
-FWAIT void \1\x9B 8086
+FWAIT void \341 8086
WBINVD void \2\x0F\x09 486,PRIV
WRSHR rm32 \321\2\x0F\x37\200 P6,CYRIX,SMM
WRMSR void \2\x0F\x30 PENT,PRIV
P_A16 = PREFIX_ENUM_START, P_A32, P_A64, P_ASP,
P_LOCK, P_O16, P_O32, P_O64, P_OSP,
P_REP, P_REPE, P_REPNE, P_REPNZ, P_REPZ, P_TIMES,
+ P_WAIT,
PREFIX_ENUM_LIMIT
};
Note that LOCK and REP are in the same slot. This is
an x86 architectural constraint. */
enum prefix_pos {
+ PPS_WAIT, /* WAIT (technically not a prefix!) */
PPS_LREP, /* Lock or REP prefix */
PPS_SEG, /* Segment override prefix */
PPS_OSIZE, /* Operand size prefix */
* Common list of prefix names
*/
static const char *prefix_names[] = {
- "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",
- "repnz", "repz", "times"
+ "a16", "a32", "a64", "asp", "lock", "o16", "o32", "o64", "osp",
+ "rep", "repe", "repne", "repnz", "repz", "times", "wait"
};
const char *prefix_name(int token)
static int prefix_slot(enum prefixes prefix)
{
switch (prefix) {
+ case P_WAIT:
+ return PPS_WAIT;
case R_CS:
case R_DS:
case R_SS:
repnz
repz
times
+wait
% TOKEN_SPECIAL, 0, S_*
abs