aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/PPCInstrInfo.td
blob: ec1f7a5fc57e618fa31a69b9fb972dd878807b46 (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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//===- PowerPCInstrInfo.td - The PowerPC Instruction Set -----*- tablegen -*-=//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file describes the subset of the 32-bit PowerPC instruction set, as used
// by the PowerPC instruction selector.
//
//===----------------------------------------------------------------------===//

include "PowerPCInstrFormats.td"

let isTerminator = 1, isReturn = 1 in
  def BLR : XLForm_2_ext<"blr", 19, 16, 20, 31, 1, 0, 0>;

class II<dag OL, string asmstr> {
  dag OperandList = OL;
  string AsmString = asmstr;
}

def u16imm  : Operand<i16> {
  let PrintMethod = "printU16ImmOperand";
}


// Pseudo-instructions:
def PHI : Pseudo<"PHI">;          // PHI node...
def ADJCALLSTACKDOWN : Pseudo<"ADJCALLSTACKDOWN">;
def ADJCALLSTACKUP : Pseudo<"ADJCALLSTACKUP">;
let Defs = [LR] in
  def MovePCtoLR : Pseudo<"MovePCtoLR">;
def IMPLICIT_DEF : Pseudo<"IMPLICIT_DEF">;

def LA : DForm_2<"la", 14, 0, 0>;
def LOADHiAddr : DForm_2_r0<"addis", 15, 0, 0>;

def ADDI : DForm_2<"addi", 14, 0, 0>;
def ADDIS : DForm_2<"addis", 15, 0, 0>;
def SUBI : DForm_2<"subi", 14, 0, 0>;
def LI : DForm_2_r0<"li", 14, 0, 0>;
def LIS : DForm_2_r0<"lis", 15, 0, 0>;
def ADDIC : DForm_2<"addic",  12, 0, 0>;
def ADD : XOForm_1<"add", 31, 266, 0, 0, 0, 0>;
def ADDC : XOForm_1<"addc", 31, 10, 0, 0, 0, 0>;
def ADDE : XOForm_1<"adde", 31, 138, 0, 0, 0, 0>;
def ADDZE : XOForm_3<"addze", 31, 202, 0, 0, 0, 0>;
def ANDIo : DForm_4<28, 0, 0,
                   (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                   "andi. $dst, $src1, $src2">;
def AND  : XForm_6<"and",  31, 28, 0, 0, 0>;
def ANDC  : XForm_6<"andc",  31, 60, 0, 0, 0>;

let isBranch = 1, isTerminator = 1 in {
  def COND_BRANCH : Pseudo<"COND_BRANCH">;
  def B : IForm<"b", 18, 0, 0, 0, 0>;
  // FIXME: 4*CR# needs to be added to the BI field!
  // This will only work for CR0 as it stands now
  def BLT : BForm_ext<"blt", 16, 0, 0, 12, 0, 0, 0>;
  def BLE : BForm_ext<"ble", 16, 0, 0, 4,  1, 0, 0>;
  def BEQ : BForm_ext<"beq", 16, 0, 0, 12, 2, 0, 0>;
  def BGE : BForm_ext<"bge", 16, 0, 0, 4,  0, 0, 0>;
  def BGT : BForm_ext<"bgt", 16, 0, 0, 12, 1, 0, 0>;
  def BNE : BForm_ext<"bne", 16, 0, 0, 4,  2, 0, 0>;
}

let isBranch = 1, isTerminator = 1, isCall = 1, 
  // All calls clobber the non-callee saved registers...
  Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,
          F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
          LR,XER,CTR,
          CR0,CR1,CR5,CR6,CR7] in {
  // Convenient aliases for call instructions
  def CALLpcrel : IForm<"bl", 18, 0, 1, 0, 0>;
  def CALLindirect : XLForm_2_ext<"bctrl", 19, 528, 20, 31, 1, 0, 0>;
}

def CMPI : DForm_5<"cmpi", 11, 0, 0>;
def CMPWI : DForm_5_ext<"cmpwi", 11, 0, 0>;
def CMPDI : DForm_5_ext<"cmpdi", 11, 1, 0>;
def CMP : XForm_16<"cmp", 31, 0, 0, 0>;
def CMPW : XForm_16_ext<"cmpw", 31, 0, 0, 0>;
def CMPD : XForm_16_ext<"cmpd", 31, 0, 1, 0>;
def CMPLI : DForm_6<10, 0, 0,
                    (ops CRRC:$dst, i1imm:$size, GPRC:$src1, u16imm:$src2),
                         "cmpli $dst, $size, $src1, $src2">;
def CMPLWI : DForm_6_ext<10, 0, 0,
                         (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
                         "cmplwi $dst, $src1, $src2">;
def CMPLDI : DForm_6_ext<10, 1, 0,
                         (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
                         "cmpldi $dst, $src1, $src2">;
def CMPL : XForm_16<"cmpl", 31, 32, 0, 0>;
def CMPLW : XForm_16_ext<"cmplw", 31, 32, 0, 0>;
def CMPLD : XForm_16_ext<"cmpld", 31, 32, 1, 0>;
def CRAND : XLForm_1<"crand", 19, 257, 0, 0>;
def CRANDC : XLForm_1<"crandc", 19, 129, 0, 0>;
def CRNOR : XLForm_1<"crnor", 19, 33, 0, 0>;
def CROR : XLForm_1<"cror", 19, 449, 0, 0>;
def DIVW : XOForm_1<"divw", 31, 491, 0, 0, 0, 0>;
def DIVWU : XOForm_1<"divwu", 31, 459, 0, 0, 0, 0>;
def EXTSB : XForm_11<"extsb", 31, 954, 0, 0, 0>;
def EXTSH : XForm_11<"extsh", 31, 922, 0, 0, 0>;
def FADD : AForm_2<"fadd", 63, 21, 0, 0, 0>;
def FADDS : AForm_2<"fadds", 59, 21, 0, 0, 0>;
def FSUB : AForm_2<"fsub", 63, 20, 0, 0, 0>;
def FSUBS : AForm_2<"fsubs", 59, 20, 0, 0, 0>;
def FMUL : AForm_3<"fmul", 63, 25, 0, 0, 0>;
def FMULS : AForm_3<"fmuls", 59, 25, 0, 0, 0>;
def FDIV : AForm_2<"fdiv", 63, 18, 0, 0, 0>;
def FDIVS : AForm_2<"fdivs", 59, 18, 0, 0, 0>;
def FMR : XForm_26<"fmr", 63, 72, 0, 0, 0>;
def FNEG : XForm_26<"fneg", 63, 80, 0, 0, 0>;
def FRSP : XForm_26<"frsp", 63, 12, 0, 0, 0>;
def FSEL : AForm_1<"fsel", 63, 23, 0, 0, 0>;
def FCTIW : XForm_26<"fctiw", 63, 14, 0, 0, 0>;
def FCTIWZ : XForm_26<"fctiwz", 63, 15, 0, 0, 0>;
def FCMPU : XForm_17<"fcmpu", 63, 0, 0, 0>;
def LBZ : DForm_1<"lbz", 35, 0, 0>;
def LBZX : XForm_1<"lbzx", 31, 87, 0, 0>;
def LHZ : DForm_1<"lhz", 40, 0, 0>;
def LHZX : XForm_1<"lhzx", 31, 279, 0, 0>;
def LHA : DForm_1<"lha", 42, 0, 0>;
def LHAX : XForm_1<"lhax", 31, 343, 0, 0>;
def LWZ : DForm_1<"lwz", 32, 0, 0>;
def LWZX : XForm_1<"lwzx", 31, 23, 0, 0>;
def LWA : DSForm_1<"lwa", 58, 2, 1, 0>;
def LWAX : XForm_1<"lwax", 31, 341, 1, 0>;
def LD : DSForm_2<"ld", 58, 0, 1, 0>;
def LDX : XForm_1<"ldx", 31, 21, 1, 0>;
def LMW : DForm_1<"lmw", 46, 0, 0>;
def STMW : DForm_3<"stmw", 47, 0, 0>;
def LFS : DForm_8<"lfs", 48, 0, 0>;
def LFSX : XForm_25<"lfsx", 31, 535, 0, 0>;
def LFD : DForm_8<"lfd", 50, 0, 0>;
def LFDX : XForm_25<"lfdx", 31, 599, 0, 0>;
def MFCR : XForm_5<"mfcr", 31, 19, 0, 0>;
def MFLR : XFXForm_1_ext<"", 31, 399, 8, 0, 0>,
                      II<(ops GPRC:$reg), "mflr $reg">;
def MFCTR : XFXForm_1_ext<"mfctr", 31, 399, 9, 0, 0>;
def MTLR : XFXForm_7_ext<"mtlr", 31, 467, 8, 0, 0>;
def MTCTR : XFXForm_7_ext<"mtctr", 31, 467, 9, 0, 0>;
def MULLD : XOForm_1<"mulld", 31, 233, 0, 0, 1, 0>;
def MULLW : XOForm_1<"mullw", 31, 235, 0, 0, 0, 0>;
def MULHWU : XOForm_2<"mulhwu", 31, 11, 0, 0, 0>;
def NAND  : XForm_6<"nand",  31, 476, 0, 0, 0>;
def NEG : XOForm_3<"neg", 31, 104, 0, 0, 0, 0>;
def NOR  : XForm_6<"nor",  31, 124, 0, 0, 0>;
def NOP : DForm_4_zero<"nop", 24, 0, 0, (ops), "nop">;
def ORI  : DForm_4<24, 0, 0,
                   (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                   "ori $dst, $src1, $src2">;
def ORIS : DForm_4<25, 0, 0,
                   (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                   "oris $dst, $src1, $src2">;
def OR  : XForm_6<"or",  31, 444, 0, 0, 0>;
def ORo : XForm_6<"or.", 31, 444, 1, 0, 0>;
def RLDICL : MDForm_1<"rldicl", 30, 0, 0, 1, 0>;
def RLDICR : MDForm_1<"rldicr", 30, 1, 0, 1, 0>;
def RLWINM : MForm_2<"rlwinm", 21, 0, 0, 0>;
def RLWNM : MForm_1<"rlwnm", 23, 0, 0, 0>;
def RLWIMI : MForm_2<"rlwimi", 20, 0, 0, 0>;
def SLD  : XForm_6<"sld",  31, 27, 0, 1, 0>;
def SLW  : XForm_6<"slw",  31, 24, 0, 0, 0>;
def SRD  : XForm_6<"srd",  31, 539, 0, 1, 0>;
def SRW  : XForm_6<"srw",  31, 536, 0, 0, 0>;
def SRADI  : XSForm_1<"sradi",  31, 413, 0, 1, 0>;
def SRAWI  : XForm_10<"srawi",  31, 824, 0, 0, 0>;
def SRAD  : XForm_6<"srad",  31, 794, 0, 1, 0>;
def SRAW  : XForm_6<"sraw",  31, 792, 0, 0, 0>;
def STB : DForm_3<"stb", 38, 0, 0>;
def STBU : DForm_3<"stbu", 39, 0, 0>;
def STBX : XForm_8<"stbx", 31, 215, 0, 0>;
def STH : DForm_3<"sth", 44, 0, 0>;
def STHU : DForm_3<"sthu", 45, 0, 0>;
def STHX : XForm_8<"sthx", 31, 407, 0, 0>;
def STW : DForm_3<"stw", 36, 0, 0>;
def STWU : DForm_3<"stwu", 37, 0, 0>;
def STWX : XForm_8<"stwx", 31, 151, 0, 0>;
def STWUX : XForm_8<"stwux", 31, 183, 0, 0>;
def STD : DSForm_2<"std", 62, 0, 1, 0>;
def STDU : DSForm_2<"stdu", 62, 1, 1, 0>;
def STDX : XForm_8<"stdx", 31, 149, 1, 0>;
def STDUX : XForm_8<"stdux", 31, 181, 1, 0>;
def STFS : DForm_9<"stfs", 52, 0, 0>;
def STFSX : XForm_28<"stfsx", 31, 663, 0, 0>;
def STFD : DForm_9<"stfd", 54, 0, 0>;
def STFDX : XForm_28<"stfdx", 31, 727, 0, 0>;
def SUBFIC : DForm_2<"subfic", 8, 0, 0>;
def SUB : XOForm_1_rev<"sub", 31, 40, 0, 0, 0, 0>;
def SUBF : XOForm_1<"subf", 31, 40, 0, 0, 0, 0>;
def SUBC : XOForm_1_rev<"subc", 31, 8, 0, 0, 0, 0>;
def SUBFC : XOForm_1<"subfc", 31, 8, 0, 0, 0, 0>;
def SUBFE : XOForm_1<"subfe", 31, 136, 0, 0, 0, 0>;
def SUBFZE : XOForm_3<"subfze", 31, 200, 0, 0, 0, 0>;
def XORI  : DForm_4<26, 0, 0,
                   (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                   "xori $dst, $src1, $src2">;
def XORIS : DForm_4<27, 0, 0,
                   (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                   "xoris $dst, $src1, $src2">;
def XOR  : XForm_6<"xor",  31, 316, 0, 0, 0>;
def MULLI : DForm_2<"mulli", 7, 0, 0>;