From d8fdb19a7fb559f9718c11217fd7dba814ad469b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 10 Feb 2014 00:50:34 +0000 Subject: [PATCH] Add MRMXr/MRMXm form to X86 for use by instructions which treat the 'reg' field of modrm byte as a don't care value. Will allow for simplification of disassembler code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201059 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 6 ++++++ lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 15 +++++++++++---- lib/Target/X86/X86CodeEmitter.cpp | 8 ++++++-- lib/Target/X86/X86InstrCMovSetCC.td | 4 ++-- lib/Target/X86/X86InstrFormats.td | 1 + lib/Target/X86/X86InstrInfo.td | 4 ++-- lib/Target/X86/X86InstrSSE.td | 2 +- utils/TableGen/X86RecognizableInstr.cpp | 6 ++++++ 8 files changed, 35 insertions(+), 11 deletions(-) diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index f35cc9d7bb1..905d4e0db5d 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -272,6 +272,10 @@ namespace X86II { /// destination index register DI/ESI/RDI. RawFrmDstSrc = 10, + /// MRMX[rm] - The forms are used to represent instructions that use a + /// Mod/RM byte, and don't use the middle field for anything. + MRMXr = 14, MRMXm = 15, + /// MRM[0-7][rm] - These forms are used to represent instructions that use /// a Mod/RM byte, and use the middle field to hold extended opcode /// information. In the intel manual these are represented as /0, /1, ... @@ -674,11 +678,13 @@ namespace X86II { // Opcode == X86::LEA16r || Opcode == X86::LEA32r) return FirstMemOp; } + case X86II::MRMXr: case X86II::MRM0r: case X86II::MRM1r: case X86II::MRM2r: case X86II::MRM3r: case X86II::MRM4r: case X86II::MRM5r: case X86II::MRM6r: case X86II::MRM7r: return -1; + case X86II::MRMXm: case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index a76eecaaee6..5a4111044ea 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1426,28 +1426,35 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, break; } + case X86II::MRMXr: case X86II::MRM0r: case X86II::MRM1r: case X86II::MRM2r: case X86II::MRM3r: case X86II::MRM4r: case X86II::MRM5r: - case X86II::MRM6r: case X86II::MRM7r: + case X86II::MRM6r: case X86II::MRM7r: { if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). ++CurOp; EmitByte(BaseOpcode, CurByte, OS); + uint64_t Form = TSFlags & X86II::FormMask; EmitRegModRMByte(MI.getOperand(CurOp++), - (TSFlags & X86II::FormMask)-X86II::MRM0r, + (Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r, CurByte, OS); break; + } + + case X86II::MRMXm: case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: - case X86II::MRM6m: case X86II::MRM7m: + case X86II::MRM6m: case X86II::MRM7m: { if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). ++CurOp; EmitByte(BaseOpcode, CurByte, OS); - EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m, + uint64_t Form = TSFlags & X86II::FormMask; + EmitMemModRMByte(MI, CurOp, (Form == X86II::MRMXm) ? 0 : Form-X86II::MRM0m, TSFlags, CurByte, OS, Fixups, STI); CurOp += X86::AddrNumOperands; break; + } case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: case X86II::MRM_C4: case X86II::MRM_C8: case X86II::MRM_C9: case X86II::MRM_CA: case X86II::MRM_CB: case X86II::MRM_D0: diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 579bf9b3e6d..378f24d9fe8 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -1295,6 +1295,7 @@ void Emitter::emitInstruction(MachineInstr &MI, break; } + case X86II::MRMXr: case X86II::MRM0r: case X86II::MRM1r: case X86II::MRM2r: case X86II::MRM3r: case X86II::MRM4r: case X86II::MRM5r: @@ -1302,8 +1303,9 @@ void Emitter::emitInstruction(MachineInstr &MI, if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). ++CurOp; MCE.emitByte(BaseOpcode); + uint64_t Form = (Desc->TSFlags & X86II::FormMask); emitRegModRMByte(MI.getOperand(CurOp++).getReg(), - (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r); + (Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r); if (CurOp == NumOps) break; @@ -1332,6 +1334,7 @@ void Emitter::emitInstruction(MachineInstr &MI, break; } + case X86II::MRMXm: case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: @@ -1343,7 +1346,8 @@ void Emitter::emitInstruction(MachineInstr &MI, X86II::getSizeOfImm(Desc->TSFlags) : 4) : 0; MCE.emitByte(BaseOpcode); - emitMemModRMByte(MI, CurOp, (Desc->TSFlags & X86II::FormMask)-X86II::MRM0m, + uint64_t Form = (Desc->TSFlags & X86II::FormMask); + emitMemModRMByte(MI, CurOp, (Form==X86II::MRMXm) ? 0 : Form - X86II::MRM0m, PCAdj); CurOp += X86::AddrNumOperands; diff --git a/lib/Target/X86/X86InstrCMovSetCC.td b/lib/Target/X86/X86InstrCMovSetCC.td index 9a8ac630b6f..315f21308c0 100644 --- a/lib/Target/X86/X86InstrCMovSetCC.td +++ b/lib/Target/X86/X86InstrCMovSetCC.td @@ -82,11 +82,11 @@ defm CMOVG : CMOV<0x4F, "cmovg" , X86_COND_G>; // SetCC instructions. multiclass SETCC opc, string Mnemonic, PatLeaf OpNode> { let Uses = [EFLAGS] in { - def r : I, TB, Sched<[WriteALU]>; - def m : I, TB, Sched<[WriteALU, WriteStore]>; diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index a834438ffcc..bff583ac506 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -24,6 +24,7 @@ def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>; def MRMSrcMem : Format<6>; def RawFrmMemOffs : Format<7>; def RawFrmSrc : Format<8>; def RawFrmDst : Format<9>; def RawFrmDstSrc: Format<10>; +def MRMXr : Format<14>; def MRMXm : Format<15>; def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>; def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>; def MRM6r : Format<22>; def MRM7r : Format<23>; diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index e1fc2ace832..776bd8145a7 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -928,9 +928,9 @@ def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{ // Nop let neverHasSideEffects = 1, SchedRW = [WriteZero] in { def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>; - def NOOPW : I<0x1f, MRM0m, (outs), (ins i16mem:$zero), + def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero), "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16; - def NOOPL : I<0x1f, MRM0m, (outs), (ins i32mem:$zero), + def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero), "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32; } diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index ea91b5b1042..431d973026b 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -7677,7 +7677,7 @@ defm : pclmul_alias<"lqlq", 0x00>; let Predicates = [HasSSE4A] in { let Constraints = "$src = $dst" in { -def EXTRQI : Ii8<0x78, MRM0r, (outs VR128:$dst), +def EXTRQI : Ii8<0x78, MRMXr, (outs VR128:$dst), (ins VR128:$src, i8imm:$len, i8imm:$idx), "extrq\t{$idx, $len, $src|$src, $len, $idx}", [(set VR128:$dst, (int_x86_sse4a_extrqi VR128:$src, imm:$len, diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 62aab5b68ae..6ddc208442e 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -63,6 +63,7 @@ namespace X86Local { RawFrmSrc = 8, RawFrmDst = 9, RawFrmDstSrc = 10, + MRMXr = 14, MRMXm = 15, MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, @@ -165,6 +166,8 @@ static bool needsModRMForDecode(uint8_t form) { form == X86Local::MRMDestMem || form == X86Local::MRMSrcReg || form == X86Local::MRMSrcMem || + form == X86Local::MRMXr || + form == X86Local::MRMXm || (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || (form >= X86Local::MRM0m && form <= X86Local::MRM7m)); } @@ -178,6 +181,7 @@ static bool needsModRMForDecode(uint8_t form) { static bool isRegFormat(uint8_t form) { return (form == X86Local::MRMDestReg || form == X86Local::MRMSrcReg || + form == X86Local::MRMXr || (form >= X86Local::MRM0r && form <= X86Local::MRM7r)); } @@ -741,6 +745,7 @@ void RecognizableInstr::emitInstructionSpecifier() { HANDLE_OPTIONAL(immediate) HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 break; + case X86Local::MRMXr: case X86Local::MRM0r: case X86Local::MRM1r: case X86Local::MRM2r: @@ -767,6 +772,7 @@ void RecognizableInstr::emitInstructionSpecifier() { HANDLE_OPTIONAL(relocation) HANDLE_OPTIONAL(immediate) break; + case X86Local::MRMXm: case X86Local::MRM0m: case X86Local::MRM1m: case X86Local::MRM2m: