#include <lib9.h>#include <kernel.h> int i386inst(ulong, char, char*, int);int i386das(ulong, char*, int);int i386instlen(ulong); static uchar *dasdata; static char *_hexify(char *buf, ulong p, int zeros){ ulong d; d = p/16; if(d) buf = _hexify(buf, d, zeros-1); else while(zeros--) *buf++ = '0'; *buf++ = "0123456789abcdef"[p&0x0f]; return buf;} /* * an instruction */typedef struct Instr Instr;struct Instr{ uchar mem[1+1+1+1+2+1+1+4+4]; /* raw instruction */ ulong addr; /* address of start of instruction */ int n; /* number of bytes in instruction */ char *prefix; /* instr prefix */ char *segment; /* segment override */ uchar jumptype; /* set to the operand type for jump/ret/call */ char osize; /* 'W' or 'L' */ char asize; /* address size 'W' or 'L' */ uchar mod; /* bits 6-7 of mod r/m field */ uchar reg; /* bits 3-5 of mod r/m field */ char ss; /* bits 6-7 of SIB */ char index; /* bits 3-5 of SIB */ char base; /* bits 0-2 of SIB */ short seg; /* segment of far address */ ulong disp; /* displacement */ ulong imm; /* immediate */ ulong imm2; /* second immediate operand */ char *curr; /* fill level in output buffer */ char *end; /* end of output buffer */ char *err; /* error message */}; /* 386 register (ha!) set */enum{ AX=0, CX, DX, BX, SP, BP, SI, DI,}; /* Operand Format codes *//*%A - address size register modifier (!asize -> 'E')%C - Control register CR0/CR1/CR2%D - Debug register DR0/DR1/DR2/DR3/DR6/DR7%I - second immediate operand%O - Operand size register modifier (!osize -> 'E')%T - Test register TR6/TR7%S - size code ('W' or 'L')%X - Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"%d - displacement 16-32 bits%e - effective address - Mod R/M value%f - floating point register F0-F7 - from Mod R/M register%g - segment register%i - immediate operand 8-32 bits%p - PC-relative - signed displacement in immediate field%r - Reg from Mod R/M%x - Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"*/ typedef struct Optable Optable;struct Optable{ char operand[2]; void *proto; /* actually either (char*) or (Optable*) */}; /* Operand decoding codes */enum { Ib = 1, /* 8-bit immediate - (no sign extension)*/ Ibs, /* 8-bit immediate (sign extended) */ Jbs, /* 8-bit sign-extended immediate in jump or call */ Iw, /* 16-bit immediate -> imm */ Iw2, /* 16-bit immediate -> imm2 */ Iwd, /* Operand-sized immediate (no sign extension)*/ Awd, /* Address offset */ Iwds, /* Operand-sized immediate (sign extended) */ RM, /* Word or long R/M field with register (/r) */ RMB, /* Byte R/M field with register (/r) */ RMOP, /* Word or long R/M field with op code (/digit) */ RMOPB, /* Byte R/M field with op code (/digit) */ RMR, /* R/M register only (mod = 11) */ RMM, /* R/M memory only (mod = 0/1/2) */ R0, /* Base reg of Mod R/M is literal 0x00 */ R1, /* Base reg of Mod R/M is literal 0x01 */ FRMOP, /* Floating point R/M field with opcode */ FRMEX, /* Extended floating point R/M field with opcode */ JUMP, /* Jump or Call flag - no operand */ RET, /* Return flag - no operand */ OA, /* literal 0x0a byte */ PTR, /* Seg:Displacement addr (ptr16:16 or ptr16:32) */ AUX, /* Multi-byte op code - Auxiliary table */ PRE, /* Instr Prefix */ SEG, /* Segment Prefix */ OPOVER, /* Operand size override */ ADDOVER, /* Address size override */}; static Optable optab0F00[8]={ 0,0, "MOVW LDT,%e", 0,0, "MOVW TR,%e", 0,0, "MOVW %e,LDT", 0,0, "MOVW %e,TR", 0,0, "VERR %e", 0,0, "VERW %e",}; static Optable optab0F01[8]={ 0,0, "MOVL GDTR,%e", 0,0, "MOVL IDTR,%e", 0,0, "MOVL %e,GDTR", 0,0, "MOVL %e,IDTR", 0,0, "MOVW MSW,%e", /* word */ 0,0, nil, 0,0, "MOVW %e,MSW", /* word */}; static Optable optab0FBA[8]={ 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, Ib,0, "BT%S %i,%e", Ib,0, "BTS%S %i,%e", Ib,0, "BTR%S %i,%e", Ib,0, "BTC%S %i,%e",}; static Optable optab0F[256]={ RMOP,0, optab0F00, RMOP,0, optab0F01, RM,0, "LAR %e,%r", RM,0, "LSL %e,%r", 0,0, nil, 0,0, nil, 0,0, "CLTS", 0,0, nil, 0,0, "INVD", 0,0, "WBINVD", 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, RMR,0, "MOVL %C,%e", /* [0x20] */ RMR,0, "MOVL %D,%e", RMR,0, "MOVL %e,%C", RMR,0, "MOVL %e,%D", RMR,0, "MOVL %T,%e", 0,0, nil, RMR,0, "MOVL %e,%T", 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, "WRMSR", /* [0x30] */ 0,0, "RDTSC", 0,0, "RDMSR", 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, Iwds,0, "JOS %p", /* [0x80] */ Iwds,0, "JOC %p", Iwds,0, "JCS %p", Iwds,0, "JCC %p", Iwds,0, "JEQ %p", Iwds,0, "JNE %p", Iwds,0, "JLS %p", Iwds,0, "JHI %p", Iwds,0, "JMI %p", Iwds,0, "JPL %p", Iwds,0, "JPS %p", Iwds,0, "JPC %p", Iwds,0, "JLT %p", Iwds,0, "JGE %p", Iwds,0, "JLE %p", Iwds,0, "JGT %p", RMB,0, "SETOS %e", /* [0x90] */ RMB,0, "SETOC %e", RMB,0, "SETCS %e", RMB,0, "SETCC %e", RMB,0, "SETEQ %e", RMB,0, "SETNE %e", RMB,0, "SETLS %e", RMB,0, "SETHI %e", RMB,0, "SETMI %e", RMB,0, "SETPL %e", RMB,0, "SETPS %e", RMB,0, "SETPC %e", RMB,0, "SETLT %e", RMB,0, "SETGE %e", RMB,0, "SETLE %e", RMB,0, "SETGT %e", 0,0, "PUSHL FS", /* [0xa0] */ 0,0, "POPL FS", 0,0, "CPUID", RM,0, "BT%S %r,%e", RM,Ib, "SHLD%S %r,%i,%e", RM,0, "SHLD%S %r,CL,%e", 0,0, nil, 0,0, nil, 0,0, "PUSHL GS", 0,0, "POPL GS", 0,0, nil, RM,0, "BTS%S %r,%e", RM,Ib, "SHRD%S %r,%i,%e", RM,0, "SHRD%S %r,CL,%e", 0,0, nil, RM,0, "IMUL%S %e,%r", 0,0, nil, 0,0, nil, RMM,0, "LSS %e,%r", /* [0xb2] */ RM,0, "BTR%S %r,%e", RMM,0, "LFS %e,%r", RMM,0, "LGS %e,%r", RMB,0, "MOVBZX %e,%R", RM,0, "MOVWZX %e,%R", 0,0, nil, 0,0, nil, RMOP,0, optab0FBA, RM,0, "BTC%S %e,%r", RM,0, "BSF%S %e,%r", RM,0, "BSR%S %e,%r", RMB,0, "MOVBSX %e,%R", RM,0, "MOVWSX %e,%R",}; static Optable optab80[8]={ Ib,0, "ADDB %i,%e", Ib,0, "ORB %i,%e", Ib,0, "ADCB %i,%e", Ib,0, "SBBB %i,%e", Ib,0, "ANDB %i,%e", Ib,0, "SUBB %i,%e", Ib,0, "XORB %i,%e", Ib,0, "CMPB %e,%i",}; static Optable optab81[8]={ Iwd,0, "ADD%S %i,%e", Iwd,0, "OR%S %i,%e", Iwd,0, "ADC%S %i,%e", Iwd,0, "SBB%S %i,%e", Iwd,0, "AND%S %i,%e", Iwd,0, "SUB%S %i,%e", Iwd,0, "XOR%S %i,%e", Iwd,0, "CMP%S %e,%i",}; static Optable optab83[8]={ Ibs,0, "ADD%S %i,%e", Ibs,0, "OR%S %i,%e", Ibs,0, "ADC%S %i,%e", Ibs,0, "SBB%S %i,%e", Ibs,0, "AND%S %i,%e", Ibs,0, "SUB%S %i,%e", Ibs,0, "XOR%S %i,%e", Ibs,0, "CMP%S %e,%i",}; static Optable optabC0[8] ={ Ib,0, "ROLB %i,%e", Ib,0, "RORB %i,%e", Ib,0, "RCLB %i,%e", Ib,0, "RCRB %i,%e", Ib,0, "SHLB %i,%e", Ib,0, "SHRB %i,%e", 0,0, nil, Ib,0, "SARB %i,%e",}; static Optable optabC1[8] ={ Ib,0, "ROL%S %i,%e", Ib,0, "ROR%S %i,%e", Ib,0, "RCL%S %i,%e", Ib,0, "RCR%S %i,%e", Ib,0, "SHL%S %i,%e", Ib,0, "SHR%S %i,%e", 0,0, nil, Ib,0, "SAR%S %i,%e",}; static Optable optabD0[8] ={ 0,0, "ROLB %e", 0,0, "RORB %e", 0,0, "RCLB %e", 0,0, "RCRB %e", 0,0, "SHLB %e", 0,0, "SHRB %e", 0,0, nil, 0,0, "SARB %e",}; static Optable optabD1[8] ={ 0,0, "ROL%S %e", 0,0, "ROR%S %e", 0,0, "RCL%S %e", 0,0, "RCR%S %e", 0,0, "SHL%S %e", 0,0, "SHR%S %e", 0,0, nil, 0,0, "SAR%S %e",}; static Optable optabD2[8] ={ 0,0, "ROLB CL,%e", 0,0, "RORB CL,%e", 0,0, "RCLB CL,%e", 0,0, "RCRB CL,%e", 0,0, "SHLB CL,%e", 0,0, "SHRB CL,%e", 0,0, nil, 0,0, "SARB CL,%e",}; static Optable optabD3[8] ={ 0,0, "ROL%S CL,%e", 0,0, "ROR%S CL,%e", 0,0, "RCL%S CL,%e", 0,0, "RCR%S CL,%e", 0,0, "SHL%S CL,%e", 0,0, "SHR%S CL,%e", 0,0, nil, 0,0, "SAR%S CL,%e",}; static Optable optabD8[8+8] ={ 0,0, "FADDF %e,F0", 0,0, "FMULF %e,F0", 0,0, "FCOMF %e,F0", 0,0, "FCOMFP %e,F0", 0,0, "FSUBF %e,F0", 0,0, "FSUBRF %e,F0", 0,0, "FDIVF %e,F0", 0,0, "FDIVRF %e,F0", 0,0, "FADDD %f,F0", 0,0, "FMULD %f,F0", 0,0, "FCOMD %f,F0", 0,0, "FCOMPD %f,F0", 0,0, "FSUBD %f,F0", 0,0, "FSUBRD %f,F0", 0,0, "FDIVD %f,F0", 0,0, "FDIVRD %f,F0",};/* * optabD9 and optabDB use the following encoding: * if (0 <= modrm <= 2) instruction = optabDx[modrm&0x07]; * else instruction = optabDx[(modrm&0x3f)+8]; * * the instructions for MOD == 3, follow the 8 instructions * for the other MOD values stored at the front of the table. */static Optable optabD9[64+8] ={ 0,0, "FMOVF %e,F0", 0,0, nil, 0,0, "FMOVF F0,%e",Lines 1–500 of 1630. Load more
#include <lib9.h> #include <kernel.h> int i386inst(ulong, char, char*, int); int i386das(ulong, char*, int); int i386instlen(ulong); static uchar *dasdata; static char * _hexify(char *buf, ulong p, int zeros) { ulong d; d = p/16; if(d) buf = _hexify(buf, d, zeros-1); else while(zeros--) *buf++ = '0'; *buf++ = "0123456789abcdef"[p&0x0f]; return buf; } /* * an instruction */ typedef struct Instr Instr; struct Instr { uchar mem[1+1+1+1+2+1+1+4+4]; /* raw instruction */ ulong addr; /* address of start of instruction */ int n; /* number of bytes in instruction */ char *prefix; /* instr prefix */ char *segment; /* segment override */ uchar jumptype; /* set to the operand type for jump/ret/call */ char osize; /* 'W' or 'L' */ char asize; /* address size 'W' or 'L' */ uchar mod; /* bits 6-7 of mod r/m field */ uchar reg; /* bits 3-5 of mod r/m field */ char ss; /* bits 6-7 of SIB */ char index; /* bits 3-5 of SIB */ char base; /* bits 0-2 of SIB */ short seg; /* segment of far address */ ulong disp; /* displacement */ ulong imm; /* immediate */ ulong imm2; /* second immediate operand */ char *curr; /* fill level in output buffer */ char *end; /* end of output buffer */ char *err; /* error message */ }; /* 386 register (ha!) set */ enum{ AX=0, CX, DX, BX, SP, BP, SI, DI, }; /* Operand Format codes */ /* %A - address size register modifier (!asize -> 'E') %C - Control register CR0/CR1/CR2 %D - Debug register DR0/DR1/DR2/DR3/DR6/DR7 %I - second immediate operand %O - Operand size register modifier (!osize -> 'E') %T - Test register TR6/TR7 %S - size code ('W' or 'L') %X - Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE" %d - displacement 16-32 bits %e - effective address - Mod R/M value %f - floating point register F0-F7 - from Mod R/M register %g - segment register %i - immediate operand 8-32 bits %p - PC-relative - signed displacement in immediate field %r - Reg from Mod R/M %x - Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ" */ typedef struct Optable Optable; struct Optable { char operand[2]; void *proto; /* actually either (char*) or (Optable*) */ }; /* Operand decoding codes */ enum { Ib = 1, /* 8-bit immediate - (no sign extension)*/ Ibs, /* 8-bit immediate (sign extended) */ Jbs, /* 8-bit sign-extended immediate in jump or call */ Iw, /* 16-bit immediate -> imm */ Iw2, /* 16-bit immediate -> imm2 */ Iwd, /* Operand-sized immediate (no sign extension)*/ Awd, /* Address offset */ Iwds, /* Operand-sized immediate (sign extended) */ RM, /* Word or long R/M field with register (/r) */ RMB, /* Byte R/M field with register (/r) */ RMOP, /* Word or long R/M field with op code (/digit) */ RMOPB, /* Byte R/M field with op code (/digit) */ RMR, /* R/M register only (mod = 11) */ RMM, /* R/M memory only (mod = 0/1/2) */ R0, /* Base reg of Mod R/M is literal 0x00 */ R1, /* Base reg of Mod R/M is literal 0x01 */ FRMOP, /* Floating point R/M field with opcode */ FRMEX, /* Extended floating point R/M field with opcode */ JUMP, /* Jump or Call flag - no operand */ RET, /* Return flag - no operand */ OA, /* literal 0x0a byte */ PTR, /* Seg:Displacement addr (ptr16:16 or ptr16:32) */ AUX, /* Multi-byte op code - Auxiliary table */ PRE, /* Instr Prefix */ SEG, /* Segment Prefix */ OPOVER, /* Operand size override */ ADDOVER, /* Address size override */ }; static Optable optab0F00[8]= { 0,0, "MOVW LDT,%e", 0,0, "MOVW TR,%e", 0,0, "MOVW %e,LDT", 0,0, "MOVW %e,TR", 0,0, "VERR %e", 0,0, "VERW %e", }; static Optable optab0F01[8]= { 0,0, "MOVL GDTR,%e", 0,0, "MOVL IDTR,%e", 0,0, "MOVL %e,GDTR", 0,0, "MOVL %e,IDTR", 0,0, "MOVW MSW,%e", /* word */ 0,0, nil, 0,0, "MOVW %e,MSW", /* word */ }; static Optable optab0FBA[8]= { 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, Ib,0, "BT%S %i,%e", Ib,0, "BTS%S %i,%e", Ib,0, "BTR%S %i,%e", Ib,0, "BTC%S %i,%e", }; static Optable optab0F[256]= { RMOP,0, optab0F00, RMOP,0, optab0F01, RM,0, "LAR %e,%r", RM,0, "LSL %e,%r", 0,0, nil, 0,0, nil, 0,0, "CLTS", 0,0, nil, 0,0, "INVD", 0,0, "WBINVD", 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, RMR,0, "MOVL %C,%e", /* [0x20] */ RMR,0, "MOVL %D,%e", RMR,0, "MOVL %e,%C", RMR,0, "MOVL %e,%D", RMR,0, "MOVL %T,%e", 0,0, nil, RMR,0, "MOVL %e,%T", 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, "WRMSR", /* [0x30] */ 0,0, "RDTSC", 0,0, "RDMSR", 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, 0,0, nil, Iwds,0, "JOS %p", /* [0x80] */ Iwds,0, "JOC %p", Iwds,0, "JCS %p", Iwds,0, "JCC %p", Iwds,0, "JEQ %p", Iwds,0, "JNE %p", Iwds,0, "JLS %p", Iwds,0, "JHI %p", Iwds,0, "JMI %p", Iwds,0, "JPL %p", Iwds,0, "JPS %p", Iwds,0, "JPC %p", Iwds,0, "JLT %p", Iwds,0, "JGE %p", Iwds,0, "JLE %p", Iwds,0, "JGT %p", RMB,0, "SETOS %e", /* [0x90] */ RMB,0, "SETOC %e", RMB,0, "SETCS %e", RMB,0, "SETCC %e", RMB,0, "SETEQ %e", RMB,0, "SETNE %e", RMB,0, "SETLS %e", RMB,0, "SETHI %e", RMB,0, "SETMI %e", RMB,0, "SETPL %e", RMB,0, "SETPS %e", RMB,0, "SETPC %e", RMB,0, "SETLT %e", RMB,0, "SETGE %e", RMB,0, "SETLE %e", RMB,0, "SETGT %e", 0,0, "PUSHL FS", /* [0xa0] */ 0,0, "POPL FS", 0,0, "CPUID", RM,0, "BT%S %r,%e", RM,Ib, "SHLD%S %r,%i,%e", RM,0, "SHLD%S %r,CL,%e", 0,0, nil, 0,0, nil, 0,0, "PUSHL GS", 0,0, "POPL GS", 0,0, nil, RM,0, "BTS%S %r,%e", RM,Ib, "SHRD%S %r,%i,%e", RM,0, "SHRD%S %r,CL,%e", 0,0, nil, RM,0, "IMUL%S %e,%r", 0,0, nil, 0,0, nil, RMM,0, "LSS %e,%r", /* [0xb2] */ RM,0, "BTR%S %r,%e", RMM,0, "LFS %e,%r", RMM,0, "LGS %e,%r", RMB,0, "MOVBZX %e,%R", RM,0, "MOVWZX %e,%R", 0,0, nil, 0,0, nil, RMOP,0, optab0FBA, RM,0, "BTC%S %e,%r", RM,0, "BSF%S %e,%r", RM,0, "BSR%S %e,%r", RMB,0, "MOVBSX %e,%R", RM,0, "MOVWSX %e,%R", }; static Optable optab80[8]= { Ib,0, "ADDB %i,%e", Ib,0, "ORB %i,%e", Ib,0, "ADCB %i,%e", Ib,0, "SBBB %i,%e", Ib,0, "ANDB %i,%e", Ib,0, "SUBB %i,%e", Ib,0, "XORB %i,%e", Ib,0, "CMPB %e,%i", }; static Optable optab81[8]= { Iwd,0, "ADD%S %i,%e", Iwd,0, "OR%S %i,%e", Iwd,0, "ADC%S %i,%e", Iwd,0, "SBB%S %i,%e", Iwd,0, "AND%S %i,%e", Iwd,0, "SUB%S %i,%e", Iwd,0, "XOR%S %i,%e", Iwd,0, "CMP%S %e,%i", }; static Optable optab83[8]= { Ibs,0, "ADD%S %i,%e", Ibs,0, "OR%S %i,%e", Ibs,0, "ADC%S %i,%e", Ibs,0, "SBB%S %i,%e", Ibs,0, "AND%S %i,%e", Ibs,0, "SUB%S %i,%e", Ibs,0, "XOR%S %i,%e", Ibs,0, "CMP%S %e,%i", }; static Optable optabC0[8] = { Ib,0, "ROLB %i,%e", Ib,0, "RORB %i,%e", Ib,0, "RCLB %i,%e", Ib,0, "RCRB %i,%e", Ib,0, "SHLB %i,%e", Ib,0, "SHRB %i,%e", 0,0, nil, Ib,0, "SARB %i,%e", }; static Optable optabC1[8] = { Ib,0, "ROL%S %i,%e", Ib,0, "ROR%S %i,%e", Ib,0, "RCL%S %i,%e", Ib,0, "RCR%S %i,%e", Ib,0, "SHL%S %i,%e", Ib,0, "SHR%S %i,%e", 0,0, nil, Ib,0, "SAR%S %i,%e", }; static Optable optabD0[8] = { 0,0, "ROLB %e", 0,0, "RORB %e", 0,0, "RCLB %e", 0,0, "RCRB %e", 0,0, "SHLB %e", 0,0, "SHRB %e", 0,0, nil, 0,0, "SARB %e", }; static Optable optabD1[8] = { 0,0, "ROL%S %e", 0,0, "ROR%S %e", 0,0, "RCL%S %e", 0,0, "RCR%S %e", 0,0, "SHL%S %e", 0,0, "SHR%S %e", 0,0, nil, 0,0, "SAR%S %e", }; static Optable optabD2[8] = { 0,0, "ROLB CL,%e", 0,0, "RORB CL,%e", 0,0, "RCLB CL,%e", 0,0, "RCRB CL,%e", 0,0, "SHLB CL,%e", 0,0, "SHRB CL,%e", 0,0, nil, 0,0, "SARB CL,%e", }; static Optable optabD3[8] = { 0,0, "ROL%S CL,%e", 0,0, "ROR%S CL,%e", 0,0, "RCL%S CL,%e", 0,0, "RCR%S CL,%e", 0,0, "SHL%S CL,%e", 0,0, "SHR%S CL,%e", 0,0, nil, 0,0, "SAR%S CL,%e", }; static Optable optabD8[8+8] = { 0,0, "FADDF %e,F0", 0,0, "FMULF %e,F0", 0,0, "FCOMF %e,F0", 0,0, "FCOMFP %e,F0", 0,0, "FSUBF %e,F0", 0,0, "FSUBRF %e,F0", 0,0, "FDIVF %e,F0", 0,0, "FDIVRF %e,F0", 0,0, "FADDD %f,F0", 0,0, "FMULD %f,F0", 0,0, "FCOMD %f,F0", 0,0, "FCOMPD %f,F0", 0,0, "FSUBD %f,F0", 0,0, "FSUBRD %f,F0", 0,0, "FDIVD %f,F0", 0,0, "FDIVRD %f,F0", }; /* * optabD9 and optabDB use the following encoding: * if (0 <= modrm <= 2) instruction = optabDx[modrm&0x07]; * else instruction = optabDx[(modrm&0x3f)+8]; * * the instructions for MOD == 3, follow the 8 instructions * for the other MOD values stored at the front of the table. */ static Optable optabD9[64+8] = { 0,0, "FMOVF %e,F0", 0,0, nil, 0,0, "FMOVF F0,%e",