Add CLAC/STAC instruction encoding/decoding support

As these two instructions in AVX extension are privileged instructions for
special purpose, it's only expected to be used in inlined assembly.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179266 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael Liao
2013-04-11 04:52:28 +00:00
parent 959ddbb5e0
commit 02d2e61252
8 changed files with 89 additions and 51 deletions

View File

@@ -274,11 +274,12 @@ namespace X86II {
//// MRM_XX - A mod/rm byte of exactly 0xXX. //// MRM_XX - A mod/rm byte of exactly 0xXX.
MRM_C1 = 33, MRM_C2 = 34, MRM_C3 = 35, MRM_C4 = 36, 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_C8 = 37, MRM_C9 = 38, MRM_CA = 39, MRM_CB = 40,
MRM_F8 = 41, MRM_F9 = 42, MRM_D0 = 45, MRM_D1 = 46, MRM_E8 = 41, MRM_F0 = 42, MRM_F8 = 45, MRM_F9 = 46,
MRM_D4 = 47, MRM_D5 = 48, MRM_D6 = 49, MRM_D8 = 50, MRM_D0 = 47, MRM_D1 = 48, MRM_D4 = 49, MRM_D5 = 50,
MRM_D9 = 51, MRM_DA = 52, MRM_DB = 53, MRM_DC = 54, MRM_D6 = 51, MRM_D8 = 52, MRM_D9 = 53, MRM_DA = 54,
MRM_DD = 55, MRM_DE = 56, MRM_DF = 57, MRM_DB = 55, MRM_DC = 56, MRM_DD = 57, MRM_DE = 58,
MRM_DF = 59,
/// RawFrmImm8 - This is used for the ENTER instruction, which has two /// RawFrmImm8 - This is used for the ENTER instruction, which has two
/// immediates, the first of which is a 16-bit immediate (specified by /// immediates, the first of which is a 16-bit immediate (specified by
@@ -596,12 +597,13 @@ namespace X86II {
} }
case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: 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_C4: case X86II::MRM_C8: case X86II::MRM_C9:
case X86II::MRM_E8: case X86II::MRM_F0: case X86II::MRM_F8: case X86II::MRM_CA: case X86II::MRM_CB: case X86II::MRM_E8:
case X86II::MRM_F9: case X86II::MRM_D0: case X86II::MRM_D1: case X86II::MRM_F0: case X86II::MRM_F8: case X86II::MRM_F9:
case X86II::MRM_D4: case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D0: case X86II::MRM_D1: case X86II::MRM_D4:
case X86II::MRM_D8: case X86II::MRM_D9: case X86II::MRM_DA: case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D8:
case X86II::MRM_DB: case X86II::MRM_DC: case X86II::MRM_DD: case X86II::MRM_D9: case X86II::MRM_DA: case X86II::MRM_DB:
case X86II::MRM_DE: case X86II::MRM_DF: case X86II::MRM_DC: case X86II::MRM_DD: case X86II::MRM_DE:
case X86II::MRM_DF:
return -1; return -1;
} }
} }

View File

@@ -1128,12 +1128,13 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
break; break;
case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: 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_C4: case X86II::MRM_C8: case X86II::MRM_C9:
case X86II::MRM_D0: case X86II::MRM_D1: case X86II::MRM_D4: case X86II::MRM_CA: case X86II::MRM_CB: case X86II::MRM_D0:
case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D8: case X86II::MRM_D1: case X86II::MRM_D4: case X86II::MRM_D5:
case X86II::MRM_D9: case X86II::MRM_DA: case X86II::MRM_DB: case X86II::MRM_D6: case X86II::MRM_D8: case X86II::MRM_D9:
case X86II::MRM_DC: case X86II::MRM_DD: case X86II::MRM_DE: case X86II::MRM_DA: case X86II::MRM_DB: case X86II::MRM_DC:
case X86II::MRM_DF: case X86II::MRM_E8: case X86II::MRM_F0: case X86II::MRM_DD: case X86II::MRM_DE: case X86II::MRM_DF:
case X86II::MRM_F8: case X86II::MRM_F9: case X86II::MRM_E8: case X86II::MRM_F0: case X86II::MRM_F8:
case X86II::MRM_F9:
EmitByte(BaseOpcode, CurByte, OS); EmitByte(BaseOpcode, CurByte, OS);
unsigned char MRM; unsigned char MRM;
@@ -1145,6 +1146,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
case X86II::MRM_C4: MRM = 0xC4; break; case X86II::MRM_C4: MRM = 0xC4; break;
case X86II::MRM_C8: MRM = 0xC8; break; case X86II::MRM_C8: MRM = 0xC8; break;
case X86II::MRM_C9: MRM = 0xC9; break; case X86II::MRM_C9: MRM = 0xC9; break;
case X86II::MRM_CA: MRM = 0xCA; break;
case X86II::MRM_CB: MRM = 0xCB; break;
case X86II::MRM_D0: MRM = 0xD0; break; case X86II::MRM_D0: MRM = 0xD0; break;
case X86II::MRM_D1: MRM = 0xD1; break; case X86II::MRM_D1: MRM = 0xD1; break;
case X86II::MRM_D4: MRM = 0xD4; break; case X86II::MRM_D4: MRM = 0xD4; break;

View File

@@ -1451,6 +1451,14 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
MCE.emitByte(BaseOpcode); MCE.emitByte(BaseOpcode);
MCE.emitByte(0xC9); MCE.emitByte(0xC9);
break; break;
case X86II::MRM_CA:
MCE.emitByte(BaseOpcode);
MCE.emitByte(0xCA);
break;
case X86II::MRM_CB:
MCE.emitByte(BaseOpcode);
MCE.emitByte(0xCB);
break;
case X86II::MRM_E8: case X86II::MRM_E8:
MCE.emitByte(BaseOpcode); MCE.emitByte(BaseOpcode);
MCE.emitByte(0xE8); MCE.emitByte(0xE8);

View File

@@ -35,25 +35,27 @@ def MRM_C3 : Format<35>;
def MRM_C4 : Format<36>; def MRM_C4 : Format<36>;
def MRM_C8 : Format<37>; def MRM_C8 : Format<37>;
def MRM_C9 : Format<38>; def MRM_C9 : Format<38>;
def MRM_E8 : Format<39>; def MRM_CA : Format<39>;
def MRM_F0 : Format<40>; def MRM_CB : Format<40>;
def MRM_F8 : Format<41>; def MRM_E8 : Format<41>;
def MRM_F9 : Format<42>; def MRM_F0 : Format<42>;
def RawFrmImm8 : Format<43>; def RawFrmImm8 : Format<43>;
def RawFrmImm16 : Format<44>; def RawFrmImm16 : Format<44>;
def MRM_D0 : Format<45>; def MRM_F8 : Format<45>;
def MRM_D1 : Format<46>; def MRM_F9 : Format<46>;
def MRM_D4 : Format<47>; def MRM_D0 : Format<47>;
def MRM_D5 : Format<48>; def MRM_D1 : Format<48>;
def MRM_D6 : Format<49>; def MRM_D4 : Format<49>;
def MRM_D8 : Format<50>; def MRM_D5 : Format<50>;
def MRM_D9 : Format<51>; def MRM_D6 : Format<51>;
def MRM_DA : Format<52>; def MRM_D8 : Format<52>;
def MRM_DB : Format<53>; def MRM_D9 : Format<53>;
def MRM_DC : Format<54>; def MRM_DA : Format<54>;
def MRM_DD : Format<55>; def MRM_DB : Format<55>;
def MRM_DE : Format<56>; def MRM_DC : Format<56>;
def MRM_DF : Format<57>; def MRM_DD : Format<57>;
def MRM_DE : Format<58>;
def MRM_DF : Format<59>;
// ImmType - This specifies the immediate type used by an instruction. This is // 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 // part of the ad-hoc solution used to emit machine instruction encodings by our

View File

@@ -520,3 +520,10 @@ def INVPCID32 : I<0x82, MRMSrcMem, (outs), (ins GR32:$src1, i128mem:$src2),
def INVPCID64 : I<0x82, MRMSrcMem, (outs), (ins GR64:$src1, i128mem:$src2), def INVPCID64 : I<0x82, MRMSrcMem, (outs), (ins GR64:$src1, i128mem:$src2),
"invpcid\t{$src2, $src1|$src1, $src2}", []>, OpSize, T8, "invpcid\t{$src2, $src1|$src1, $src2}", []>, OpSize, T8,
Requires<[In64BitMode]>; Requires<[In64BitMode]>;
//===----------------------------------------------------------------------===//
// SMAP Instruction
let Defs = [EFLAGS], Uses = [EFLAGS] in {
def CLAC : I<0x01, MRM_CA, (outs), (ins), "clac", []>, TB;
def STAC : I<0x01, MRM_CB, (outs), (ins), "stac", []>, TB;
}

View File

@@ -121,3 +121,9 @@
# CHECK: xsaveoptq (%rax) # CHECK: xsaveoptq (%rax)
0x48 0x0f 0xae 0x30 0x48 0x0f 0xae 0x30
# CHECK: clac
0x0f 0x01 0xca
# CHECK: stac
0x0f 0x01 0xcb

View File

@@ -1228,3 +1228,11 @@ sysexitl
// CHECK: sysexitq // CHECK: sysexitq
// CHECK: encoding: [0x48,0x0f,0x35] // CHECK: encoding: [0x48,0x0f,0x35]
sysexitq sysexitq
// CHECK: clac
// CHECK: encoding: [0x0f,0x01,0xca]
clac
// CHECK: stac
// CHECK: encoding: [0x0f,0x01,0xcb]
stac

View File

@@ -29,23 +29,25 @@ using namespace llvm;
MAP(C4, 36) \ MAP(C4, 36) \
MAP(C8, 37) \ MAP(C8, 37) \
MAP(C9, 38) \ MAP(C9, 38) \
MAP(E8, 39) \ MAP(CA, 39) \
MAP(F0, 40) \ MAP(CB, 40) \
MAP(F8, 41) \ MAP(E8, 41) \
MAP(F9, 42) \ MAP(F0, 42) \
MAP(D0, 45) \ MAP(F8, 45) \
MAP(D1, 46) \ MAP(F9, 46) \
MAP(D4, 47) \ MAP(D0, 47) \
MAP(D5, 48) \ MAP(D1, 48) \
MAP(D6, 49) \ MAP(D4, 49) \
MAP(D8, 50) \ MAP(D5, 50) \
MAP(D9, 51) \ MAP(D6, 51) \
MAP(DA, 52) \ MAP(D8, 52) \
MAP(DB, 53) \ MAP(D9, 53) \
MAP(DC, 54) \ MAP(DA, 54) \
MAP(DD, 55) \ MAP(DB, 55) \
MAP(DE, 56) \ MAP(DC, 56) \
MAP(DF, 57) MAP(DD, 57) \
MAP(DE, 58) \
MAP(DF, 59)
// A clone of X86 since we can't depend on something that is generated. // A clone of X86 since we can't depend on something that is generated.
namespace X86Local { namespace X86Local {