Index: coregrind/vg_to_ucode.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_to_ucode.c,v retrieving revision 1.50 diff -u -r1.50 vg_to_ucode.c --- coregrind/vg_to_ucode.c 3 Feb 2003 11:25:34 -0000 1.50 +++ coregrind/vg_to_ucode.c 17 Mar 2003 14:22:37 -0000 @@ -3195,6 +3195,72 @@ Int t1, t2, t3, t4; UChar dis_buf[50]; Int am_sz, d_sz; + static const int jmp_array[] = { + &&l_0x00-&&b, &&l_0x01-&&b, &&l_0x02-&&b, &&l_0x03-&&b, &&l_0x04-&&b, /* 0 */ + &&l_0x05-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0x08-&&b, &&l_0x09-&&b, + &&l_0x0A-&&b, &&l_0x0B-&&b, &&l_0x0C-&&b, &&l_0x0D-&&b, &&l_switch-&&b, + &&l_0x0F-&&b, + &&l_0x10-&&b, &&l_0x11-&&b, &&l_0x12-&&b, &&l_0x13-&&b, &&l_0x14-&&b, /* 1 */ + &&l_0x15-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0x19-&&b, + &&l_0x1A-&&b, &&l_0x1B-&&b, &&l_0x1C-&&b, &&l_switch-&&b, &&l_switch-&&b, + &&l_switch-&&b, + &&l_0x20-&&b, &&l_0x21-&&b, &&l_0x22-&&b, &&l_0x23-&&b, &&l_0x24-&&b, /* 2 */ + &&l_0x25-&&b, &&l_switch-&&b, &&l_0x27-&&b, &&l_0x28-&&b, &&l_0x29-&&b, + &&l_0x2A-&&b, &&l_0x2B-&&b, &&l_0x2C-&&b, &&l_0x2D-&&b, &&l_switch-&&b, + &&l_0x2F-&&b, + &&l_0x30-&&b, &&l_0x31-&&b, &&l_0x32-&&b, &&l_0x33-&&b, &&l_0x34-&&b, /* 3 */ + &&l_0x35-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0x38-&&b, &&l_0x39-&&b, + &&l_0x3A-&&b, &&l_0x3B-&&b, &&l_0x3C-&&b, &&l_0x3D-&&b, &&l_switch-&&b, + &&l_switch-&&b, + &&l_0x40_47-&&b, &&l_0x40_47-&&b, &&l_0x40_47-&&b, &&l_0x40_47-&&b, &&l_0x40_47-&&b, /* 4 */ + &&l_0x40_47-&&b, &&l_0x40_47-&&b, &&l_0x40_47-&&b, &&l_0x48_4F-&&b, &&l_0x48_4F-&&b, + &&l_0x48_4F-&&b, &&l_0x48_4F-&&b, &&l_0x48_4F-&&b, &&l_0x48_4F-&&b, &&l_0x48_4F-&&b, + &&l_0x48_4F-&&b, + &&l_0x50_57-&&b, &&l_0x50_57-&&b, &&l_0x50_57-&&b, &&l_0x50_57-&&b, &&l_0x50_57-&&b, /* 5 */ + &&l_0x50_57-&&b, &&l_0x50_57-&&b, &&l_0x50_57-&&b, &&l_0x58_5F-&&b, &&l_0x58_5F-&&b, + &&l_0x58_5F-&&b, &&l_0x58_5F-&&b, &&l_0x58_5F-&&b, &&l_0x58_5F-&&b, &&l_0x58_5F-&&b, + &&l_0x58_5F-&&b, + &&l_0x60-&&b, &&l_0x61-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, /* 6 */ + &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0x68-&&b, &&l_0x69-&&b, + &&l_0x6A-&&b, &&l_0x6B-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, + &&l_switch-&&b, + &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, /* 7 */ + &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, + &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, &&l_0x70_7F-&&b, + &&l_0x70_7F-&&b, + &&l_0x80-&&b, &&l_0x81-&&b, &&l_0x83-&&b, &&l_switch-&&b, &&l_0x84-&&b, /* 8 */ + &&l_0x85-&&b, &&l_0x86-&&b, &&l_switch-&&b, &&l_0x88-&&b, &&l_0x89-&&b, + &&l_0x8A-&&b, &&l_0x8B-&&b, &&l_0x8C-&&b, &&l_0x8D-&&b, &&l_0x8E-&&b, + &&l_0x8F-&&b, + &&l_0x90-&&b, &&l_0x91_93-&&b, &&l_0x91_93-&&b, &&l_0x91_93-&&b, &&l_switch-&&b, /* 9 */ + &&l_switch-&&b, &&l_0x96-&&b, &&l_0x97-&&b, &&l_0x98-&&b, &&l_0x99-&&b, + &&l_switch-&&b, &&l_0x9B-&&b, &&l_0x9C-&&b, &&l_0x9D-&&b, &&l_0x9E-&&b, + &&l_switch-&&b, + &&l_0xA0-&&b, &&l_0xA1-&&b, &&l_0xA2-&&b, &&l_0xA3-&&b, &&l_0xA4-&&b, /* A */ + &&l_0xA5-&&b, &&l_0xA6-&&b, &&l_switch-&&b, &&l_0xA8-&&b, &&l_0xA9-&&b, + &&l_0xAA-&&b, &&l_0xAB-&&b, &&l_0xAC-&&b, &&l_0xAD-&&b, &&l_0xAE-&&b, + &&l_switch-&&b, + &&l_0xB0_B7-&&b, &&l_0xB0_B7-&&b, &&l_0xB0_B7-&&b, &&l_0xB0_B7-&&b, &&l_0xB0_B7-&&b, /* B */ + &&l_0xB0_B7-&&b, &&l_0xB0_B7-&&b, &&l_0xB0_B7-&&b, &&l_0xB8_BB-&&b, &&l_0xB8_BB-&&b, + &&l_0xB8_BB-&&b, &&l_0xB8_BB-&&b, &&l_switch-&&b, &&l_0xBD_BF-&&b, &&l_0xBD_BF-&&b, + &&l_0xBD_BF-&&b, + &&l_0xC0-&&b, &&l_0xC1-&&b, &&l_0xC2-&&b, &&l_0xC3-&&b, &&l_switch-&&b, /* C */ + &&l_switch-&&b, &&l_0xC6-&&b, &&l_0xC7-&&b, &&l_switch-&&b, &&l_0xC9-&&b, + &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0xCD-&&b, &&l_switch-&&b, + &&l_switch-&&b, + &&l_0xD0-&&b, &&l_0xD1-&&b, &&l_0xD2-&&b, &&l_0xD3-&&b, &&l_switch-&&b, /* D */ + &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0xD8_DF-&&b, &&l_0xD8_DF-&&b, + &&l_0xD8_DF-&&b, &&l_0xD8_DF-&&b, &&l_0xD8_DF-&&b, &&l_0xD8_DF-&&b, &&l_0xD8_DF-&&b, + &&l_0xD8_DF-&&b, + &&l_switch-&&b, &&l_switch-&&b, &&l_0xE2-&&b, &&l_0xE3-&&b, &&l_switch-&&b, /* E */ + &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_0xE8-&&b, &&l_0xE9-&&b, + &&l_switch-&&b, &&l_0xEB-&&b, &&l_switch-&&b, &&l_switch-&&b, &&l_switch-&&b, + &&l_switch-&&b, + &&l_switch-&&b, &&l_switch-&&b, &&l_0xF2-&&b, &&l_0xF3-&&b, &&l_switch-&&b, /* F */ + &&l_switch-&&b, &&l_0xF6-&&b, &&l_0xF7-&&b, &&l_0xF8-&&b, &&l_0xF9-&&b, + &&l_switch-&&b, &&l_switch-&&b, &&l_0xFC-&&b, &&l_0xFD-&&b, &&l_0xFE-&&b, + &&l_0xFF-&&b + }; /* sz denotes the nominal data-op size of the insn; we change it to 2 if an 0x66 prefix is seen */ @@ -3275,14 +3341,20 @@ opc = getUChar(eip); eip++; + goto *(&&b + jmp_array[opc]); + +b: /* means "base", took it because it's short */ +l_switch: switch (opc) { /* ------------------------ Control flow --------------- */ case 0xC2: /* RET imm16 */ +l_0xC2: d32 = getUDisp16(eip); eip += 2; goto do_Ret; case 0xC3: /* RET */ +l_0xC3: d32 = 0; goto do_Ret; do_Ret: @@ -3304,6 +3376,7 @@ break; case 0xE8: /* CALL J4 */ +l_0xE8: d32 = getUDisp32(eip); eip += 4; d32 += eip; /* eip now holds return-to addr, d32 is call-to addr */ if (d32 == eip && getUChar(eip) >= 0x58 @@ -3344,6 +3417,7 @@ break; case 0xC9: /* LEAVE */ +l_0xC9: t1 = newTemp(cb); t2 = newTemp(cb); uInstr2(cb, GET, 4, ArchReg, R_EBP, TempReg, t1); uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP); @@ -3361,6 +3435,8 @@ case 0x27: /* DAA */ case 0x2F: /* DAS */ +l_0x27: +l_0x2F: t1 = newTemp(cb); uInstr2(cb, GET, 1, ArchReg, R_AL, TempReg, t1); /* Widen %AL to 32 bits, so it's all defined when we push it. */ @@ -3381,6 +3457,7 @@ /* ------------------------ CWD/CDQ -------------------- */ case 0x98: /* CBW */ +l_0x98: t1 = newTemp(cb); if (sz == 4) { uInstr2(cb, GET, 2, ArchReg, R_EAX, TempReg, t1); @@ -3401,6 +3478,7 @@ break; case 0x99: /* CWD/CDQ */ +l_0x99: t1 = newTemp(cb); uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, t1); uInstr2(cb, SAR, sz, Literal, 0, TempReg, t1); @@ -3412,11 +3490,13 @@ /* ------------------------ FPU ops -------------------- */ case 0x9E: /* SAHF */ +l_0x9E: codegen_SAHF ( cb ); if (dis) VG_(printf)("sahf\n"); break; case 0x9B: /* FWAIT */ +l_0x9B: /* ignore? */ if (dis) VG_(printf)("fwait\n"); break; @@ -3429,6 +3509,7 @@ case 0xDD: case 0xDE: case 0xDF: +l_0xD8_DF: eip = dis_fpu ( cb, sorb, opc, eip ); break; @@ -3441,6 +3522,7 @@ case 0x45: /* INC eBP */ case 0x46: /* INC eSI */ case 0x47: /* INC eDI */ +l_0x40_47: t1 = newTemp(cb); uInstr2(cb, GET, sz, ArchReg, (UInt)(opc - 0x40), TempReg, t1); @@ -3459,6 +3541,7 @@ case 0x4D: /* DEC eBP */ case 0x4E: /* DEC eSI */ case 0x4F: /* DEC eDI */ +l_0x48_4F: t1 = newTemp(cb); uInstr2(cb, GET, sz, ArchReg, (UInt)(opc - 0x48), TempReg, t1); @@ -3473,6 +3556,7 @@ /* ------------------------ INT ------------------------ */ case 0xCD: /* INT imm8 */ +l_0xCD: d32 = getUChar(eip); eip++; if (d32 != 0x80) VG_(core_panic)("disInstr: INT but not 0x80 !"); /* It's important that all ArchRegs carry their up-to-date value @@ -3489,6 +3573,7 @@ /* ------------------------ Jcond, byte offset --------- */ case 0xEB: /* Jb (jump, byte offset) */ +l_0xEB: d32 = (eip+1) + getSDisp8(eip); eip++; uInstr1(cb, JMP, 0, Literal, 0); uLiteral(cb, d32); @@ -3499,6 +3584,7 @@ break; case 0xE9: /* Jv (jump, 16/32 offset) */ +l_0xE9: d32 = (eip+sz) + getSDisp(sz,eip); eip += sz; uInstr1(cb, JMP, 0, Literal, 0); uLiteral(cb, d32); @@ -3524,6 +3610,7 @@ case 0x7D: /* JGEb/JNLb (jump greater or equal) */ case 0x7E: /* JLEb/JNGb (jump less or equal) */ case 0x7F: /* JGb/JNLEb (jump greater) */ +l_0x70_7F: d32 = (eip+1) + getSDisp8(eip); eip++; uInstr1(cb, JMP, 0, Literal, 0); uLiteral(cb, d32); @@ -3547,6 +3634,7 @@ case 0xE3: /* JECXZ or perhaps JCXZ, depending on OSO ? Intel manual says it depends on address size override, which doesn't sound right to me. */ +l_0xE3: d32 = (eip+1) + getSDisp8(eip); eip++; t1 = newTemp(cb); uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, t1); @@ -3561,6 +3649,7 @@ the address size override, not the operand one. Since we don't handle address size overrides, I guess that means ECX. */ +l_0xE2: d32 = (eip+1) + getSDisp8(eip); eip++; t1 = newTemp(cb); uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, t1); @@ -3579,31 +3668,38 @@ /* ------------------------ IMUL ----------------------- */ case 0x69: /* IMUL Iv, Ev, Gv */ +l_0x69: eip = dis_imul_I_E_G ( cb, sorb, sz, eip, sz ); break; case 0x6B: /* IMUL Ib, Ev, Gv */ +l_0x6B: eip = dis_imul_I_E_G ( cb, sorb, sz, eip, 1 ); break; /* ------------------------ MOV ------------------------ */ case 0x88: /* MOV Gb,Eb */ +l_0x88: eip = dis_mov_G_E(cb, sorb, 1, eip); break; case 0x89: /* MOV Gv,Ev */ +l_0x89: eip = dis_mov_G_E(cb, sorb, sz, eip); break; case 0x8A: /* MOV Eb,Gb */ +l_0x8A: eip = dis_mov_E_G(cb, sorb, 1, eip); break; case 0x8B: /* MOV Ev,Gv */ +l_0x8B: eip = dis_mov_E_G(cb, sorb, sz, eip); break; case 0x8D: /* LEA M,Gv */ +l_0x8D: modrm = getUChar(eip); if (epartIsReg(modrm)) VG_(core_panic)("LEA M,Gv: modRM refers to register"); @@ -3620,17 +3716,21 @@ break; case 0x8C: /* MOV Sw,Ew -- MOV from a SEGMENT REGISTER */ +l_0x8C: eip = dis_mov_Sw_Ew(cb, sorb, eip); break; case 0x8E: /* MOV Ew,Sw -- MOV to a SEGMENT REGISTER */ +l_0x8E: eip = dis_mov_Ew_Sw(cb, sorb, eip); break; case 0xA0: /* MOV Ob,AL */ +l_0xA0: sz = 1; /* Fall through ... */ case 0xA1: /* MOV Ov,eAX */ +l_0xA1: d32 = getUDisp32(eip); eip += 4; t1 = newTemp(cb); t2 = newTemp(cb); uInstr2(cb, MOV, 4, Literal, 0, TempReg, t2); @@ -3644,9 +3744,11 @@ break; case 0xA2: /* MOV AL,Ob */ +l_0xA2: sz = 1; /* Fall through ... */ case 0xA3: /* MOV eAX,Ov */ +l_0xA3: d32 = getUDisp32(eip); eip += 4; t1 = newTemp(cb); t2 = newTemp(cb); uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, t1); @@ -3667,6 +3769,7 @@ case 0xB5: /* MOV imm,CH */ case 0xB6: /* MOV imm,DH */ case 0xB7: /* MOV imm,BH */ +l_0xB0_B7: d32 = getUChar(eip); eip += 1; t1 = newTemp(cb); uInstr2(cb, MOV, 1, Literal, 0, TempReg, t1); @@ -3683,6 +3786,8 @@ case 0xBD: /* MOV imm,eBP */ case 0xBE: /* MOV imm,eSI */ case 0xBF: /* MOV imm,eDI */ +l_0xB8_BB: +l_0xBD_BF: d32 = getUDisp(sz,eip); eip += sz; t1 = newTemp(cb); uInstr2(cb, MOV, sz, Literal, 0, TempReg, t1); @@ -3693,9 +3798,11 @@ break; case 0xC6: /* MOV Ib,Eb */ +l_0xC6: sz = 1; goto do_Mov_I_E; case 0xC7: /* MOV Iv,Ev */ +l_0xC7: goto do_Mov_I_E; do_Mov_I_E: @@ -3725,182 +3832,232 @@ /* ------------------------ opl imm, A ----------------- */ case 0x04: /* ADD Ib, AL */ +l_0x04: eip = dis_op_imm_A(cb, 1, ADD, True, eip, "add" ); break; case 0x05: /* ADD Iv, eAX */ +l_0x05: eip = dis_op_imm_A(cb, sz, ADD, True, eip, "add" ); break; case 0x0C: /* OR Ib, AL */ +l_0x0C: eip = dis_op_imm_A(cb, 1, OR, True, eip, "or" ); break; case 0x0D: /* OR Iv, eAX */ +l_0x0D: eip = dis_op_imm_A(cb, sz, OR, True, eip, "or" ); break; case 0x14: /* ADC Ib, AL */ +l_0x14: eip = dis_op_imm_A(cb, 1, ADC, True, eip, "adc" ); break; case 0x15: /* ADC Iv, eAX */ +l_0x15: eip = dis_op_imm_A(cb, sz, ADC, True, eip, "adc" ); break; case 0x1C: /* SBB Ib, AL */ +l_0x1C: eip = dis_op_imm_A(cb, 1, SBB, True, eip, "sbb" ); break; case 0x24: /* AND Ib, AL */ +l_0x24: eip = dis_op_imm_A(cb, 1, AND, True, eip, "and" ); break; case 0x25: /* AND Iv, eAX */ +l_0x25: eip = dis_op_imm_A(cb, sz, AND, True, eip, "and" ); break; case 0x2C: /* SUB Ib, AL */ +l_0x2C: eip = dis_op_imm_A(cb, 1, SUB, True, eip, "sub" ); break; case 0x2D: /* SUB Iv, eAX */ +l_0x2D: eip = dis_op_imm_A(cb, sz, SUB, True, eip, "sub" ); break; case 0x34: /* XOR Ib, AL */ +l_0x34: eip = dis_op_imm_A(cb, 1, XOR, True, eip, "xor" ); break; case 0x35: /* XOR Iv, eAX */ +l_0x35: eip = dis_op_imm_A(cb, sz, XOR, True, eip, "xor" ); break; case 0x3C: /* CMP Ib, AL */ +l_0x3C: eip = dis_op_imm_A(cb, 1, SUB, False, eip, "cmp" ); break; case 0x3D: /* CMP Iv, eAX */ +l_0x3D: eip = dis_op_imm_A(cb, sz, SUB, False, eip, "cmp" ); break; case 0xA8: /* TEST Ib, AL */ +l_0xA8: eip = dis_op_imm_A(cb, 1, AND, False, eip, "test" ); break; case 0xA9: /* TEST Iv, eAX */ +l_0xA9: eip = dis_op_imm_A(cb, sz, AND, False, eip, "test" ); break; /* ------------------------ opl Ev, Gv ----------------- */ case 0x02: /* ADD Eb,Gb */ +l_0x02: eip = dis_op2_E_G ( cb, sorb, ADD, True, 1, eip, "add" ); break; case 0x03: /* ADD Ev,Gv */ +l_0x03: eip = dis_op2_E_G ( cb, sorb, ADD, True, sz, eip, "add" ); break; case 0x0A: /* OR Eb,Gb */ +l_0x0A: eip = dis_op2_E_G ( cb, sorb, OR, True, 1, eip, "or" ); break; case 0x0B: /* OR Ev,Gv */ +l_0x0B: eip = dis_op2_E_G ( cb, sorb, OR, True, sz, eip, "or" ); break; case 0x12: /* ADC Eb,Gb */ +l_0x12: eip = dis_op2_E_G ( cb, sorb, ADC, True, 1, eip, "adc" ); break; case 0x13: /* ADC Ev,Gv */ +l_0x13: eip = dis_op2_E_G ( cb, sorb, ADC, True, sz, eip, "adc" ); break; case 0x1A: /* SBB Eb,Gb */ +l_0x1A: eip = dis_op2_E_G ( cb, sorb, SBB, True, 1, eip, "sbb" ); break; case 0x1B: /* SBB Ev,Gv */ +l_0x1B: eip = dis_op2_E_G ( cb, sorb, SBB, True, sz, eip, "sbb" ); break; case 0x22: /* AND Eb,Gb */ +l_0x22: eip = dis_op2_E_G ( cb, sorb, AND, True, 1, eip, "and" ); break; case 0x23: /* AND Ev,Gv */ +l_0x23: eip = dis_op2_E_G ( cb, sorb, AND, True, sz, eip, "and" ); break; case 0x2A: /* SUB Eb,Gb */ +l_0x2A: eip = dis_op2_E_G ( cb, sorb, SUB, True, 1, eip, "sub" ); break; case 0x2B: /* SUB Ev,Gv */ +l_0x2B: eip = dis_op2_E_G ( cb, sorb, SUB, True, sz, eip, "sub" ); break; case 0x32: /* XOR Eb,Gb */ +l_0x32: eip = dis_op2_E_G ( cb, sorb, XOR, True, 1, eip, "xor" ); break; case 0x33: /* XOR Ev,Gv */ +l_0x33: eip = dis_op2_E_G ( cb, sorb, XOR, True, sz, eip, "xor" ); break; case 0x3A: /* CMP Eb,Gb */ +l_0x3A: eip = dis_op2_E_G ( cb, sorb, SUB, False, 1, eip, "cmp" ); break; case 0x3B: /* CMP Ev,Gv */ +l_0x3B: eip = dis_op2_E_G ( cb, sorb, SUB, False, sz, eip, "cmp" ); break; case 0x84: /* TEST Eb,Gb */ +l_0x84: eip = dis_op2_E_G ( cb, sorb, AND, False, 1, eip, "test" ); break; case 0x85: /* TEST Ev,Gv */ +l_0x85: eip = dis_op2_E_G ( cb, sorb, AND, False, sz, eip, "test" ); break; /* ------------------------ opl Gv, Ev ----------------- */ case 0x00: /* ADD Gb,Eb */ +l_0x00: eip = dis_op2_G_E ( cb, sorb, ADD, True, 1, eip, "add" ); break; case 0x01: /* ADD Gv,Ev */ +l_0x01: eip = dis_op2_G_E ( cb, sorb, ADD, True, sz, eip, "add" ); break; case 0x08: /* OR Gb,Eb */ +l_0x08: eip = dis_op2_G_E ( cb, sorb, OR, True, 1, eip, "or" ); break; case 0x09: /* OR Gv,Ev */ +l_0x09: eip = dis_op2_G_E ( cb, sorb, OR, True, sz, eip, "or" ); break; case 0x10: /* ADC Gb,Eb */ +l_0x10: eip = dis_op2_G_E ( cb, sorb, ADC, True, 1, eip, "adc" ); break; case 0x11: /* ADC Gv,Ev */ +l_0x11: eip = dis_op2_G_E ( cb, sorb, ADC, True, sz, eip, "adc" ); break; case 0x19: /* SBB Gv,Ev */ +l_0x19: eip = dis_op2_G_E ( cb, sorb, SBB, True, sz, eip, "sbb" ); break; case 0x20: /* AND Gb,Eb */ +l_0x20: eip = dis_op2_G_E ( cb, sorb, AND, True, 1, eip, "and" ); break; case 0x21: /* AND Gv,Ev */ +l_0x21: eip = dis_op2_G_E ( cb, sorb, AND, True, sz, eip, "and" ); break; case 0x28: /* SUB Gb,Eb */ +l_0x28: eip = dis_op2_G_E ( cb, sorb, SUB, True, 1, eip, "sub" ); break; case 0x29: /* SUB Gv,Ev */ +l_0x29: eip = dis_op2_G_E ( cb, sorb, SUB, True, sz, eip, "sub" ); break; case 0x30: /* XOR Gb,Eb */ +l_0x30: eip = dis_op2_G_E ( cb, sorb, XOR, True, 1, eip, "xor" ); break; case 0x31: /* XOR Gv,Ev */ +l_0x31: eip = dis_op2_G_E ( cb, sorb, XOR, True, sz, eip, "xor" ); break; case 0x38: /* CMP Gb,Eb */ +l_0x38: eip = dis_op2_G_E ( cb, sorb, SUB, False, 1, eip, "cmp" ); break; case 0x39: /* CMP Gv,Ev */ +l_0x39: eip = dis_op2_G_E ( cb, sorb, SUB, False, sz, eip, "cmp" ); break; @@ -3914,6 +4071,7 @@ case 0x5E: /* POP eSI */ case 0x5F: /* POP eDI */ case 0x5C: /* POP eSP */ +l_0x58_5F: t1 = newTemp(cb); t2 = newTemp(cb); uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2); uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1); @@ -3926,6 +4084,7 @@ break; case 0x9D: /* POPF */ +l_0x9D: vg_assert(sz == 2 || sz == 4); t1 = newTemp(cb); t2 = newTemp(cb); uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2); @@ -3941,6 +4100,7 @@ break; case 0x61: /* POPA */ +l_0x61: { Int reg; /* Just to keep things sane, we assert for a size 4. It's probably OK for size 2 as well, but I'd like to find a test @@ -3982,6 +4142,7 @@ } case 0x8F: /* POPL/POPW m32 */ +l_0x8F: { UInt pair1; Int tmpa; UChar rm = getUChar(eip); @@ -4026,6 +4187,7 @@ case 0x56: /* PUSH eSI */ case 0x57: /* PUSH eDI */ case 0x54: /* PUSH eSP */ +l_0x50_57: /* This is the Right Way, in that the value to be pushed is established before %esp is changed, so that pushl %esp correctly pushes the old value. */ @@ -4042,9 +4204,11 @@ break; case 0x68: /* PUSH Iv */ +l_0x68: d32 = getUDisp(sz,eip); eip += sz; goto do_push_I; case 0x6A: /* PUSH Ib, sign-extended to sz */ +l_0x6A: d32 = getSDisp8(eip); eip += 1; goto do_push_I; do_push_I: @@ -4061,6 +4225,7 @@ break; case 0x9C: /* PUSHF */ +l_0x9C: vg_assert(sz == 2 || sz == 4); t1 = newTemp(cb); t2 = newTemp(cb); t3 = newTemp(cb); uInstr1(cb, GETF, sz, TempReg, t1); @@ -4077,6 +4242,7 @@ break; case 0x60: /* PUSHA */ +l_0x60: { Int reg; /* Just to keep things sane, we assert for a size 4. It's probably OK for size 2 as well, but I'd like to find a test @@ -4123,51 +4289,60 @@ /* ------------------------ SCAS et al ----------------- */ case 0xA4: /* MOVSb, no REP prefix */ +l_0xA4: vg_assert(sorb == 0); codegen_MOVS ( cb, 1 ); if (dis) VG_(printf)("movsb\n"); break; case 0xA5: /* MOVSv, no REP prefix */ +l_0xA5: vg_assert(sorb == 0); codegen_MOVS ( cb, sz ); if (dis) VG_(printf)("movs%c\n", nameISize(sz)); break; case 0xA6: /* CMPSb, no REP prefix */ +l_0xA6: vg_assert(sorb == 0); codegen_CMPS ( cb, 1 ); if (dis) VG_(printf)("cmpsb\n"); break; case 0xAA: /* STOSb, no REP prefix */ +l_0xAA: vg_assert(sorb == 0); codegen_STOS ( cb, 1 ); if (dis) VG_(printf)("stosb\n"); break; case 0xAB: /* STOSv, no REP prefix */ +l_0xAB: vg_assert(sorb == 0); codegen_STOS ( cb, sz ); if (dis) VG_(printf)("stos%c\n", nameISize(sz)); break; case 0xAC: /* LODSb, no REP prefix */ +l_0xAC: vg_assert(sorb == 0); codegen_LODS ( cb, 1 ); if (dis) VG_(printf)("lodsb\n"); break; case 0xAD: /* LODSv, no REP prefix */ +l_0xAD: vg_assert(sorb == 0); codegen_LODS ( cb, sz ); if (dis) VG_(printf)("lods%c\n", nameISize(sz)); break; case 0xAE: /* SCASb, no REP prefix */ +l_0xAE: vg_assert(sorb == 0); codegen_SCAS ( cb, 1 ); if (dis) VG_(printf)("scasb\n"); break; case 0xFC: /* CLD */ +l_0xFC: uInstr0(cb, CALLM_S, 0); uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLD)); uFlagsRWU(cb, FlagsEmpty, FlagD, FlagsEmpty); @@ -4176,6 +4351,7 @@ break; case 0xFD: /* STD */ +l_0xFD: uInstr0(cb, CALLM_S, 0); uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_STD)); uFlagsRWU(cb, FlagsEmpty, FlagD, FlagsEmpty); @@ -4184,6 +4360,7 @@ break; case 0xF8: /* CLC */ +l_0xF8: uInstr0(cb, CALLM_S, 0); uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLC)); uFlagsRWU(cb, FlagsEmpty, FlagC, FlagsOSZAP); @@ -4192,6 +4369,7 @@ break; case 0xF9: /* STC */ +l_0xF9: uInstr0(cb, CALLM_S, 0); uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_STC)); uFlagsRWU(cb, FlagsEmpty, FlagC, FlagsOSZCP); @@ -4199,7 +4377,9 @@ if (dis) VG_(printf)("stc\n"); break; - case 0xF2: { /* REPNE prefix insn */ + case 0xF2: +l_0xF2: + { /* REPNE prefix insn */ Addr eip_orig = eip - 1; vg_assert(sorb == 0); abyte = getUChar(eip); eip++; @@ -4218,7 +4398,9 @@ break; } - case 0xF3: { /* REPE prefix insn */ + case 0xF3: +l_0xF3: + { /* REPE prefix insn */ Addr eip_orig = eip - 1; vg_assert(sorb == 0); abyte = getUChar(eip); eip++; @@ -4258,6 +4440,7 @@ /* ------------------------ XCHG ----------------------- */ case 0x86: /* XCHG Gb,Eb */ +l_0x86: sz = 1; /* Fall through ... */ case 0x87: /* XCHG Gv,Ev */ @@ -4289,6 +4472,7 @@ break; case 0x90: /* XCHG eAX,eAX */ +l_0x90: if (dis) VG_(printf)("nop\n"); break; case 0x91: /* XCHG eAX,eCX */ @@ -4296,12 +4480,16 @@ case 0x93: /* XCHG eAX,eBX */ case 0x96: /* XCHG eAX,eSI */ case 0x97: /* XCHG eAX,eDI */ +l_0x91_93: +l_0x96: +l_0x97: codegen_xchg_eAX_Reg ( cb, sz, opc - 0x90 ); break; /* ------------------------ (Grp1 extensions) ---------- */ case 0x80: /* Grp1 Ib,Eb */ +l_0x80: modrm = getUChar(eip); am_sz = lengthAMode(eip); sz = 1; @@ -4311,6 +4499,7 @@ break; case 0x81: /* Grp1 Iv,Ev */ +l_0x81: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = sz; @@ -4319,6 +4508,7 @@ break; case 0x83: /* Grp1 Ib,Ev */ +l_0x83: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 1; @@ -4329,6 +4519,7 @@ /* ------------------------ (Grp2 extensions) ---------- */ case 0xC0: /* Grp2 Ib,Eb */ +l_0xC0: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 1; @@ -4338,6 +4529,7 @@ break; case 0xC1: /* Grp2 Ib,Ev */ +l_0xC1: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 1; @@ -4346,6 +4538,7 @@ break; case 0xD0: /* Grp2 1,Eb */ +l_0xD0: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 0; @@ -4355,6 +4548,7 @@ break; case 0xD1: /* Grp2 1,Ev */ +l_0xD1: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 0; @@ -4363,6 +4557,7 @@ break; case 0xD2: /* Grp2 CL,Eb */ +l_0xD2: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 0; @@ -4371,6 +4566,7 @@ break; case 0xD3: /* Grp2 CL,Ev */ +l_0xD3: modrm = getUChar(eip); am_sz = lengthAMode(eip); d_sz = 0; @@ -4380,27 +4576,32 @@ /* ------------------------ (Grp3 extensions) ---------- */ case 0xF6: /* Grp3 Eb */ +l_0xF6: eip = dis_Grp3 ( cb, sorb, 1, eip ); break; case 0xF7: /* Grp3 Ev */ +l_0xF7: eip = dis_Grp3 ( cb, sorb, sz, eip ); break; /* ------------------------ (Grp4 extensions) ---------- */ case 0xFE: /* Grp4 Eb */ +l_0xFE: eip = dis_Grp4 ( cb, sorb, eip ); break; /* ------------------------ (Grp5 extensions) ---------- */ case 0xFF: /* Grp5 Ev */ +l_0xFF: eip = dis_Grp5 ( cb, sorb, sz, eip, isEnd ); break; /* ------------------------ Escapes to 2-byte opcodes -- */ case 0x0F: { +l_0x0F: opc = getUChar(eip); eip++; switch (opc) {