clo/clz aren't supported on mips I. Keep them around for when we'll
[oota-llvm.git] / lib / Target / Mips / MipsInstrInfo.td
1 //===- 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
14 include "MipsInstrFormats.td"
15
16 //===----------------------------------------------------------------------===//
17 // Mips profiles and nodes
18 //===----------------------------------------------------------------------===//
19
20 // Call
21 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
22 def 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, ... on static model
28 // This two nodes have nothing to do with Mips Registers Hi and Lo.
29 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>;
30 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
31
32 // Necessary to generate glued instructions when loading GlobalAddress
33 // into registers.
34 def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative,
35                      SDNPAssociative, SDNPOptInFlag]>;
36
37 // Used to Load Addresses on PIC code.
38 def MipsLoadAddr: SDNode<"MipsISD::LoadAddr", SDTIntUnaryOp>;
39
40 // Return
41 def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
42 def MipsRet     : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain,
43                              SDNPOptInFlag]>;
44
45 // These are target-independent nodes, but have target-specific formats.
46 def SDT_MipsCallSeq : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
47 def callseq_start   : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeq,
48                              [SDNPHasChain, SDNPOutFlag]>;
49 def callseq_end     : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq,
50                              [SDNPHasChain, SDNPOutFlag]>;
51
52 //===----------------------------------------------------------------------===//
53 // Mips Instruction Predicate Definitions.
54 //===----------------------------------------------------------------------===//
55 def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
56
57 //===----------------------------------------------------------------------===//
58 // Mips Operand, Complex Patterns and Transformations Definitions.
59 //===----------------------------------------------------------------------===//
60
61 // Instruction operand types
62 def brtarget    : Operand<OtherVT>;
63 def calltarget  : Operand<i32>;
64 def uimm16      : Operand<i32>;
65 def simm16      : Operand<i32>;
66 def shamt       : Operand<i32>;
67 def addrlabel   : Operand<i32>;
68
69 // Address operand
70 def mem : Operand<i32> {
71   let PrintMethod = "printMemOperand";
72   let MIOperandInfo = (ops simm16, CPURegs);
73 }
74
75 // Transformation Function - get the lower 16 bits.
76 def LO16 : SDNodeXForm<imm, [{
77   return getI32Imm((unsigned)N->getValue() & 0xFFFF);
78 }]>;
79
80 // Transformation Function - get the higher 16 bits.
81 def HI16 : SDNodeXForm<imm, [{
82   return getI32Imm((unsigned)N->getValue() >> 16);
83 }]>;
84
85 // Node immediate fits as 16-bit sign extended on target immediate.
86 // e.g. addi, andi
87 def immSExt16  : PatLeaf<(imm), [{
88   if (N->getValueType(0) == MVT::i32)
89     return (int32_t)N->getValue() == (short)N->getValue();
90   else
91     return (int64_t)N->getValue() == (short)N->getValue();
92 }]>;
93
94 // Node immediate fits as 16-bit zero extended on target immediate.
95 // The LO16 param means that only the lower 16 bits of the node
96 // immediate are caught.
97 // e.g. addiu, sltiu
98 def immZExt16  : PatLeaf<(imm), [{
99   if (N->getValueType(0) == MVT::i32)
100     return (uint32_t)N->getValue() == (unsigned short)N->getValue();
101   else
102     return (uint64_t)N->getValue() == (unsigned short)N->getValue();
103 }], LO16>;
104
105 // Node immediate fits as 32-bit zero extended on target immediate.
106 //def immZExt32  : PatLeaf<(imm), [{
107 //  return (uint64_t)N->getValue() == (uint32_t)N->getValue();
108 //}], LO16>;
109
110 // shamt field must fit in 5 bits.
111 def immZExt5 : PatLeaf<(imm), [{
112   return N->getValue() == ((N->getValue()) & 0x1f) ;
113 }]>;
114
115 // Mips Address Mode! SDNode frameindex could possibily be a match
116 // since load and store instructions from stack used it.
117 def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>;
118
119 //===----------------------------------------------------------------------===//
120 // Instructions specific format
121 //===----------------------------------------------------------------------===//
122
123 // Arithmetic 3 register operands
124 let isCommutable = 1 in
125 class ArithR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode,
126              InstrItinClass itin>:
127   FR< op,
128       func,
129       (outs CPURegs:$dst),
130       (ins CPURegs:$b, CPURegs:$c),
131       !strconcat(instr_asm, " $dst, $b, $c"),
132       [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
133
134 let isCommutable = 1 in
135 class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm>:
136   FR< op,
137       func,
138       (outs CPURegs:$dst),
139       (ins CPURegs:$b, CPURegs:$c),
140       !strconcat(instr_asm, " $dst, $b, $c"),
141       [], IIAlu>;
142
143 // Arithmetic 2 register operands
144 let isCommutable = 1 in
145 class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
146              Operand Od, PatLeaf imm_type> :
147   FI< op,
148       (outs CPURegs:$dst),
149       (ins CPURegs:$b, Od:$c),
150       !strconcat(instr_asm, " $dst, $b, $c"),
151       [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>;
152
153 // Arithmetic Multiply ADD/SUB
154 let rd=0 in
155 class MArithR<bits<6> func, string instr_asm> :
156   FR< 0x1c,
157       func,
158       (outs CPURegs:$rs),
159       (ins CPURegs:$rt),
160       !strconcat(instr_asm, " $rs, $rt"),
161       [], IIImul>;
162
163 //  Logical
164 class LogicR<bits<6> func, string instr_asm, SDNode OpNode>:
165   FR< 0x00,
166       func,
167       (outs CPURegs:$dst),
168       (ins CPURegs:$b, CPURegs:$c),
169       !strconcat(instr_asm, " $dst, $b, $c"),
170       [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
171
172 class LogicI<bits<6> op, string instr_asm, SDNode OpNode>:
173   FI< op,
174       (outs CPURegs:$dst),
175       (ins CPURegs:$b, uimm16:$c),
176       !strconcat(instr_asm, " $dst, $b, $c"),
177       [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))], IIAlu>;
178
179 class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
180   FR< op,
181       func,
182       (outs CPURegs:$dst),
183       (ins CPURegs:$b, CPURegs:$c),
184       !strconcat(instr_asm, " $dst, $b, $c"),
185       [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))], IIAlu>;
186
187 // Shifts
188 let rt = 0 in
189 class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>:
190   FR< 0x00,
191       func,
192       (outs CPURegs:$dst),
193       (ins CPURegs:$b, shamt:$c),
194       !strconcat(instr_asm, " $dst, $b, $c"),
195       [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu>;
196
197 class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
198   FR< 0x00,
199       func,
200       (outs CPURegs:$dst),
201       (ins CPURegs:$b, CPURegs:$c),
202       !strconcat(instr_asm, " $dst, $b, $c"),
203       [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
204
205 // Load Upper Imediate
206 class LoadUpper<bits<6> op, string instr_asm>:
207   FI< op,
208       (outs CPURegs:$dst),
209       (ins uimm16:$imm),
210       !strconcat(instr_asm, " $dst, $imm"),
211       [], IIAlu>;
212
213 // Memory Load/Store
214 let isLoad = 1, hasDelaySlot = 1 in
215 class LoadM<bits<6> op, string instr_asm, PatFrag OpNode>:
216   FI< op,
217       (outs CPURegs:$dst),
218       (ins mem:$addr),
219       !strconcat(instr_asm, " $dst, $addr"),
220       [(set CPURegs:$dst, (OpNode addr:$addr))], IILoad>;
221
222 let isStore = 1 in
223 class StoreM<bits<6> op, string instr_asm, PatFrag OpNode>:
224   FI< op,
225       (outs),
226       (ins CPURegs:$dst, mem:$addr),
227       !strconcat(instr_asm, " $dst, $addr"),
228       [(OpNode CPURegs:$dst, addr:$addr)], IIStore>;
229
230 // Conditional Branch
231 let isBranch = 1, isTerminator=1, hasDelaySlot = 1 in {
232 class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>:
233   FI< op,
234       (outs),
235       (ins CPURegs:$a, CPURegs:$b, brtarget:$offset),
236       !strconcat(instr_asm, " $a, $b, $offset"),
237       [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)],
238       IIBranch>;
239
240
241 class CBranchZero<bits<6> op, string instr_asm, PatFrag cond_op>:
242   FI< op,
243       (outs),
244       (ins CPURegs:$src, brtarget:$offset),
245       !strconcat(instr_asm, " $src, $offset"),
246       [(brcond (cond_op CPURegs:$src, 0), bb:$offset)],
247       IIBranch>;
248 }
249
250 // SetCC
251 class SetCC_R<bits<6> op, bits<6> func, string instr_asm,
252       PatFrag cond_op>:
253   FR< op,
254       func,
255       (outs CPURegs:$dst),
256       (ins CPURegs:$b, CPURegs:$c),
257       !strconcat(instr_asm, " $dst, $b, $c"),
258       [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))],
259       IIAlu>;
260
261 class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op,
262       Operand Od, PatLeaf imm_type>:
263   FI< op,
264       (outs CPURegs:$dst),
265       (ins CPURegs:$b, Od:$c),
266       !strconcat(instr_asm, " $dst, $b, $c"),
267       [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))],
268       IIAlu>;
269
270 // Unconditional branch
271 let isBranch=1, isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
272 class JumpFJ<bits<6> op, string instr_asm>:
273   FJ< op,
274       (outs),
275       (ins brtarget:$target),
276       !strconcat(instr_asm, " $target"),
277       [(br bb:$target)], IIBranch>;
278
279 let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in
280 class JumpFR<bits<6> op, bits<6> func, string instr_asm>:
281   FR< op,
282       func,
283       (outs),
284       (ins CPURegs:$target),
285       !strconcat(instr_asm, " $target"),
286       [], IIBranch>;
287
288 // Jump and Link (Call)
289 let isCall=1, hasDelaySlot=1,
290   // All calls clobber the non-callee saved registers...
291   Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2,
292           T3, T4, T5, T6, T7, T8, T9, K0, K1] in {
293   class JumpLink<bits<6> op, string instr_asm>:
294     FJ< op,
295         (outs),
296         (ins calltarget:$target),
297         !strconcat(instr_asm, " $target"),
298         [(MipsJmpLink imm:$target)], IIBranch>;
299
300   let rd=31 in
301   class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm>:
302     FR< op,
303         func,
304         (outs),
305         (ins CPURegs:$rs),
306         !strconcat(instr_asm, " $rs"),
307         [(MipsJmpLink CPURegs:$rs)], IIBranch>;
308
309   class BranchLink<string instr_asm>:
310     FI< 0x1,
311         (outs),
312         (ins CPURegs:$rs, brtarget:$target),
313         !strconcat(instr_asm, " $rs, $target"),
314         [], IIBranch>;
315 }
316
317 // Mul, Div
318 class MulDiv<bits<6> func, string instr_asm, InstrItinClass itin>:
319   FR< 0x00,
320       func,
321       (outs),
322       (ins CPURegs:$a, CPURegs:$b),
323       !strconcat(instr_asm, " $a, $b"),
324       [], itin>;
325
326 // Move from Hi/Lo
327 class MoveFromTo<bits<6> func, string instr_asm>:
328   FR< 0x00,
329       func,
330       (outs CPURegs:$dst),
331       (ins),
332       !strconcat(instr_asm, " $dst"),
333       [], IIHiLo>;
334
335 // Count Leading Ones/Zeros in Word
336 class CountLeading<bits<6> func, string instr_asm>:
337   FR< 0x1c,
338       func,
339       (outs CPURegs:$dst),
340       (ins CPURegs:$src),
341       !strconcat(instr_asm, " $dst, $src"),
342       [], IIAlu>;
343
344 class EffectiveAddress<string instr_asm> :
345   FI<0x09,
346      (outs CPURegs:$dst),
347      (ins mem:$addr),
348      instr_asm,
349      [(set CPURegs:$dst, addr:$addr)], IIAlu>;
350
351 //===----------------------------------------------------------------------===//
352 // Pseudo instructions
353 //===----------------------------------------------------------------------===//
354
355 // As stack alignment is always done with addiu, we need a 16-bit immediate
356 let Defs = [SP], Uses = [SP] in {
357 def ADJCALLSTACKDOWN : PseudoInstMips<(outs), (ins uimm16:$amt),
358                                       "!ADJCALLSTACKDOWN $amt",
359                                       [(callseq_start imm:$amt)]>;
360 def ADJCALLSTACKUP   : PseudoInstMips<(outs), (ins uimm16:$amt),
361                                       "!ADJCALLSTACKUP $amt",
362                                       [(callseq_end imm:$amt)]>;
363 }
364
365 def IMPLICIT_DEF_CPURegs : PseudoInstMips<(outs CPURegs:$dst), (ins),
366                                           "!IMPLICIT_DEF $dst",
367                                           [(set CPURegs:$dst, (undef))]>;
368
369 // When handling PIC code the assembler needs .cpload and .cprestore
370 // directives. If the real instructions corresponding these directives
371 // are used, we have the same behavior, but get also a bunch of warnings
372 // from the assembler.
373 def CPLOAD: PseudoInstMips<(outs), (ins CPURegs:$reg),
374                           ".set noreorder\n\t.cpload $reg\n\t.set reorder", []>;
375 def CPRESTORE: PseudoInstMips<(outs), (ins uimm16:$loc),
376                               ".cprestore $loc", []>;
377
378 // Used on PIC code only, it loads the address of label into register reg. The
379 // address is calculated from the global pointer ($gp) and is expanded by the
380 // assembler into two instructions "lw" and "addiu".
381 def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label),
382                        "la $dst, $label", []>;
383
384 //===----------------------------------------------------------------------===//
385 // Instruction definition
386 //===----------------------------------------------------------------------===//
387
388 //===----------------------------------------------------------------------===//
389 // MipsI Instructions
390 //===----------------------------------------------------------------------===//
391
392 // Arithmetic
393
394 // ADDiu just accept 16-bit immediates but we handle this on Pat's.
395 // immZExt32 is used here so it can match GlobalAddress immediates.
396 def ADDiu   : ArithI<0x09, "addiu", MipsAdd, uimm16, immZExt16>;
397 def ADDi    : ArithI<0x08, "addi",  add, simm16, immSExt16>;
398 def MUL     : ArithR<0x1c, 0x02, "mul", mul, IIImul>;
399 def ADDu    : ArithR<0x00, 0x21, "addu", add, IIAlu>;
400 def SUBu    : ArithR<0x00, 0x23, "subu", sub, IIAlu>;
401 def ADD     : ArithOverflowR<0x00, 0x20, "add">;
402 def SUB     : ArithOverflowR<0x00, 0x22, "sub">;
403 def MADD    : MArithR<0x00, "madd">;
404 def MADDU   : MArithR<0x01, "maddu">;
405 def MSUB    : MArithR<0x04, "msub">;
406 def MSUBU   : MArithR<0x05, "msubu">;
407
408 // Logical
409 def AND     : LogicR<0x24, "and", and>;
410 def OR      : LogicR<0x25, "or",  or>;
411 def XOR     : LogicR<0x26, "xor", xor>;
412 def ANDi    : LogicI<0x0c, "andi", and>;
413 def ORi     : LogicI<0x0d, "ori",  or>;
414 def XORi    : LogicI<0x0e, "xori",  xor>;
415 def NOR     : LogicNOR<0x00, 0x27, "nor">;
416
417 // Shifts
418 def SLL     : LogicR_shift_imm<0x00, "sll", shl>;
419 def SRL     : LogicR_shift_imm<0x02, "srl", srl>;
420 def SRA     : LogicR_shift_imm<0x03, "sra", sra>;
421 def SLLV    : LogicR_shift_reg<0x04, "sllv", shl>;
422 def SRLV    : LogicR_shift_reg<0x06, "srlv", srl>;
423 def SRAV    : LogicR_shift_reg<0x07, "srav", sra>;
424
425 // Load Upper Immediate
426 def LUi     : LoadUpper<0x0f, "lui">;
427
428 // Load/Store
429 def LB      : LoadM<0x20, "lb",  sextloadi8>;
430 def LBu     : LoadM<0x24, "lbu", zextloadi8>;
431 def LH      : LoadM<0x21, "lh",  sextloadi16>;
432 def LHu     : LoadM<0x25, "lhu", zextloadi16>;
433 def LW      : LoadM<0x23, "lw",  load>;
434 def SB      : StoreM<0x28, "sb", truncstorei8>;
435 def SH      : StoreM<0x29, "sh", truncstorei16>;
436 def SW      : StoreM<0x2b, "sw", store>;
437
438 // Conditional Branch
439 def BEQ     : CBranch<0x04, "beq", seteq>;
440 def BNE     : CBranch<0x05, "bne", setne>;
441
442 let rt=1 in
443 def BGEZ    : CBranchZero<0x01, "bgez", setge>;
444
445 let rt=0 in {
446 def BGTZ    : CBranchZero<0x07, "bgtz", setgt>;
447 def BLEZ    : CBranchZero<0x07, "blez", setle>;
448 def BLTZ    : CBranchZero<0x01, "bltz", setlt>;
449 }
450
451 // Set Condition Code
452 def SLT     : SetCC_R<0x00, 0x2a, "slt", setlt>;
453 def SLTu    : SetCC_R<0x00, 0x2b, "sltu", setult>;
454 def SLTi    : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>;
455 def SLTiu   : SetCC_I<0x0b, "sltiu", setult, uimm16, immZExt16>;
456
457 // Unconditional jump
458 def J       : JumpFJ<0x02, "j">;
459 def JR      : JumpFR<0x00, 0x08, "jr">;
460
461 // Jump and Link (Call)
462 def JAL     : JumpLink<0x03, "jal">;
463 def JALR    : JumpLinkReg<0x00, 0x09, "jalr">;
464 def BGEZAL  : BranchLink<"bgezal">;
465 def BLTZAL  : BranchLink<"bltzal">;
466
467 // MulDiv and Move From Hi/Lo operations, have
468 // their correpondent SDNodes created on ISelDAG.
469 // Special Mul, Div operations
470 def MULT    : MulDiv<0x18, "mult", IIImul>;
471 def MULTu   : MulDiv<0x19, "multu", IIImul>;
472 def DIV     : MulDiv<0x1a, "div", IIIdiv>;
473 def DIVu    : MulDiv<0x1b, "divu", IIIdiv>;
474
475 // Move From Hi/Lo
476 def MFHI    : MoveFromTo<0x10, "mfhi">;
477 def MFLO    : MoveFromTo<0x12, "mflo">;
478 def MTHI    : MoveFromTo<0x11, "mthi">;
479 def MTLO    : MoveFromTo<0x13, "mtlo">;
480
481 // Count Leading
482 // CLO/CLZ are part of the newer MIPS32(tm) instruction
483 // set and not older Mips I keep this for future use
484 // though.
485 //def CLO     : CountLeading<0x21, "clo">;
486 //def CLZ     : CountLeading<0x20, "clz">;
487
488 // No operation
489 let addr=0 in
490 def NOP     : FJ<0, (outs), (ins), "nop", [], IIAlu>;
491
492 // Ret instruction - as mips does not have "ret" a
493 // jr $ra must be generated.
494 let isReturn=1, isTerminator=1, hasDelaySlot=1,
495     isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
496 {
497   def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
498                 "jr $target", [(MipsRet CPURegs:$target)], IIBranch>;
499 }
500
501 // FrameIndexes are legalized when they are operands from load/store
502 // instructions. The same not happens for stack address copies, so an
503 // add op with mem ComplexPattern is used and the stack address copy
504 // can be matched. It's similar to Sparc LEA_ADDRi
505 def LEA_ADDiu : EffectiveAddress<"addiu $dst, ${addr:stackloc}">;
506
507 //===----------------------------------------------------------------------===//
508 //  Arbitrary patterns that map to one or more instructions
509 //===----------------------------------------------------------------------===//
510
511 // Small immediates
512 def : Pat<(i32 immSExt16:$in),
513           (ADDiu ZERO, imm:$in)>;
514 def : Pat<(i32 immZExt16:$in),
515           (ORi ZERO, imm:$in)>;
516
517 // Arbitrary immediates
518 def : Pat<(i32 imm:$imm),
519           (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
520
521 // Call
522 def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
523           (JAL tglobaladdr:$dst)>;
524 def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
525           (JAL texternalsym:$dst)>;
526 def : Pat<(MipsJmpLink CPURegs:$dst),
527           (JALR CPURegs:$dst)>;
528
529 // GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
530 def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
531 def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
532 def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
533           (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
534 def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>;
535
536 // Mips does not have not, so we increase the operation
537 def : Pat<(not CPURegs:$in),
538           (NOR CPURegs:$in, ZERO)>;
539
540 // extended load and stores
541 def : Pat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>;
542 def : Pat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>;
543 def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
544 def : Pat<(truncstorei1 CPURegs:$src, addr:$addr),
545            (SB CPURegs:$src, addr:$addr)>;
546
547 ///
548 /// brcond patterns
549 ///
550
551 // direct match equal/notequal zero branches
552 def : Pat<(brcond (setne CPURegs:$lhs, 0), bb:$dst),
553           (BNE CPURegs:$lhs, ZERO, bb:$dst)>;
554 def : Pat<(brcond (seteq CPURegs:$lhs, 0), bb:$dst),
555           (BEQ CPURegs:$lhs, ZERO, bb:$dst)>;
556
557 def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
558           (BGEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
559 def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
560           (BGEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
561
562 def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
563           (BGTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
564 def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
565           (BGTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
566
567 def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
568           (BLEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
569 def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
570           (BLEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
571
572 def : Pat<(brcond (setlt CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
573           (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
574 def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
575           (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
576 def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
577           (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
578 def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
579           (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
580
581 def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
582           (BLTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
583 def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
584           (BLTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
585
586 // generic brcond pattern
587 def : Pat<(brcond CPURegs:$cond, bb:$dst),
588           (BNE CPURegs:$cond, ZERO, bb:$dst)>;
589
590 ///
591 /// setcc patterns, only matched when there
592 /// is no brcond following a setcc operation
593 ///
594
595 // setcc 2 register operands
596 def : Pat<(setle CPURegs:$lhs, CPURegs:$rhs),
597           (XORi (SLT CPURegs:$rhs, CPURegs:$lhs), 1)>;
598 def : Pat<(setule CPURegs:$lhs, CPURegs:$rhs),
599           (XORi (SLTu CPURegs:$rhs, CPURegs:$lhs), 1)>;
600
601 def : Pat<(setgt CPURegs:$lhs, CPURegs:$rhs),
602           (SLT CPURegs:$rhs, CPURegs:$lhs)>;
603 def : Pat<(setugt CPURegs:$lhs, CPURegs:$rhs),
604           (SLTu CPURegs:$rhs, CPURegs:$lhs)>;
605
606 def : Pat<(setge CPURegs:$lhs, CPURegs:$rhs),
607           (XORi (SLT CPURegs:$lhs, CPURegs:$rhs), 1)>;
608 def : Pat<(setuge CPURegs:$lhs, CPURegs:$rhs),
609           (XORi (SLTu CPURegs:$lhs, CPURegs:$rhs), 1)>;
610
611 def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs),
612           (OR (SLT CPURegs:$lhs, CPURegs:$rhs),
613               (SLT CPURegs:$rhs, CPURegs:$lhs))>;
614
615 def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
616           (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs),
617                     (SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>;
618
619 // setcc reg/imm operands
620 def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs),
621           (XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>;
622 def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs),
623           (XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>;