aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/X86InstrInfo.def
blob: bbbff33bf39641b84c225d23d4546ef4ccbf2c18 (plain)
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
157
158
159
160
161
162
//===-- 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",   0xE9, M_BRANCH_FLAG, X86II::Void)                       // jmp foo
I(JNE         , "jne",   0x85, M_BRANCH_FLAG, X86II::TB | X86II::Void)
I(JE          , "je",    0x84, M_BRANCH_FLAG, X86II::TB | X86II::Void)
I(CALLpcrel32 , "call",  0xE8, M_BRANCH_FLAG, X86II::Void)

// Misc instructions
I(LEAVE       , "leave", 0xC9,             0, X86II::RawFrm)                     // leave

// Move instructions
I(MOVrr8      , "movb",  0x88,             0, X86II::MRMDestReg)                 // R8  = R8
I(MOVrr16     , "movw",  0x89,             0, X86II::MRMDestReg | X86II::OpSize) // R16 = R16
I(MOVrr32     , "movl",  0x89,             0, X86II::MRMDestReg)                 // R32 = R32
I(MOVir8      , "movb",  0xB0,             0, X86II::AddRegFrm)                  // R8  = imm8
I(MOVir16     , "movw",  0xB8,             0, X86II::AddRegFrm  | X86II::OpSize) // R16 = imm16
I(MOVir32     , "movl",  0xB8,             0, X86II::AddRegFrm)                  // R32 = imm32
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

I(PUSHr32     , "pushl", 0x50,             0, X86II::AddRegFrm | X86II::Void)

// Arithmetic instructions
I(ADDrr8      , "addb",  0x00,             0, X86II::MRMDestReg)                 // R8  += R8
I(ADDrr16     , "addw",  0x01,             0, X86II::MRMDestReg | X86II::OpSize) // R16 += R16
I(ADDrr32     , "addl",  0x01,             0, X86II::MRMDestReg)                 // R32 += R32
I(SUBrr8      , "subb",  0x2A,             0, X86II::MRMDestReg)                 // R8  -= R8
I(SUBrr16     , "subw",  0x2B,             0, X86II::MRMDestReg | X86II::OpSize) // R16 -= R16
I(SUBrr32     , "subl",  0x2B,             0, X86II::MRMDestReg)                 // R32 -= R32
I(MULrr8      , "mulb",  0xF6,             0, X86II::MRMS4r     | X86II::Void)   // AX   = AL*R8
I(MULrr16     , "mulw",  0xF7,             0, X86II::MRMS4r     | X86II::Void |  // DX:AX= AX*R16
                                              X86II::OpSize)
I(MULrr32     , "mull",  0xF7,             0, X86II::MRMS4r     | X86II::Void)   // ED:EA= EA*R32

// unsigned division/remainder
I(DIVrr8      , "divb",  0xF6,             0, X86II::MRMS6r     | X86II::Void)   // AX/r8= AL&AH
I(DIVrr16     , "divw",  0xF7,             0, X86II::MRMS6r     | X86II::Void |  // DA/r16=AX&DX
                                              X86II::OpSize)
I(DIVrr32     , "divl",  0xF7,             0, X86II::MRMS6r     | X86II::Void)   // DA/r32=EAX&DX

// signed division/remainder
I(IDIVrr8     , "idivb", 0xF6,             0, X86II::MRMS7r     | X86II::Void)   // AX/r8= AL&AH
I(IDIVrr16    , "idivw", 0xF7,             0, X86II::MRMS7r     | X86II::Void |  // DA/r16=AX&DX
                                              X86II::OpSize)
I(IDIVrr32    , "idivl", 0xF7,             0, X86II::MRMS7r     | X86II::Void)   // DA/r32=EAX&DX

// Logical operators
I(ANDrr8      , "andb",  0x20,             0, X86II::MRMDestReg)                 // R8  &= R8
I(ANDrr16     , "andw",  0x21,             0, X86II::MRMDestReg | X86II::OpSize) // R16 &= R16
I(ANDrr32     , "andl",  0x21,             0, X86II::MRMDestReg)                 // R32 &= R32
I(ORrr8       , "orb",   0x08,             0, X86II::MRMDestReg)                 // R8  |= R8
I(ORrr16      , "orw",   0x09,             0, X86II::MRMDestReg | X86II::OpSize) // R16 |= R16
I(ORrr32      , "orl",   0x09,             0, X86II::MRMDestReg)                 // R32 |= R32
I(XORrr8      , "xorb",  0x30,             0, X86II::MRMDestReg)                 // R8  ^= R8
I(XORrr16     , "xorw",  0x31,             0, X86II::MRMDestReg | X86II::OpSize) // R16 ^= R16
I(XORrr32     , "xorl",  0x31,             0, X86II::MRMDestReg)                 // R32 ^= R32

// Shift instructions
I(SHLrr8      , "shlb",  0xD2,             0, X86II::MRMS4r)                     // R8   <<= cl   D2/4
I(SHLrr16     , "shlw",  0xD3,             0, X86II::MRMS4r | X86II::OpSize)     // R16  <<= cl   D3/4
I(SHLrr32     , "shll",  0xD3,             0, X86II::MRMS4r)                     // R32  <<= cl   D3/4
I(SHLir8      , "shlb",  0xC0,             0, X86II::MRMS4r)                     // R8   <<= imm8 C0/4 ib
I(SHLir16     , "shlw",  0xC1,             0, X86II::MRMS4r | X86II::OpSize)     // R16  <<= imm8 C1/4 ib
I(SHLir32     , "shll",  0xC1,             0, X86II::MRMS4r)                     // R32  <<= imm8 C1/4 ib
I(SHRrr8      , "shrb",  0xD2,             0, X86II::MRMS5r)                     // R8  >>>= cl   D2/5
I(SHRrr16     , "shrw",  0xD3,             0, X86II::MRMS5r | X86II::OpSize)     // R16 >>>= cl   D3/5
I(SHRrr32     , "shrl",  0xD3,             0, X86II::MRMS5r)                     // R32 >>>= cl   D3/5
I(SHRir8      , "shrb",  0xC0,             0, X86II::MRMS5r)                     // R8  >>>= imm8 C0/5 ib
I(SHRir16     , "shrw",  0xC1,             0, X86II::MRMS5r | X86II::OpSize)     // R16 >>>= imm8 C1/5 ib
I(SHRir32     , "shrl",  0xC1,             0, X86II::MRMS5r)                     // R32 >>>= imm8 C1/5 ib
I(SARrr8      , "sarb",  0xD2,             0, X86II::MRMS7r)                     // R8   >>= cl   D2/7
I(SARrr16     , "sarw",  0xD3,             0, X86II::MRMS7r | X86II::OpSize)     // R16  >>= cl   D3/7
I(SARrr32     , "sarl",  0xD3,             0, X86II::MRMS7r)                     // R32  >>= cl   D3/7
I(SARir8      , "sarb",  0xC0,             0, X86II::MRMS7r)                     // R8   >>= imm8 C0/7 ib
I(SARir16     , "sarw",  0xC1,             0, X86II::MRMS7r | X86II::OpSize)     // R16  >>= imm8 C1/7 ib
I(SARir32     , "sarl",  0xC1,             0, X86II::MRMS7r)                     // R32  >>= imm8 C1/7 ib

// Floating point loads
I(FLDr4       , "flds",  0xD9,             0, X86II::MRMS0m)                     // push float    D9/0
I(FLDr8       , "fldl ", 0xDD,             0, X86II::MRMS0m)                     // 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, X86II::RawFrm)                     // flags = AH
I(SETBr       , "setb",  0x92,             0, X86II::TB | X86II::MRMS0r)         // R8 = < unsign
I(SETAEr      , "setae", 0x93,             0, X86II::TB | X86II::MRMS0r)         // R8 = >=unsign
I(SETEr       , "sete",  0x94,             0, X86II::TB | X86II::MRMS0r)         // R8 = ==
I(SETNEr      , "setne", 0x95,             0, X86II::TB | X86II::MRMS0r)         // R8 = !=
I(SETBEr      , "setbe", 0x96,             0, X86II::TB | X86II::MRMS0r)         // R8 = <=unsign
I(SETAr       , "seta",  0x97,             0, X86II::TB | X86II::MRMS0r)         // R8 = > unsign
I(SETLr       , "setl",  0x9C,             0, X86II::TB | X86II::MRMS0r)         // R8 = < signed
I(SETGEr      , "setge", 0x9D,             0, X86II::TB | X86II::MRMS0r)         // R8 = >=signed
I(SETLEr      , "setle", 0x9E,             0, X86II::TB | X86II::MRMS0r)         // R8 = <=signed
I(SETGr       , "setg",  0x9F,             0, X86II::TB | X86II::MRMS0r)         // R8 = > signed

// Integer comparisons
I(CMPrr8      , "cmpb",  0x38,             0, X86II::MRMDestReg)                 // compare R8,R8
I(CMPrr16     , "cmpw",  0x39,             0, X86II::MRMDestReg | X86II::OpSize) // compare R16,R16
I(CMPrr32     , "cmpl",  0x39,             0, X86II::MRMDestReg)                 // compare R32,R32
I(CMPri8      , "cmp",   0x80,             0, X86II::MRMS7r)                     // compare R8, imm8

// 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