From 9e3d0b335111b2df73984a6cfd9ef1cd5d323872 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 18 Feb 2012 08:19:49 +0000 Subject: [PATCH] Add X86 assembler and disassembler support for AMD SVM instructions. Original patch by Kay Tiong Khoo. Few tweaks by me for code density and to reduce replication. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150873 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 41 ++++------ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 82 ++++++++----------- lib/Target/X86/X86InstrFormats.td | 8 ++ lib/Target/X86/X86InstrInfo.td | 1 + test/MC/Disassembler/X86/simple-tests.txt | 24 ++++++ test/MC/Disassembler/X86/x86-32.txt | 24 ++++++ test/MC/X86/x86-32-coverage.s | 24 ++++++ test/MC/X86/x86-32.s | 27 +++++- utils/TableGen/EDEmitter.cpp | 2 + utils/TableGen/X86RecognizableInstr.cpp | 10 ++- 10 files changed, 170 insertions(+), 73 deletions(-) diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index c41e9e7aef6..6232a450997 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -229,19 +229,12 @@ namespace X86II { // destinations are the same register. MRMInitReg = 32, - //// MRM_C1 - A mod/rm byte of exactly 0xC1. - MRM_C1 = 33, - MRM_C2 = 34, - MRM_C3 = 35, - MRM_C4 = 36, - MRM_C8 = 37, - MRM_C9 = 38, - MRM_E8 = 39, - MRM_F0 = 40, - MRM_F8 = 41, - MRM_F9 = 42, - MRM_D0 = 45, - MRM_D1 = 46, + //// MRM_XX - A mod/rm byte of exactly 0xXX. + MRM_C1 = 33, MRM_C2 = 34, MRM_C3 = 35, MRM_C4 = 36, + MRM_C8 = 37, MRM_C9 = 38, MRM_E8 = 39, MRM_F0 = 40, + MRM_F8 = 41, MRM_F9 = 42, MRM_D0 = 45, MRM_D1 = 46, + MRM_D8 = 47, MRM_D9 = 48, MRM_DA = 49, MRM_DB = 50, + MRM_DC = 51, MRM_DD = 52, MRM_DE = 53, MRM_DF = 54, /// RawFrmImm8 - This is used for the ENTER instruction, which has two /// immediates, the first of which is a 16-bit immediate (specified by @@ -535,18 +528,16 @@ namespace X86II { ++FirstMemOp;// Skip the register dest (which is encoded in VEX_VVVV). return FirstMemOp; } - 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_E8: - case X86II::MRM_F0: - case X86II::MRM_F8: - case X86II::MRM_F9: - case X86II::MRM_D0: - case X86II::MRM_D1: + 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_E8: case X86II::MRM_F0: + case X86II::MRM_F8: case X86II::MRM_F9: + case X86II::MRM_D0: case X86II::MRM_D1: + case X86II::MRM_D8: case X86II::MRM_D9: + case X86II::MRM_DA: case X86II::MRM_DB: + case X86II::MRM_DC: case X86II::MRM_DD: + case X86II::MRM_DE: case X86II::MRM_DF: return -1; } } diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index b0305b44cff..4af03124bed 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1058,53 +1058,43 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, TSFlags, CurByte, OS, Fixups); CurOp += X86::AddrNumOperands; break; - case X86II::MRM_C1: + 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_D0: case X86II::MRM_D1: + case X86II::MRM_D8: case X86II::MRM_D9: + case X86II::MRM_DA: case X86II::MRM_DB: + case X86II::MRM_DC: case X86II::MRM_DD: + case X86II::MRM_DE: case X86II::MRM_DF: + case X86II::MRM_E8: case X86II::MRM_F0: + case X86II::MRM_F8: case X86II::MRM_F9: EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xC1, CurByte, OS); - break; - case X86II::MRM_C2: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xC2, CurByte, OS); - break; - case X86II::MRM_C3: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xC3, CurByte, OS); - break; - case X86II::MRM_C4: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xC4, CurByte, OS); - break; - case X86II::MRM_C8: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xC8, CurByte, OS); - break; - case X86II::MRM_C9: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xC9, CurByte, OS); - break; - case X86II::MRM_E8: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xE8, CurByte, OS); - break; - case X86II::MRM_F0: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xF0, CurByte, OS); - break; - case X86II::MRM_F8: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xF8, CurByte, OS); - break; - case X86II::MRM_F9: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xF9, CurByte, OS); - break; - case X86II::MRM_D0: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xD0, CurByte, OS); - break; - case X86II::MRM_D1: - EmitByte(BaseOpcode, CurByte, OS); - EmitByte(0xD1, CurByte, OS); + + unsigned char MRM; + switch (TSFlags & X86II::FormMask) { + default: llvm_unreachable("Invalid Form"); + case X86II::MRM_C1: MRM = 0xC1; break; + case X86II::MRM_C2: MRM = 0xC2; break; + case X86II::MRM_C3: MRM = 0xC3; break; + case X86II::MRM_C4: MRM = 0xC4; break; + case X86II::MRM_C8: MRM = 0xC8; break; + case X86II::MRM_C9: MRM = 0xC9; break; + case X86II::MRM_D0: MRM = 0xD0; break; + case X86II::MRM_D1: MRM = 0xD1; break; + case X86II::MRM_D8: MRM = 0xD8; break; + case X86II::MRM_D9: MRM = 0xD9; break; + case X86II::MRM_DA: MRM = 0xDA; break; + case X86II::MRM_DB: MRM = 0xDB; break; + case X86II::MRM_DC: MRM = 0xDC; break; + case X86II::MRM_DD: MRM = 0xDD; break; + case X86II::MRM_DE: MRM = 0xDE; break; + case X86II::MRM_DF: MRM = 0xDF; break; + case X86II::MRM_E8: MRM = 0xE8; break; + case X86II::MRM_F0: MRM = 0xF0; break; + case X86II::MRM_F8: MRM = 0xF8; break; + case X86II::MRM_F9: MRM = 0xF9; break; + } + EmitByte(MRM, CurByte, OS); break; } diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index ecb1fc8751e..dc4cb3b3a41 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -43,6 +43,14 @@ def RawFrmImm8 : Format<43>; def RawFrmImm16 : Format<44>; def MRM_D0 : Format<45>; def MRM_D1 : Format<46>; +def MRM_D8 : Format<47>; +def MRM_D9 : Format<48>; +def MRM_DA : Format<49>; +def MRM_DB : Format<50>; +def MRM_DC : Format<51>; +def MRM_DD : Format<52>; +def MRM_DE : Format<53>; +def MRM_DF : Format<54>; // ImmType - This specifies the immediate type used by an instruction. This is // part of the ad-hoc solution used to emit machine instruction encodings by our diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 5931f664766..91dc303328f 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1538,6 +1538,7 @@ include "X86InstrMMX.td" include "X86Instr3DNow.td" include "X86InstrVMX.td" +include "X86InstrSVM.td" // System instructions. include "X86InstrSystem.td" diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index 4f55068733a..5f6ae3b82be 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -52,6 +52,30 @@ # CHECK: vmptrst 0x0f 0xc7 0x38 +# CHECK: vmrun +0x0f 0x01 0xd8 + +# CHECK: vmmcall +0x0f 0x01 0xd9 + +# CHECK: vmload +0x0f 0x01 0xda + +# CHECK: vmsave +0x0f 0x01 0xdb + +# CHECK: stgi +0x0f 0x01 0xdc + +# CHECK: clgi +0x0f 0x01 0xdd + +# CHECK: skinit +0x0f 0x01 0xde + +# CHECK: invlpga +0x0f 0x01 0xdf + # CHECK: movl $0, -4(%rbp) 0xc7 0x45 0xfc 0x00 0x00 0x00 0x00 diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt index 5d5ee5dc058..6911d012cdd 100644 --- a/test/MC/Disassembler/X86/x86-32.txt +++ b/test/MC/Disassembler/X86/x86-32.txt @@ -87,6 +87,30 @@ # CHECK: vmptrst 0x0f 0xc7 0x38 +# CHECK: vmrun +0x0f 0x01 0xd8 + +# CHECK: vmmcall +0x0f 0x01 0xd9 + +# CHECK: vmload +0x0f 0x01 0xda + +# CHECK: vmsave +0x0f 0x01 0xdb + +# CHECK: stgi +0x0f 0x01 0xdc + +# CHECK: clgi +0x0f 0x01 0xdd + +# CHECK: skinit +0x0f 0x01 0xde + +# CHECK: invlpga +0x0f 0x01 0xdf + # CHECK: movl $0, -4(%ebp) 0xc7 0x45 0xfc 0x00 0x00 0x00 0x00 diff --git a/test/MC/X86/x86-32-coverage.s b/test/MC/X86/x86-32-coverage.s index 577ac40e321..cee119827f0 100644 --- a/test/MC/X86/x86-32-coverage.s +++ b/test/MC/X86/x86-32-coverage.s @@ -18465,6 +18465,30 @@ // CHECK: vmxon 305419896 vmxon 0x12345678 +// CHECK: vmrun %eax + vmrun %eax + +// CHECK: vmmcall + vmmcall + +// CHECK: vmload %eax + vmload %eax + +// CHECK: vmsave %eax + vmsave %eax + +// CHECK: stgi + stgi + +// CHECK: clgi + clgi + +// CHECK: skinit %eax + skinit %eax + +// CHECK: invlpga %ecx, %eax + invlpga %ecx, %eax + // CHECK: phaddw 3735928559(%ebx,%ecx,8), %mm3 phaddw 0xdeadbeef(%ebx,%ecx,8),%mm3 diff --git a/test/MC/X86/x86-32.s b/test/MC/X86/x86-32.s index 19f14450fee..c4eb4ffca81 100644 --- a/test/MC/X86/x86-32.s +++ b/test/MC/X86/x86-32.s @@ -41,7 +41,32 @@ // CHECK: swapgs // CHECK: encoding: [0x0f,0x01,0xf8] -rdtscp + vmrun %eax +// CHECK: vmrun %eax +// CHECK: encoding: [0x0f,0x01,0xd8] + vmmcall +// CHECK: vmmcall +// CHECK: encoding: [0x0f,0x01,0xd9] + vmload %eax +// CHECK: vmload %eax +// CHECK: encoding: [0x0f,0x01,0xda] + vmsave %eax +// CHECK: vmsave %eax +// CHECK: encoding: [0x0f,0x01,0xdb] + stgi +// CHECK: stgi +// CHECK: encoding: [0x0f,0x01,0xdc] + clgi +// CHECK: clgi +// CHECK: encoding: [0x0f,0x01,0xdd] + skinit %eax +// CHECK: skinit %eax +// CHECK: encoding: [0x0f,0x01,0xde] + invlpga %ecx, %eax +// CHECK: invlpga %ecx, %eax +// CHECK: encoding: [0x0f,0x01,0xdf] + + rdtscp // CHECK: rdtscp // CHECK: encoding: [0x0f,0x01,0xf9] diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 8ae42025792..e0fd566d8db 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -519,6 +519,8 @@ static void X86ExtractSemantics( // ignore (doesn't go anywhere we know about) } else if (name.find("VMCALL") != name.npos) { // ignore (rather different semantics than a regular call) + } else if (name.find("VMMCALL") != name.npos) { + // ignore (rather different semantics than a regular call) } else if (name.find("FAR") != name.npos && name.find("i") != name.npos) { CALL("off"); } else { diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 385e5797519..e5b10a7ec83 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -36,7 +36,15 @@ using namespace llvm; MAP(F8, 41) \ MAP(F9, 42) \ MAP(D0, 45) \ - MAP(D1, 46) + MAP(D1, 46) \ + MAP(D8, 47) \ + MAP(D9, 48) \ + MAP(DA, 49) \ + MAP(DB, 50) \ + MAP(DC, 51) \ + MAP(DD, 52) \ + MAP(DE, 53) \ + MAP(DF, 54) // A clone of X86 since we can't depend on something that is generated. namespace X86Local { -- 2.34.1