1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
//===-- X86InstructionInfo.def - X86 Instruction Information ----*- C++ -*-===//
//
// This file describes all of the instructions that the X86 backend uses. It
// relys on an external 'I' macro being defined that takes the arguments
// specified below, and is used to make all of the information relevant to an
// instruction be in one place.
//
// Note that X86 Instructions always have the destination register listed as
// operand 0, unless it does not produce a value (in which case the TSFlags will
// include X86II::Void).
//
//===----------------------------------------------------------------------===//
// NOTE: No include guards desired
#ifndef I
#errror "Must define I macro before including X86/X86InstructionInfo.def!"
#endif
// Arguments to be passed into the I macro
// #1: Enum name - This ends up being the opcode symbol in the X86 namespace
// #2: Opcode name, as used by the gnu assembler
// #3: The base opcode for the instruction
// #4: Instruction Flags - This should be a field or'd together that contains
// constants from the MachineInstrInfo.h file.
// #5: Target Specific Flags - Another bitfield containing X86 specific flags
// that we are interested in for each instruction. These should be flags
// defined in X86InstrInfo.h in the X86II namespace.
//
// The first instruction must always be the PHI instruction:
I(PHI , "phi", 0, 0, 0)
// The second instruction must always be the noop instruction:
I(NOOP , "nop", 0x90, 0, X86II::RawFrm | X86II::Void) // nop
// Flow control instructions
I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret
I(JMP , "jmp", 0x00, M_BRANCH_FLAG, X86II::Void) // jmp foo EB|E9 cb|w
I(JNE , "jne", 0x00, M_BRANCH_FLAG, X86II::Void) // 75 cb, or 0f 85 cw|cd
I(JE , "je", 0x00, M_BRANCH_FLAG, X86II::Void) // 74 cb, or 0f 84 cw|cd
// Misc instructions
I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave
// Move instructions
I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg) // R8 = R8 88/r
I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize) // R16 = R16 89/r
I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg) // R32 = R32 89/r
I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm) // R8 = imm8 B0+ rb
I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize) // R16 = imm16 B8+ rw
I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm) // R32 = imm32 B8+ rd
I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem) // R8 = [mem] 8A/r
I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem | X86II::OpSize) // R16 = [mem] 8B/r
I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem) // R32 = [mem] 8B/r
I(MOVrm8 , "movb", 0x88, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R8 88/r
I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void | // [mem] = R16 89/r
X86II::OpSize)
I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R32 89/r
// Arithmetic instructions
I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg) // R8 += R8 00/r
I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize) // R16 += R16 01/r
I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg) // R32 += R32 01/r
I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg) // R8 -= R8 2A/r
I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize) // R16 -= R16 2B/r
I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg) // R32 -= R32 2B/r
I(MULrr8 , "mulb", 0xF6, 0, X86II::Void) // AX = AL*R8 F6/4
I(MULrr16 , "mulw", 0xF7, 0, X86II::Void | X86II::OpSize) // DX:AX= AX*R16 F7/4
I(MULrr32 , "mull", 0xF7, 0, X86II::Void) // ED:EA= EA*R32 F7/4
// unsigned division/remainder
I(DIVrr8 , "divb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6
I(DIVrr16 , "divw", 0xF7, 0, X86II::Void | X86II::OpSize) // DA/r16=AX&DX F7/6
I(DIVrr32 , "divl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6
// signed division/remainder
I(IDIVrr8 , "idivb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6
I(IDIVrr16 , "idivw", 0xF7, 0, X86II::Void | X86II::OpSize) // DA/r16=AX&DX F7/6
I(IDIVrr32 , "idivl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6
// Logical operators
I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg) // R8 &= R8 20/r
I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize) // R16 &= R16 21/r
I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg) // R32 &= R32 21/r
I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg) // R8 |= R8 08/r
I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize) // R16 |= R16 09/r
I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg) // R32 |= R32 09/r
I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg) // R8 ^= R8 30/r
I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize) // R16 ^= R16 31/r
I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg) // R32 ^= R32 31/r
// Shift instructions
I(SHLrr8 , "shlb", 0xD2, 0, 0) // R8 <<= cl D2/4
I(SHLrr16 , "shlw", 0xD3, 0, X86II::OpSize) // R16 <<= cl D3/4
I(SHLrr32 , "shll", 0xD3, 0, 0) // R32 <<= cl D3/4
I(SHLir8 , "shlb", 0xC0, 0, 0) // R8 <<= imm8 C0/4 ib
I(SHLir16 , "shlw", 0xC1, 0, X86II::OpSize) // R16 <<= imm8 C1/4 ib
I(SHLir32 , "shll", 0xC1, 0, 0) // R32 <<= imm8 C1/4 ib
I(SHRrr8 , "shrb", 0xD2, 0, 0) // R8 >>>= cl D2/5
I(SHRrr16 , "shrw", 0xD3, 0, X86II::OpSize) // R16 >>>= cl D3/5
I(SHRrr32 , "shrl", 0xD3, 0, 0) // R32 >>>= cl D3/5
I(SHRir8 , "shrb", 0xC0, 0, 0) // R8 >>>= imm8 C0/5 ib
I(SHRir16 , "shrw", 0xC1, 0, X86II::OpSize) // R16 >>>= imm8 C1/5 ib
I(SHRir32 , "shrl", 0xC1, 0, 0) // R32 >>>= imm8 C1/5 ib
I(SARrr8 , "sarb", 0xD2, 0, 0) // R8 >>= cl D2/7
I(SARrr16 , "sarw", 0xD3, 0, X86II::OpSize) // R16 >>= cl D3/7
I(SARrr32 , "sarl", 0xD3, 0, 0) // R32 >>= cl D3/7
I(SARir8 , "sarb", 0xC0, 0, 0) // R8 >>= imm8 C0/7 ib
I(SARir16 , "sarw", 0xC1, 0, X86II::OpSize) // R16 >>= imm8 C1/7 ib
I(SARir32 , "sarl", 0xC1, 0, 0) // R32 >>= imm8 C1/7 ib
// Floating point loads
I(FLDr4 , "flds", 0xD9, 0, X86II::Void) // push float D9/0
I(FLDr8 , "fldl ", 0xDD, 0, X86II::Void) // push double DD/0
// Floating point compares
I(FUCOMPP , "fucompp", 0xDA, 0, X86II::Void) // compare+pop2x DA E9
// Floating point flag ops
I(FNSTSWr8 , "fnstsw", 0xDF, 0, X86II::Void) // AX = fp flags DF E0
// Condition code ops, incl. set if equal/not equal/...
I(SAHF , "sahf", 0x9E, 0, 0) // flags = AH 9E
I(SETAr , "seta", 0x97, 0, X86II::TB) // R8 = > unsign 0F 97
I(SETAEr , "setae", 0x93, 0, X86II::TB) // R8 = >=unsign 0F 93
I(SETBr , "setb", 0x92, 0, X86II::TB) // R8 = < unsign 0F 92
I(SETBEr , "setbe", 0x96, 0, X86II::TB) // R8 = <=unsign 0F 96
I(SETEr , "sete", 0x94, 0, X86II::TB) // R8 = == 0F 94
I(SETGr , "setg", 0x9F, 0, X86II::TB) // R8 = > signed 0F 9F
I(SETGEr , "setge", 0x9D, 0, X86II::TB) // R8 = >=signed 0F 9D
I(SETLr , "setl", 0x9C, 0, X86II::TB) // R8 = < signed 0F 9C
I(SETLEr , "setle", 0x9E, 0, X86II::TB) // R8 = <=signed 0F 9E
I(SETNEr , "setne", 0x95, 0, X86II::TB) // R8 = != 0F 95
// Integer comparisons
I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 38/r
I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize) // compare R16,R16 39/r
I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 39/r
I(CMPri8 , "cmp", 0x80, 0, 0) // compare R8, imm8 80 /7 ib
// Sign extenders (first 3 are good for DIV/IDIV; the others are more general)
I(CBW , "cbw", 0x98, 0, X86II::RawFrm) // AX = signext(AL)
I(CWD , "cwd", 0x99, 0, X86II::RawFrm) // DX:AX = signext(AX)
I(CDQ , "cdq", 0x99, 0, X86II::RawFrm) // EDX:EAX = signext(EAX)
I(MOVSXr16r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB | // R16 = signext(R8)
X86II::OpSize)
I(MOVSXr32r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R8)
I(MOVSXr32r16 , "movsx", 0xBF, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R16)
I(MOVZXr16r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB | // R16 = zeroext(R8)
X86II::OpSize)
I(MOVZXr32r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R8)
I(MOVZXr32r16 , "movzx", 0xB7, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R16)
// At this point, I is dead, so undefine the macro
#undef I
|