blob: 0a7e3ce29cf51766ce2cc09612784868f28ffc10 [file] [log] [blame]
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +00001//===- MipsInstrInfo.td - Mips Register defs --------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Bruno Cardoso Lopes and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10//===----------------------------------------------------------------------===//
11// Instruction format superclass
12//===----------------------------------------------------------------------===//
13
14include "MipsInstrFormats.td"
15
16//===----------------------------------------------------------------------===//
17// Mips profiles and nodes
18//===----------------------------------------------------------------------===//
19
20// Call
21def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
22def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
23 SDNPOutFlag]>;
24
25// Hi and Lo nodes are created to let easy manipulation of 16-bit when
26// handling 32-bit immediates. They are used on MipsISelLowering to
27// lower stuff like GlobalAddress, ExternalSymbol, ...
28// This two nodes have nothing to do with Mips Registers Hi and Lo.
29def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
30def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
31
32// Return
33def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
34def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain,
35 SDNPOptInFlag]>;
36
37// These are target-independent nodes, but have target-specific formats.
38def SDT_MipsCallSeq : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
39def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeq,
40 [SDNPHasChain, SDNPOutFlag]>;
41def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq,
42 [SDNPHasChain, SDNPOutFlag]>;
43
44// Instruction operand types
45def brtarget : Operand<OtherVT>;
46def calltarget : Operand<i32>;
47def uimm16 : Operand<i32>;
48def simm16 : Operand<i32>;
49def shamt : Operand<i32>;
50
51// Address operand
52def mem : Operand<i32> {
53 let PrintMethod = "printMemOperand";
54 let MIOperandInfo = (ops simm16, CPURegs);
55}
56
57//===----------------------------------------------------------------------===//
58// Mips Patterns and Transformations
59//===----------------------------------------------------------------------===//
60
61// Transformation Function - get the lower 16 bits.
62def LO16 : SDNodeXForm<imm, [{
63 return getI32Imm((unsigned)N->getValue() & 0xFFFF);
64}]>;
65
66// Transformation Function - get the higher 16 bits.
67def HI16 : SDNodeXForm<imm, [{
68 return getI32Imm((unsigned)N->getValue() >> 16);
69}]>;
70
71// Node immediate fits as 16-bit sign extended on target immediate.
72// e.g. addi, andi
73def immSExt16 : PatLeaf<(imm), [{
74 if (N->getValueType(0) == MVT::i32)
75 return (int32_t)N->getValue() == (short)N->getValue();
76 else
77 return (int64_t)N->getValue() == (short)N->getValue();
78}]>;
79
80// Node immediate fits as 16-bit zero extended on target immediate.
81// The LO16 param means that only the lower 16 bits of the node
82// immediate are caught.
83// e.g. addiu, sltiu
84def immZExt16 : PatLeaf<(imm), [{
85 return (uint64_t)N->getValue() == (unsigned short)N->getValue();
86}], LO16>;
87
88// Node immediate must have only it's 16 high bits set.
89// The HI16 param means that only the higher 16 bits of the node
90// immediate are caught.
91// e.g. lui
92def imm16ShiftedZExt : PatLeaf<(imm), [{
93 return (N->getValue() & ~uint64_t(0xFFFF0000)) == 0;
94}], HI16>;
95
96// shamt field must fit in 5 bits.
97def immZExt5 : PatLeaf<(imm), [{
98 return N->getValue() == ((N->getValue()) & 0x1f) ;
99}]>;
100
101// Mips Address Mode! SDNode frameindex could possibily be a match
102// since load and store instructions from stack used it.
103def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>;
104
105//===----------------------------------------------------------------------===//
106// Instructions specific format
107//===----------------------------------------------------------------------===//
108
109// Arithmetic 3 register operands
110let isCommutable = 1 in
111class ArithR< bits<6> op, bits<6> func, string instr_asm, SDNode OpNode>:
112 FR< op,
113 func,
114 (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
115 !strconcat(instr_asm, " $dst, $b, $c"),
116 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
117
118let isCommutable = 1 in
119class ArithOverflowR< bits<6> op, bits<6> func, string instr_asm>:
120 FR< op,
121 func,
122 (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
123 !strconcat(instr_asm, " $dst, $b, $c"),
124 []>;
125
126// Arithmetic 2 register operands
127let isCommutable = 1 in
128class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
129 Operand Od, PatLeaf imm_type> :
130 FI< op,
131 (ops CPURegs:$dst, CPURegs:$b, Od:$c),
132 !strconcat(instr_asm, " $dst, $b, $c"),
133 [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))] >;
134
135// Arithmetic Multiply ADD/SUB
136let rd=0 in
137class MArithR<bits<6> func, string instr_asm> :
138 FR< 0x1c,
139 func,
140 (ops CPURegs:$rs, CPURegs:$rt),
141 !strconcat(instr_asm, " $rs, $rt"),
142 []>;
143
144// Logical
145class LogicR<bits<6> func, string instr_asm, SDNode OpNode>:
146 FR< 0x00,
147 func,
148 (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
149 !strconcat(instr_asm, " $dst, $b, $c"),
150 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
151
152class LogicI<bits<6> op, string instr_asm, SDNode OpNode>:
153 FI< op,
154 (ops CPURegs:$dst, CPURegs:$b, uimm16:$c),
155 !strconcat(instr_asm, " $dst, $b, $c"),
156 [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))]>;
157
158class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
159 FR< op,
160 func,
161 (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
162 !strconcat(instr_asm, " $dst, $b, $c"),
163 [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))] >;
164
165// Shifts
166let rt = 0 in
167class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>:
168 FR< 0x00,
169 func,
170 (ops CPURegs:$dst, CPURegs:$b, shamt:$c),
171 !strconcat(instr_asm, " $dst, $b, $c"),
172 [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))] >;
173
174class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
175 FR< 0x00,
176 func,
177 (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
178 !strconcat(instr_asm, " $dst, $b, $c"),
179 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
180
181// Load Upper Imediate
182class LoadUpper<bits<6> op, string instr_asm>:
183 FI< op,
184 (ops CPURegs:$dst, uimm16:$imm),
185 !strconcat(instr_asm, " $dst, $imm"),
186 [(set CPURegs:$dst, imm16ShiftedZExt:$imm)]>;
187
188// Memory Load/Store
189let isLoad = 1 in
190class LoadM<bits<6> op, string instr_asm, PatFrag OpNode>:
191 FI< op,
192 (ops CPURegs:$dst, mem:$addr),
193 !strconcat(instr_asm, " $dst, $addr"),
194 [(set CPURegs:$dst, (OpNode addr:$addr))]>;
195
196let isStore = 1 in
197class StoreM<bits<6> op, string instr_asm, PatFrag OpNode>:
198 FI< op,
199 (ops CPURegs:$dst, mem:$addr),
200 !strconcat(instr_asm, " $dst, $addr"),
201 [(OpNode CPURegs:$dst, addr:$addr)]>;
202
203// Conditional Branch
204let isBranch = 1, noResults=1, isTerminator=1 in
205class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>:
206 FI< op,
207 (ops CPURegs:$a, CPURegs:$b, brtarget:$offset),
208 !strconcat(instr_asm, " $a, $b, $offset"),
209 [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)]>;
210
211class SetCC_R<bits<6> op, bits<6> func, string instr_asm,
212 PatFrag cond_op>:
213 FR< op,
214 func,
215 (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
216 !strconcat(instr_asm, " $dst, $b, $c"),
217 [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))]>;
218
219class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op,
220 Operand Od, PatLeaf imm_type>:
221 FI< op,
222 (ops CPURegs:$dst, CPURegs:$b, Od:$c),
223 !strconcat(instr_asm, " $dst, $b, $c"),
224 [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))]>;
225
226// Unconditional branch
227let hasCtrlDep=1, noResults=1, isTerminator=1 in
228class JumpFJ<bits<6> op, string instr_asm>:
229 FJ< op,
230 (ops brtarget:$target),
231 !strconcat(instr_asm, " $target"),
232 [(br bb:$target)]>;
233
234let hasCtrlDep=1, noResults=1, isTerminator=1, rd=0 in
235class JumpFR<bits<6> op, bits<6> func, string instr_asm>:
236 FR< op,
237 func,
238 (ops CPURegs:$target),
239 !strconcat(instr_asm, " $target"),
240 []>;
241
242// Jump and Link (Call)
243let isCall=1 in
244class JumpLink<bits<6> op, string instr_asm>:
245 FJ< op,
246 (ops calltarget:$target),
247 !strconcat(instr_asm, " $target"),
248 [(MipsJmpLink imm:$target)]>;
249
250let isCall=1 in
251class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm>:
252 FR< op,
253 func,
254 (ops CPURegs:$rd, CPURegs:$rs),
255 !strconcat(instr_asm, " $rs, $rd"),
256 []>;
257
258// Mul, Div
259class MulDiv<bits<6> func, string instr_asm>:
260 FR< 0x00,
261 func,
262 (ops CPURegs:$a, CPURegs:$b),
263 !strconcat(instr_asm, " $a, $b"),
264 []>;
265
266// Move from Hi/Lo
267class MoveFromTo<bits<6> func, string instr_asm>:
268 FR< 0x00,
269 func,
270 (ops CPURegs:$dst),
271 !strconcat(instr_asm, " $dst"),
272 []>;
273
274// Count Leading Ones/Zeros in Word
275class CountLeading<bits<6> func, string instr_asm>:
276 FR< 0x1c,
277 func,
278 (ops CPURegs:$dst, CPURegs:$src),
279 !strconcat(instr_asm, " $dst, $src"),
280 []>;
281
282
283//===----------------------------------------------------------------------===//
284// Pseudo instructions
285//===----------------------------------------------------------------------===//
286
287class Pseudo<dag ops, string asmstr, list<dag> pattern>:
288 MipsInst<ops, asmstr, pattern>;
289
290// As stack alignment is always done with addiu, we need a 16-bit immediate
291def ADJCALLSTACKDOWN : Pseudo<(ops uimm16:$amt),
292 "!ADJCALLSTACKDOWN $amt",
293 [(callseq_start imm:$amt)]>, Imp<[SP],[SP]>;
294def ADJCALLSTACKUP : Pseudo<(ops uimm16:$amt),
295 "!ADJCALLSTACKUP $amt",
296 [(callseq_end imm:$amt)]>, Imp<[SP],[SP]>;
297
298def IMPLICIT_DEF_CPURegs : Pseudo<(ops CPURegs:$dst),
299 "!IMPLICIT_DEF $dst",
300 [(set CPURegs:$dst, (undef))]>;
301
302//===----------------------------------------------------------------------===//
303// Instruction definition
304//===----------------------------------------------------------------------===//
305
306//===----------------------------------------------------------------------===//
307// Mips32 I
308//===----------------------------------------------------------------------===//
309
310// Arithmetic
311def ADDi : ArithI<0x08, "addi", add, simm16, immZExt16>;
312def ADDiu : ArithI<0x09, "addiu", add, uimm16, immSExt16>;
313def MUL : ArithR<0x1c, 0x02, "mul", mul>;
314def ADDu : ArithR<0x00, 0x21, "addu", add>;
315def SUBu : ArithR<0x00, 0x23, "subu", sub>;
316def ADD : ArithOverflowR<0x00, 0x20, "add">;
317def SUB : ArithOverflowR<0x00, 0x22, "sub">;
318def MADD : MArithR<0x00, "madd">;
319def MADDU : MArithR<0x01, "maddu">;
320def MSUB : MArithR<0x04, "msub">;
321def MSUBU : MArithR<0x05, "msubu">;
322
323// Logical
324def AND : LogicR<0x24, "and", and>;
325def OR : LogicR<0x25, "or", or>;
326def XOR : LogicR<0x26, "xor", xor>;
327def ANDi : LogicI<0x0c, "andi", and>;
328def ORi : LogicI<0x0d, "ori", or>;
329def XORi : LogicI<0x0e, "xori", xor>;
330def NOR : LogicNOR<0x00, 0x27, "nor">;
331
332// Shifts
333def SLL : LogicR_shift_imm<0x00, "sll", shl>;
334def SRL : LogicR_shift_imm<0x02, "srl", srl>;
335def SRA : LogicR_shift_imm<0x03, "sra", sra>;
336def SLLV : LogicR_shift_reg<0x04, "sllv", shl>;
337def SRLV : LogicR_shift_reg<0x06, "srlv", srl>;
338def SRAV : LogicR_shift_reg<0x07, "srav", sra>;
339
340// Load Upper Immediate
341def LUi : LoadUpper<0x0f, "lui">;
342
343// Load/Store
344def LB : LoadM<0x20, "lb", sextloadi8>;
345def LBu : LoadM<0x24, "lbu", zextloadi8>;
346def LH : LoadM<0x21, "lh", sextloadi16>;
347def LHu : LoadM<0x25, "lhu", zextloadi16>;
348def LW : LoadM<0x23, "lw", load>;
349def SB : StoreM<0x28, "sb", truncstorei8>;
350def SH : StoreM<0x29, "sh", truncstorei16>;
351def SW : StoreM<0x2b, "sw", store>;
352
353// Conditional Branch
354def BEQ : CBranch<0x04, "beq", seteq>;
355def BNE : CBranch<0x05, "bne", setne>;
356def SLT : SetCC_R<0x00, 0x2a, "slt", setlt>;
357def SLTu : SetCC_R<0x00, 0x2b, "sltu", setult>;
358def SLTi : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>;
359def SLTiu : SetCC_I<0x0b, "sltiu", setult, uimm16, immZExt16>;
360
361// Unconditional jump
362def J : JumpFJ<0x02, "j">;
363def JR : JumpFR<0x00, 0x08, "jr">;
364
365// Jump and Link (Call)
366def JAL : JumpLink<0x03, "jal">;
367def JALR : JumpLinkReg<0x00, 0x09, "jalr">;
368
369// MulDiv and Move From Hi/Lo operations, have
370// their correpondent SDNodes created on ISelDAG.
371// Special Mul, Div operations
372def MULT : MulDiv<0x18, "mult">;
373def MULTu : MulDiv<0x19, "multu">;
374def DIV : MulDiv<0x1a, "div">;
375def DIVu : MulDiv<0x1b, "divu">;
376
377// Move From Hi/Lo
378def MFHI : MoveFromTo<0x10, "mfhi">;
379def MFLO : MoveFromTo<0x12, "mflo">;
380def MTHI : MoveFromTo<0x11, "mthi">;
381def MTLO : MoveFromTo<0x13, "mtlo">;
382
383// Count Leading
384def CLO : CountLeading<0x21, "clo">;
385def CLZ : CountLeading<0x20, "clz">;
386
387// No operation
388let addr=0 in
389def NOOP : FJ<0, (ops), "nop", []>;
390
391// Ret instruction - as mips does not have "ret" a
392// jr $ra must be generated.
393let isReturn=1, isTerminator=1, hasDelaySlot=1, noResults=1,
394 isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
395{
396 def RET : FR <0x00, 0x02, (ops CPURegs:$target),
397 "jr $target", [(MipsRet CPURegs:$target)]>;
398}
399
400//===----------------------------------------------------------------------===//
401// Arbitrary patterns that map to one or more instructions
402//===----------------------------------------------------------------------===//
403
404// Small immediates
405def : Pat<(i32 immSExt16:$in),
406 (ORi ZERO, imm:$in)>;
407
408// Arbitrary immediates
409def : Pat<(i32 imm:$imm),
410 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
411
412// Call
413def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
414 (JAL tglobaladdr:$dst)>;
415def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
416 (JAL texternalsym:$dst)>;
417
418// GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
419def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
420def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
421
422// When extracting the address from GlobalAddress we
423// need something of the form "addiu $reg, %lo(addr)"
424def : Pat<(add CPURegs:$a, (MipsLo tglobaladdr:$in)),
425 (ADDiu CPURegs:$a, tglobaladdr:$in)>;
426
427// Mips does not have not, so we increase the operation
428def : Pat<(not CPURegs:$in),
429 (NOR CPURegs:$in, CPURegs:$in)>;
430
431// extended load and stores
432def : Pat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
433def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
434def : Pat<(truncstorei1 CPURegs:$src, addr:$addr),
435 (SB CPURegs:$src, addr:$src)>;
436
437// Conditional branch patterns.
438// cond branches patterns, 2 register operands signed.
439def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
440 (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
441def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
442 (BEQ (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
443def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
444 (BNE (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
445def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
446 (BEQ (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
447
448// cond branches patterns, 2 register operands unsigned.
449def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
450 (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
451def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
452 (BEQ (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
453def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
454 (BNE (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
455def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
456 (BEQ (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
457
458// cond branches patterns, reg/imm operands signed.
459def : Pat<(brcond (setult CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
460 (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
461def : Pat<(brcond (setuge CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
462 (BEQ (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
463
464// cond branches patterns, reg/imm operands unsigned.
465def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
466 (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
467def : Pat<(brcond (setuge CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
468 (BEQ (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;