blob: 8f0854051b4eff95f172ec11c64751876ad7678d [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +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 if (N->getValueType(0) == MVT::i32)
86 return (uint32_t)N->getValue() == (unsigned short)N->getValue();
87 else
88 return (uint64_t)N->getValue() == (unsigned short)N->getValue();
89}], LO16>;
90
91// shamt field must fit in 5 bits.
92def immZExt5 : PatLeaf<(imm), [{
93 return N->getValue() == ((N->getValue()) & 0x1f) ;
94}]>;
95
96// Mips Address Mode! SDNode frameindex could possibily be a match
97// since load and store instructions from stack used it.
98def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>;
99
100//===----------------------------------------------------------------------===//
101// Instructions specific format
102//===----------------------------------------------------------------------===//
103
104// Arithmetic 3 register operands
105let isCommutable = 1 in
106class ArithR< bits<6> op, bits<6> func, string instr_asm, SDNode OpNode>:
107 FR< op,
108 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000109 (outs CPURegs:$dst),
110 (ins CPURegs:$b, CPURegs:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000111 !strconcat(instr_asm, " $dst, $b, $c"),
112 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
113
114let isCommutable = 1 in
115class ArithOverflowR< bits<6> op, bits<6> func, string instr_asm>:
116 FR< op,
117 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000118 (outs CPURegs:$dst),
119 (ins CPURegs:$b, CPURegs:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000120 !strconcat(instr_asm, " $dst, $b, $c"),
121 []>;
122
123// Arithmetic 2 register operands
124let isCommutable = 1 in
125class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
126 Operand Od, PatLeaf imm_type> :
127 FI< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000128 (outs CPURegs:$dst),
129 (ins CPURegs:$b, Od:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000130 !strconcat(instr_asm, " $dst, $b, $c"),
131 [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))] >;
132
133// Arithmetic Multiply ADD/SUB
134let rd=0 in
135class MArithR<bits<6> func, string instr_asm> :
136 FR< 0x1c,
137 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000138 (outs CPURegs:$rs),
139 (ins CPURegs:$rt),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000140 !strconcat(instr_asm, " $rs, $rt"),
141 []>;
142
143// Logical
144class LogicR<bits<6> func, string instr_asm, SDNode OpNode>:
145 FR< 0x00,
146 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000147 (outs CPURegs:$dst),
148 (ins CPURegs:$b, CPURegs:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000149 !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,
Evan Chengb783fa32007-07-19 01:14:50 +0000154 (outs CPURegs:$dst),
155 (ins CPURegs:$b, uimm16:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000156 !strconcat(instr_asm, " $dst, $b, $c"),
157 [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))]>;
158
159class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
160 FR< op,
161 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000162 (outs CPURegs:$dst),
163 (ins CPURegs:$b, CPURegs:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000164 !strconcat(instr_asm, " $dst, $b, $c"),
165 [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))] >;
166
167// Shifts
168let rt = 0 in
169class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>:
170 FR< 0x00,
171 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000172 (outs CPURegs:$dst),
173 (ins CPURegs:$b, shamt:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000174 !strconcat(instr_asm, " $dst, $b, $c"),
175 [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))] >;
176
177class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
178 FR< 0x00,
179 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000180 (outs CPURegs:$dst),
181 (ins CPURegs:$b, CPURegs:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000182 !strconcat(instr_asm, " $dst, $b, $c"),
183 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
184
185// Load Upper Imediate
186class LoadUpper<bits<6> op, string instr_asm>:
187 FI< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000188 (outs CPURegs:$dst),
189 (ins uimm16:$imm),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000190 !strconcat(instr_asm, " $dst, $imm"),
191 []>;
192
193// Memory Load/Store
194let isLoad = 1 in
195class LoadM<bits<6> op, string instr_asm, PatFrag OpNode>:
196 FI< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000197 (outs CPURegs:$dst),
198 (ins mem:$addr),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000199 !strconcat(instr_asm, " $dst, $addr"),
200 [(set CPURegs:$dst, (OpNode addr:$addr))]>;
201
202let isStore = 1 in
203class StoreM<bits<6> op, string instr_asm, PatFrag OpNode>:
204 FI< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000205 (outs),
206 (ins CPURegs:$dst, mem:$addr),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000207 !strconcat(instr_asm, " $dst, $addr"),
208 [(OpNode CPURegs:$dst, addr:$addr)]>;
209
210// Conditional Branch
Evan Cheng37e7c752007-07-21 00:34:19 +0000211let isBranch = 1, isTerminator=1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000212class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>:
213 FI< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000214 (outs),
215 (ins CPURegs:$a, CPURegs:$b, brtarget:$offset),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000216 !strconcat(instr_asm, " $a, $b, $offset"),
217 [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)]>;
218
219class SetCC_R<bits<6> op, bits<6> func, string instr_asm,
220 PatFrag cond_op>:
221 FR< op,
222 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000223 (outs CPURegs:$dst),
224 (ins CPURegs:$b, CPURegs:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000225 !strconcat(instr_asm, " $dst, $b, $c"),
226 [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))]>;
227
228class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op,
229 Operand Od, PatLeaf imm_type>:
230 FI< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000231 (outs CPURegs:$dst),
232 (ins CPURegs:$b, Od:$c),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000233 !strconcat(instr_asm, " $dst, $b, $c"),
234 [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))]>;
235
236// Unconditional branch
Evan Cheng37e7c752007-07-21 00:34:19 +0000237let hasCtrlDep=1, isTerminator=1 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000238class JumpFJ<bits<6> op, string instr_asm>:
239 FJ< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000240 (outs),
241 (ins brtarget:$target),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000242 !strconcat(instr_asm, " $target"),
243 [(br bb:$target)]>;
244
Evan Cheng37e7c752007-07-21 00:34:19 +0000245let hasCtrlDep=1, isTerminator=1, rd=0 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000246class JumpFR<bits<6> op, bits<6> func, string instr_asm>:
247 FR< op,
248 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000249 (outs),
250 (ins CPURegs:$target),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000251 !strconcat(instr_asm, " $target"),
252 []>;
253
254// Jump and Link (Call)
255let isCall=1 in
256class JumpLink<bits<6> op, string instr_asm>:
257 FJ< op,
Evan Chengb783fa32007-07-19 01:14:50 +0000258 (outs),
259 (ins calltarget:$target),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000260 !strconcat(instr_asm, " $target"),
261 [(MipsJmpLink imm:$target)]>;
262
263let isCall=1 in
264class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm>:
265 FR< op,
266 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000267 (outs),
268 (ins CPURegs:$rd, CPURegs:$rs),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000269 !strconcat(instr_asm, " $rs, $rd"),
270 []>;
271
272// Mul, Div
273class MulDiv<bits<6> func, string instr_asm>:
274 FR< 0x00,
275 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000276 (outs),
277 (ins CPURegs:$a, CPURegs:$b),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000278 !strconcat(instr_asm, " $a, $b"),
279 []>;
280
281// Move from Hi/Lo
282class MoveFromTo<bits<6> func, string instr_asm>:
283 FR< 0x00,
284 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000285 (outs CPURegs:$dst),
286 (ins),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000287 !strconcat(instr_asm, " $dst"),
288 []>;
289
290// Count Leading Ones/Zeros in Word
291class CountLeading<bits<6> func, string instr_asm>:
292 FR< 0x1c,
293 func,
Evan Chengb783fa32007-07-19 01:14:50 +0000294 (outs CPURegs:$dst),
295 (ins CPURegs:$src),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000296 !strconcat(instr_asm, " $dst, $src"),
297 []>;
298
299
300//===----------------------------------------------------------------------===//
301// Pseudo instructions
302//===----------------------------------------------------------------------===//
303
Evan Chengb783fa32007-07-19 01:14:50 +0000304class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
305 MipsInst<outs, ins, asmstr, pattern>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000306
307// As stack alignment is always done with addiu, we need a 16-bit immediate
Evan Chengb783fa32007-07-19 01:14:50 +0000308def ADJCALLSTACKDOWN : Pseudo<(outs), (ins uimm16:$amt),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000309 "!ADJCALLSTACKDOWN $amt",
310 [(callseq_start imm:$amt)]>, Imp<[SP],[SP]>;
Evan Chengb783fa32007-07-19 01:14:50 +0000311def ADJCALLSTACKUP : Pseudo<(outs), (ins uimm16:$amt),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000312 "!ADJCALLSTACKUP $amt",
313 [(callseq_end imm:$amt)]>, Imp<[SP],[SP]>;
314
Evan Chengb783fa32007-07-19 01:14:50 +0000315def IMPLICIT_DEF_CPURegs : Pseudo<(outs CPURegs:$dst), (ins),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000316 "!IMPLICIT_DEF $dst",
317 [(set CPURegs:$dst, (undef))]>;
318
319//===----------------------------------------------------------------------===//
320// Instruction definition
321//===----------------------------------------------------------------------===//
322
323//===----------------------------------------------------------------------===//
324// Mips32 I
325//===----------------------------------------------------------------------===//
326
327// Arithmetic
328def ADDiu : ArithI<0x09, "addiu", add, uimm16, immSExt16>;
329def ADDi : ArithI<0x08, "addi", add, simm16, immZExt16>;
330def MUL : ArithR<0x1c, 0x02, "mul", mul>;
331def ADDu : ArithR<0x00, 0x21, "addu", add>;
332def SUBu : ArithR<0x00, 0x23, "subu", sub>;
333def ADD : ArithOverflowR<0x00, 0x20, "add">;
334def SUB : ArithOverflowR<0x00, 0x22, "sub">;
335def MADD : MArithR<0x00, "madd">;
336def MADDU : MArithR<0x01, "maddu">;
337def MSUB : MArithR<0x04, "msub">;
338def MSUBU : MArithR<0x05, "msubu">;
339
340// Logical
341def AND : LogicR<0x24, "and", and>;
342def OR : LogicR<0x25, "or", or>;
343def XOR : LogicR<0x26, "xor", xor>;
344def ANDi : LogicI<0x0c, "andi", and>;
345def ORi : LogicI<0x0d, "ori", or>;
346def XORi : LogicI<0x0e, "xori", xor>;
347def NOR : LogicNOR<0x00, 0x27, "nor">;
348
349// Shifts
350def SLL : LogicR_shift_imm<0x00, "sll", shl>;
351def SRL : LogicR_shift_imm<0x02, "srl", srl>;
352def SRA : LogicR_shift_imm<0x03, "sra", sra>;
353def SLLV : LogicR_shift_reg<0x04, "sllv", shl>;
354def SRLV : LogicR_shift_reg<0x06, "srlv", srl>;
355def SRAV : LogicR_shift_reg<0x07, "srav", sra>;
356
357// Load Upper Immediate
358def LUi : LoadUpper<0x0f, "lui">;
359
360// Load/Store
361def LB : LoadM<0x20, "lb", sextloadi8>;
362def LBu : LoadM<0x24, "lbu", zextloadi8>;
363def LH : LoadM<0x21, "lh", sextloadi16>;
364def LHu : LoadM<0x25, "lhu", zextloadi16>;
365def LW : LoadM<0x23, "lw", load>;
366def SB : StoreM<0x28, "sb", truncstorei8>;
367def SH : StoreM<0x29, "sh", truncstorei16>;
368def SW : StoreM<0x2b, "sw", store>;
369
370// Conditional Branch
371def BEQ : CBranch<0x04, "beq", seteq>;
372def BNE : CBranch<0x05, "bne", setne>;
373def SLT : SetCC_R<0x00, 0x2a, "slt", setlt>;
374def SLTu : SetCC_R<0x00, 0x2b, "sltu", setult>;
375def SLTi : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>;
376def SLTiu : SetCC_I<0x0b, "sltiu", setult, uimm16, immZExt16>;
377
378// Unconditional jump
379def J : JumpFJ<0x02, "j">;
380def JR : JumpFR<0x00, 0x08, "jr">;
381
382// Jump and Link (Call)
383def JAL : JumpLink<0x03, "jal">;
384def JALR : JumpLinkReg<0x00, 0x09, "jalr">;
385
386// MulDiv and Move From Hi/Lo operations, have
387// their correpondent SDNodes created on ISelDAG.
388// Special Mul, Div operations
389def MULT : MulDiv<0x18, "mult">;
390def MULTu : MulDiv<0x19, "multu">;
391def DIV : MulDiv<0x1a, "div">;
392def DIVu : MulDiv<0x1b, "divu">;
393
394// Move From Hi/Lo
395def MFHI : MoveFromTo<0x10, "mfhi">;
396def MFLO : MoveFromTo<0x12, "mflo">;
397def MTHI : MoveFromTo<0x11, "mthi">;
398def MTLO : MoveFromTo<0x13, "mtlo">;
399
400// Count Leading
401def CLO : CountLeading<0x21, "clo">;
402def CLZ : CountLeading<0x20, "clz">;
403
404// No operation
405let addr=0 in
Evan Chengb783fa32007-07-19 01:14:50 +0000406def NOOP : FJ<0, (outs), (ins), "nop", []>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000407
408// Ret instruction - as mips does not have "ret" a
409// jr $ra must be generated.
Evan Cheng37e7c752007-07-21 00:34:19 +0000410let isReturn=1, isTerminator=1, hasDelaySlot=1,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000411 isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
412{
Evan Chengb783fa32007-07-19 01:14:50 +0000413 def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000414 "jr $target", [(MipsRet CPURegs:$target)]>;
415}
416
417//===----------------------------------------------------------------------===//
418// Arbitrary patterns that map to one or more instructions
419//===----------------------------------------------------------------------===//
420
421// Small immediates
422def : Pat<(i32 immSExt16:$in),
423 (ADDiu ZERO, imm:$in)>;
424def : Pat<(i32 immZExt16:$in),
425 (ORi ZERO, imm:$in)>;
426
427// Arbitrary immediates
428def : Pat<(i32 imm:$imm),
429 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
430
431// Call
432def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
433 (JAL tglobaladdr:$dst)>;
434def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
435 (JAL texternalsym:$dst)>;
436
437// GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
438def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
439def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
440
441// When extracting the address from GlobalAddress we
442// need something of the form "addiu $reg, %lo(addr)"
443def : Pat<(add CPURegs:$a, (MipsLo tglobaladdr:$in)),
444 (ADDiu CPURegs:$a, tglobaladdr:$in)>;
445
446// Mips does not have not, so we increase the operation
447def : Pat<(not CPURegs:$in),
448 (NOR CPURegs:$in, CPURegs:$in)>;
449
450// extended load and stores
451def : Pat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
452def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
453def : Pat<(truncstorei1 CPURegs:$src, addr:$addr),
454 (SB CPURegs:$src, addr:$src)>;
455
456def : Pat<(brcond (setne CPURegs:$lhs, (add ZERO, 0)), bb:$dst),
457 (BNE CPURegs:$lhs, ZERO, bb:$dst)>;
458
459
460// Conditional branch patterns.
461// cond branches patterns, 2 register operands signed.
462def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
463 (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
464def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
465 (BEQ (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
466def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
467 (BNE (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
468def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
469 (BEQ (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
470
471// cond branches patterns, 2 register operands unsigned.
472def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
473 (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
474def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
475 (BEQ (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
476def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
477 (BNE (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
478def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
479 (BEQ (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
480
481// cond branches patterns, reg/imm operands signed.
482def : Pat<(brcond (setult CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
483 (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
484def : Pat<(brcond (setuge CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
485 (BEQ (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
486
487// cond branches patterns, reg/imm operands unsigned.
488def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
489 (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
490def : Pat<(brcond (setuge CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
491 (BEQ (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;