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