Position Independent Code (PIC) support [1]
[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 def CLO     : CountLeading<0x21, "clo">;
483 def CLZ     : CountLeading<0x20, "clz">;
484
485 // No operation
486 let addr=0 in
487 def NOP     : FJ<0, (outs), (ins), "nop", [], IIAlu>;
488
489 // Ret instruction - as mips does not have "ret" a 
490 // jr $ra must be generated.
491 let isReturn=1, isTerminator=1, hasDelaySlot=1,
492     isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in 
493 {
494   def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
495                 "jr $target", [(MipsRet CPURegs:$target)], IIBranch>;
496 }
497
498 // FrameIndexes are legalized when they are operands from load/store 
499 // instructions. The same not happens for stack address copies, so an
500 // add op with mem ComplexPattern is used and the stack address copy
501 // can be matched. It's similar to Sparc LEA_ADDRi
502 def LEA_ADDiu : EffectiveAddress<"addiu $dst, ${addr:stackloc}">;
503
504 //===----------------------------------------------------------------------===//
505 //  Arbitrary patterns that map to one or more instructions
506 //===----------------------------------------------------------------------===//
507
508 // Small immediates
509 def : Pat<(i32 immSExt16:$in), 
510           (ADDiu ZERO, imm:$in)>;
511 def : Pat<(i32 immZExt16:$in), 
512           (ORi ZERO, imm:$in)>;
513
514 // Arbitrary immediates
515 def : Pat<(i32 imm:$imm),
516           (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
517
518 // Call
519 def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
520           (JAL tglobaladdr:$dst)>;
521 def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
522           (JAL texternalsym:$dst)>;
523 def : Pat<(MipsJmpLink CPURegs:$dst),
524           (JALR CPURegs:$dst)>;
525
526 // GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
527 def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
528 def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
529 def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
530           (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
531 def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>;          
532
533 // Mips does not have not, so we increase the operation  
534 def : Pat<(not CPURegs:$in),
535           (NOR CPURegs:$in, ZERO)>;
536
537 // extended load and stores 
538 def : Pat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>;
539 def : Pat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>;
540 def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
541 def : Pat<(truncstorei1 CPURegs:$src, addr:$addr), 
542            (SB CPURegs:$src, addr:$addr)>;
543
544 ///
545 /// brcond patterns
546 ///
547
548 // direct match equal/notequal zero branches
549 def : Pat<(brcond (setne CPURegs:$lhs, 0), bb:$dst),
550           (BNE CPURegs:$lhs, ZERO, bb:$dst)>;
551 def : Pat<(brcond (seteq CPURegs:$lhs, 0), bb:$dst),
552           (BEQ CPURegs:$lhs, ZERO, bb:$dst)>;
553
554 def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
555           (BGEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
556 def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
557           (BGEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
558
559 def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
560           (BGTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
561 def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
562           (BGTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
563
564 def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
565           (BLEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
566 def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
567           (BLEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
568
569 def : Pat<(brcond (setlt CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
570           (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
571 def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
572           (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
573 def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
574           (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
575 def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
576           (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
577
578 def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
579           (BLTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
580 def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
581           (BLTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
582
583 // generic brcond pattern
584 def : Pat<(brcond CPURegs:$cond, bb:$dst),
585           (BNE CPURegs:$cond, ZERO, bb:$dst)>;
586
587 ///
588 /// setcc patterns, only matched when there 
589 /// is no brcond following a setcc operation
590 ///
591
592 // setcc 2 register operands
593 def : Pat<(setle CPURegs:$lhs, CPURegs:$rhs),
594           (XORi (SLT CPURegs:$rhs, CPURegs:$lhs), 1)>;
595 def : Pat<(setule CPURegs:$lhs, CPURegs:$rhs),
596           (XORi (SLTu CPURegs:$rhs, CPURegs:$lhs), 1)>;
597
598 def : Pat<(setgt CPURegs:$lhs, CPURegs:$rhs),
599           (SLT CPURegs:$rhs, CPURegs:$lhs)>;
600 def : Pat<(setugt CPURegs:$lhs, CPURegs:$rhs),
601           (SLTu CPURegs:$rhs, CPURegs:$lhs)>;
602
603 def : Pat<(setge CPURegs:$lhs, CPURegs:$rhs),
604           (XORi (SLT CPURegs:$lhs, CPURegs:$rhs), 1)>;
605 def : Pat<(setuge CPURegs:$lhs, CPURegs:$rhs),
606           (XORi (SLTu CPURegs:$lhs, CPURegs:$rhs), 1)>;
607
608 def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs),
609           (OR (SLT CPURegs:$lhs, CPURegs:$rhs), 
610               (SLT CPURegs:$rhs, CPURegs:$lhs))>;
611
612 def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
613           (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs), 
614                     (SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>;
615           
616 // setcc reg/imm operands
617 def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs),
618           (XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>;
619 def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs),
620           (XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>;
621