llvm.org GIT mirror llvm / 9710536
MipsHi now has ouput flag MipsAdd SDNode created to add support to an Add opcode which supports input flag Added an instruction itinerary to all instruction classes Added branches with zero cond codes Now call clobbers all non-callee saved registers Call w/ register support added Added DelaySlot to branch and load instructions Added patterns to handle all setcc, brcond/setcc and MipsAdd instructions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41161 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 13 years ago
1 changed file(s) with 193 addition(s) and 99 deletion(s). Raw diff Collapse all Expand all
2525 // handling 32-bit immediates. They are used on MipsISelLowering to
2626 // lower stuff like GlobalAddress, ExternalSymbol, ...
2727 // This two nodes have nothing to do with Mips Registers Hi and Lo.
28 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
28 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>;
2929 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
30
31 // Necessary to generate glued instructions when loading GlobalAddress
32 // into registers.
33 def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative,
34 SDNPAssociative, SDNPOptInFlag]>;
3035
3136 // Return
3237 def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
8792 return (uint64_t)N->getValue() == (unsigned short)N->getValue();
8893 }], LO16>;
8994
95 // Node immediate fits as 32-bit zero extended on target immediate.
96 //def immZExt32 : PatLeaf<(imm), [{
97 // return (uint64_t)N->getValue() == (uint32_t)N->getValue();
98 //}], LO16>;
99
90100 // shamt field must fit in 5 bits.
91101 def immZExt5 : PatLeaf<(imm), [{
92102 return N->getValue() == ((N->getValue()) & 0x1f) ;
102112
103113 // Arithmetic 3 register operands
104114 let isCommutable = 1 in
105 class ArithR< bits<6> op, bits<6> func, string instr_asm, SDNode OpNode>:
115 class ArithR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode,
116 InstrItinClass itin>:
106117 FR< op,
107118 func,
108119 (outs CPURegs:$dst),
109120 (ins CPURegs:$b, CPURegs:$c),
110121 !strconcat(instr_asm, " $dst, $b, $c"),
111 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
122 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
112123
113124 let isCommutable = 1 in
114 class ArithOverflowR< bits<6> op, bits<6> func, string instr_asm>:
125 class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm>:
115126 FR< op,
116127 func,
117128 (outs CPURegs:$dst),
118129 (ins CPURegs:$b, CPURegs:$c),
119130 !strconcat(instr_asm, " $dst, $b, $c"),
120 []>;
131 [], IIAlu>;
121132
122133 // Arithmetic 2 register operands
123134 let isCommutable = 1 in
127138 (outs CPURegs:$dst),
128139 (ins CPURegs:$b, Od:$c),
129140 !strconcat(instr_asm, " $dst, $b, $c"),
130 [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))] >;
141 [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>;
131142
132143 // Arithmetic Multiply ADD/SUB
133144 let rd=0 in
137148 (outs CPURegs:$rs),
138149 (ins CPURegs:$rt),
139150 !strconcat(instr_asm, " $rs, $rt"),
140 []>;
151 [], IIImul>;
141152
142153 // Logical
143154 class LogicR func, string instr_asm, SDNode OpNode>:
146157 (outs CPURegs:$dst),
147158 (ins CPURegs:$b, CPURegs:$c),
148159 !strconcat(instr_asm, " $dst, $b, $c"),
149 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
160 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
150161
151162 class LogicI op, string instr_asm, SDNode OpNode>:
152163 FI< op,
153164 (outs CPURegs:$dst),
154165 (ins CPURegs:$b, uimm16:$c),
155166 !strconcat(instr_asm, " $dst, $b, $c"),
156 [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))]>;
167 [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))], IIAlu>;
157168
158169 class LogicNOR op, bits<6> func, string instr_asm>:
159170 FR< op,
161172 (outs CPURegs:$dst),
162173 (ins CPURegs:$b, CPURegs:$c),
163174 !strconcat(instr_asm, " $dst, $b, $c"),
164 [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))] >;
175 [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))], IIAlu>;
165176
166177 // Shifts
167178 let rt = 0 in
171182 (outs CPURegs:$dst),
172183 (ins CPURegs:$b, shamt:$c),
173184 !strconcat(instr_asm, " $dst, $b, $c"),
174 [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))] >;
185 [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu>;
175186
176187 class LogicR_shift_reg func, string instr_asm, SDNode OpNode>:
177188 FR< 0x00,
179190 (outs CPURegs:$dst),
180191 (ins CPURegs:$b, CPURegs:$c),
181192 !strconcat(instr_asm, " $dst, $b, $c"),
182 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
193 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
183194
184195 // Load Upper Imediate
185196 class LoadUpper op, string instr_asm>:
187198 (outs CPURegs:$dst),
188199 (ins uimm16:$imm),
189200 !strconcat(instr_asm, " $dst, $imm"),
190 []>;
201 [], IIAlu>;
191202
192203 // Memory Load/Store
193 let isLoad = 1 in
204 let isLoad = 1, hasDelaySlot = 1 in
194205 class LoadM op, string instr_asm, PatFrag OpNode>:
195206 FI< op,
196207 (outs CPURegs:$dst),
197208 (ins mem:$addr),
198209 !strconcat(instr_asm, " $dst, $addr"),
199 [(set CPURegs:$dst, (OpNode addr:$addr))]>;
210 [(set CPURegs:$dst, (OpNode addr:$addr))], IILoad>;
200211
201212 let isStore = 1 in
202213 class StoreM op, string instr_asm, PatFrag OpNode>:
204215 (outs),
205216 (ins CPURegs:$dst, mem:$addr),
206217 !strconcat(instr_asm, " $dst, $addr"),
207 [(OpNode CPURegs:$dst, addr:$addr)]>;
218 [(OpNode CPURegs:$dst, addr:$addr)], IIStore>;
208219
209220 // Conditional Branch
210 let isBranch = 1, isTerminator=1 in
221 let isBranch = 1, isTerminator=1, hasDelaySlot = 1 in {
211222 class CBranch op, string instr_asm, PatFrag cond_op>:
212223 FI< op,
213224 (outs),
214225 (ins CPURegs:$a, CPURegs:$b, brtarget:$offset),
215226 !strconcat(instr_asm, " $a, $b, $offset"),
216 [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)]>;
217
227 [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)],
228 IIBranch>;
229
230
231 class CBranchZero op, string instr_asm, PatFrag cond_op>:
232 FI< op,
233 (outs),
234 (ins CPURegs:$src, brtarget:$offset),
235 !strconcat(instr_asm, " $src, $offset"),
236 [(brcond (cond_op CPURegs:$src, 0), bb:$offset)],
237 IIBranch>;
238 }
239
240 // SetCC
218241 class SetCC_R op, bits<6> func, string instr_asm,
219242 PatFrag cond_op>:
220243 FR< op,
222245 (outs CPURegs:$dst),
223246 (ins CPURegs:$b, CPURegs:$c),
224247 !strconcat(instr_asm, " $dst, $b, $c"),
225 [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))]>;
248 [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))],
249 IIAlu>;
226250
227251 class SetCC_I op, string instr_asm, PatFrag cond_op,
228252 Operand Od, PatLeaf imm_type>:
230254 (outs CPURegs:$dst),
231255 (ins CPURegs:$b, Od:$c),
232256 !strconcat(instr_asm, " $dst, $b, $c"),
233 [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))]>;
257 [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))],
258 IIAlu>;
234259
235260 // Unconditional branch
236 let hasCtrlDep=1, isTerminator=1 in
261 let isBranch=1, isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
237262 class JumpFJ op, string instr_asm>:
238263 FJ< op,
239264 (outs),
240265 (ins brtarget:$target),
241266 !strconcat(instr_asm, " $target"),
242 [(br bb:$target)]>;
243
244 let hasCtrlDep=1, isTerminator=1, rd=0 in
267 [(br bb:$target)], IIBranch>;
268
269 let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in
245270 class JumpFR op, bits<6> func, string instr_asm>:
246271 FR< op,
247272 func,
248273 (outs),
249274 (ins CPURegs:$target),
250275 !strconcat(instr_asm, " $target"),
251 []>;
276 [], IIBranch>;
252277
253278 // Jump and Link (Call)
254 let isCall=1 in
255 class JumpLink op, string instr_asm>:
256 FJ< op,
257 (outs),
258 (ins calltarget:$target),
259 !strconcat(instr_asm, " $target"),
260 [(MipsJmpLink imm:$target)]>;
261
262 let isCall=1 in
263 class JumpLinkReg op, bits<6> func, string instr_asm>:
264 FR< op,
265 func,
266 (outs),
267 (ins CPURegs:$rd, CPURegs:$rs),
268 !strconcat(instr_asm, " $rs, $rd"),
269 []>;
279 let isCall=1, hasDelaySlot=1,
280 // All calls clobber the non-callee saved registers...
281 Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2,
282 T3, T4, T5, T6, T7, T8, T9, K0, K1, GP] in {
283 class JumpLink op, string instr_asm>:
284 FJ< op,
285 (outs),
286 (ins calltarget:$target),
287 !strconcat(instr_asm, " $target"),
288 [(MipsJmpLink imm:$target)], IIBranch>;
289
290 let rd=31 in
291 class JumpLinkReg op, bits<6> func, string instr_asm>:
292 FR< op,
293 func,
294 (outs),
295 (ins CPURegs:$rs),
296 !strconcat(instr_asm, " $rs"),
297 [(MipsJmpLink CPURegs:$rs)], IIBranch>;
298
299 class BranchLink:
300 FI< 0x1,
301 (outs),
302 (ins CPURegs:$rs, brtarget:$target),
303 !strconcat(instr_asm, " $rs, $target"),
304 [], IIBranch>;
305 }
270306
271307 // Mul, Div
272 class MulDiv func, string instr_asm>:
308 class MulDiv func, string instr_asm, InstrItinClass itin>:
273309 FR< 0x00,
274310 func,
275311 (outs),
276312 (ins CPURegs:$a, CPURegs:$b),
277313 !strconcat(instr_asm, " $a, $b"),
278 []>;
314 [], itin>;
279315
280316 // Move from Hi/Lo
281317 class MoveFromTo func, string instr_asm>:
284320 (outs CPURegs:$dst),
285321 (ins),
286322 !strconcat(instr_asm, " $dst"),
287 []>;
323 [], IIHiLo>;
288324
289325 // Count Leading Ones/Zeros in Word
290326 class CountLeading func, string instr_asm>:
293329 (outs CPURegs:$dst),
294330 (ins CPURegs:$src),
295331 !strconcat(instr_asm, " $dst, $src"),
296 []>;
332 [], IIAlu>;
297333
298334
299335 //===----------------------------------------------------------------------===//
300336 // Pseudo instructions
301337 //===----------------------------------------------------------------------===//
302338
303 class Pseudo pattern>:
304 MipsInst;
339 class Pseudo pattern>:
340 MipsInst;
305341
306342 // As stack alignment is always done with addiu, we need a 16-bit immediate
307343 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins uimm16:$amt),
320356 //===----------------------------------------------------------------------===//
321357
322358 //===----------------------------------------------------------------------===//
323 // Mips32 I
359 // MipsI Instructions
324360 //===----------------------------------------------------------------------===//
325361
326362 // Arithmetic
327 def ADDiu : ArithI<0x09, "addiu", add, uimm16, immSExt16>;
328 def ADDi : ArithI<0x08, "addi", add, simm16, immZExt16>;
329 def MUL : ArithR<0x1c, 0x02, "mul", mul>;
330 def ADDu : ArithR<0x00, 0x21, "addu", add>;
331 def SUBu : ArithR<0x00, 0x23, "subu", sub>;
363
364 // ADDiu just accept 16-bit immediates but we handle this on Pat's.
365 // immZExt32 is used here so it can match GlobalAddress immediates.
366 def ADDiu : ArithI<0x09, "addiu", MipsAdd, uimm16, immZExt16>;
367 def ADDi : ArithI<0x08, "addi", add, simm16, immSExt16>;
368 def MUL : ArithR<0x1c, 0x02, "mul", mul, IIImul>;
369 def ADDu : ArithR<0x00, 0x21, "addu", add, IIAlu>;
370 def SUBu : ArithR<0x00, 0x23, "subu", sub, IIAlu>;
332371 def ADD : ArithOverflowR<0x00, 0x20, "add">;
333372 def SUB : ArithOverflowR<0x00, 0x22, "sub">;
334373 def MADD : MArithR<0x00, "madd">;
369408 // Conditional Branch
370409 def BEQ : CBranch<0x04, "beq", seteq>;
371410 def BNE : CBranch<0x05, "bne", setne>;
411
412 let rt=1 in
413 def BGEZ : CBranchZero<0x01, "bgez", setge>;
414
415 let rt=0 in {
416 def BGTZ : CBranchZero<0x07, "bgtz", setgt>;
417 def BLEZ : CBranchZero<0x07, "blez", setle>;
418 def BLTZ : CBranchZero<0x01, "bltz", setlt>;
419 }
420
421 // Set Condition Code
372422 def SLT : SetCC_R<0x00, 0x2a, "slt", setlt>;
373423 def SLTu : SetCC_R<0x00, 0x2b, "sltu", setult>;
374424 def SLTi : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>;
381431 // Jump and Link (Call)
382432 def JAL : JumpLink<0x03, "jal">;
383433 def JALR : JumpLinkReg<0x00, 0x09, "jalr">;
434 def BGEZAL : BranchLink<"bgezal">;
435 def BLTZAL : BranchLink<"bltzal">;
384436
385437 // MulDiv and Move From Hi/Lo operations, have
386438 // their correpondent SDNodes created on ISelDAG.
387439 // Special Mul, Div operations
388 def MULT : MulDiv<0x18, "mult">;
389 def MULTu : MulDiv<0x19, "multu">;
390 def DIV : MulDiv<0x1a, "div">;
391 def DIVu : MulDiv<0x1b, "divu">;
440 def MULT : MulDiv<0x18, "mult", IIImul>;
441 def MULTu : MulDiv<0x19, "multu", IIImul>;
442 def DIV : MulDiv<0x1a, "div", IIIdiv>;
443 def DIVu : MulDiv<0x1b, "divu", IIIdiv>;
392444
393445 // Move From Hi/Lo
394446 def MFHI : MoveFromTo<0x10, "mfhi">;
402454
403455 // No operation
404456 let addr=0 in
405 def NOOP : FJ<0, (outs), (ins), "nop", []>;
457 def NOP : FJ<0, (outs), (ins), "nop", [], IIAlu>;
406458
407459 // Ret instruction - as mips does not have "ret" a
408460 // jr $ra must be generated.
410462 isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
411463 {
412464 def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
413 "jr $target", [(MipsRet CPURegs:$target)]>;
465 "jr $target", [(MipsRet CPURegs:$target)], IIBranch>;
414466 }
415467
416468 //===----------------------------------------------------------------------===//
432484 (JAL tglobaladdr:$dst)>;
433485 def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
434486 (JAL texternalsym:$dst)>;
487 def : Pat<(MipsJmpLink CPURegs:$dst),
488 (JALR CPURegs:$dst)>;
435489
436490 // GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
437491 def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
438492 def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
439
440 // When extracting the address from GlobalAddress we
441 // need something of the form "addiu $reg, %lo(addr)"
442 def : Pat<(add CPURegs:$a, (MipsLo tglobaladdr:$in)),
443 (ADDiu CPURegs:$a, tglobaladdr:$in)>;
493 def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
494 (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
444495
445496 // Mips does not have not, so we increase the operation
446497 def : Pat<(not CPURegs:$in),
447 (NOR CPURegs:$in, CPURegs:$in)>;
498 (NOR CPURegs:$in, ZERO)>;
448499
449500 // extended load and stores
501 def : Pat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
450502 def : Pat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
451503 def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
452504 def : Pat<(truncstorei1 CPURegs:$src, addr:$addr),
453 (SB CPURegs:$src, addr:$src)>;
454
455 def : Pat<(brcond (setne CPURegs:$lhs, (add ZERO, 0)), bb:$dst),
505 (SB CPURegs:$src, addr:$addr)>;
506
507 ///
508 /// brcond patterns
509 ///
510
511 // direct match equal/notequal zero branches
512 def : Pat<(brcond (setne CPURegs:$lhs, 0), bb:$dst),
456513 (BNE CPURegs:$lhs, ZERO, bb:$dst)>;
457
458
459 // Conditional branch patterns.
460 // cond branches patterns, 2 register operands signed.
514 def : Pat<(brcond (seteq CPURegs:$lhs, 0), bb:$dst),
515 (BEQ CPURegs:$lhs, ZERO, bb:$dst)>;
516
517 def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
518 (BGEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
519 def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
520 (BGEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
521
522 def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
523 (BGTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
524 def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
525 (BGTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
526
527 def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
528 (BLEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
529 def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
530 (BLEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
531
532 def : Pat<(brcond (setlt CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
533 (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
534 def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
535 (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
461536 def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
462537 (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
463 def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
464 (BEQ (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
465 def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
466 (BNE (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
467 def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
468 (BEQ (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
469
470 // cond branches patterns, 2 register operands unsigned.
471538 def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
472539 (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
473 def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
474 (BEQ (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
475 def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
476 (BNE (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
477 def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
478 (BEQ (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
479
480 // cond branches patterns, reg/imm operands signed.
481 def : Pat<(brcond (setult CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
482 (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
483 def : Pat<(brcond (setuge CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
484 (BEQ (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
485
486 // cond branches patterns, reg/imm operands unsigned.
487 def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
488 (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
489 def : Pat<(brcond (setuge CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
490 (BEQ (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
540
541 def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
542 (BLTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
543 def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
544 (BLTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
545
546 // generic brcond pattern
547 def : Pat<(brcond CPURegs:$cond, bb:$dst),
548 (BNE CPURegs:$cond, ZERO, bb:$dst)>;
549
550 ///
551 /// setcc patterns, only matched when there
552 /// is no brcond following a setcc operation
553 ///
554
555 // setcc 2 register operands
556 def : Pat<(setle CPURegs:$lhs, CPURegs:$rhs),
557 (XORi (SLT CPURegs:$rhs, CPURegs:$lhs), 1)>;
558 def : Pat<(setule CPURegs:$lhs, CPURegs:$rhs),
559 (XORi (SLTu CPURegs:$rhs, CPURegs:$lhs), 1)>;
560
561 def : Pat<(setgt CPURegs:$lhs, CPURegs:$rhs),
562 (SLT CPURegs:$rhs, CPURegs:$lhs)>;
563 def : Pat<(setugt CPURegs:$lhs, CPURegs:$rhs),
564 (SLTu CPURegs:$rhs, CPURegs:$lhs)>;
565
566 def : Pat<(setge CPURegs:$lhs, CPURegs:$rhs),
567 (XORi (SLT CPURegs:$lhs, CPURegs:$rhs), 1)>;
568 def : Pat<(setuge CPURegs:$lhs, CPURegs:$rhs),
569 (XORi (SLTu CPURegs:$lhs, CPURegs:$rhs), 1)>;
570
571 def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs),
572 (OR (SLT CPURegs:$lhs, CPURegs:$rhs),
573 (SLT CPURegs:$rhs, CPURegs:$lhs))>;
574
575 def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
576 (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs),
577 (SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>;
578
579 // setcc reg/imm operands
580 def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs),
581 (XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>;
582 def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs),
583 (XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>;
584