1//===- Mips16InstrInfo.td - Target Description for Mips16  -*- tablegen -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes Mips16 instructions.
11//
12//===----------------------------------------------------------------------===//
13//
14//
15// Mips Address
16//
17def addr16 :
18  ComplexPattern<iPTR, 3, "selectAddr16", [frameindex], [SDNPWantParent]>;
19
20//
21// Address operand
22def mem16 : Operand<i32> {
23  let PrintMethod = "printMemOperand";
24  let MIOperandInfo = (ops CPU16Regs, simm16, CPU16RegsPlusSP);
25  let EncoderMethod = "getMemEncoding";
26}
27
28def mem16_ea : Operand<i32> {
29  let PrintMethod = "printMemOperandEA";
30  let MIOperandInfo = (ops CPU16RegsPlusSP, simm16);
31  let EncoderMethod = "getMemEncoding";
32}
33
34//
35// I-type instruction format
36//
37// this is only used by bimm. the actual assembly value is a 12 bit signed
38// number
39//
40class FI16_ins<bits<5> op, string asmstr, InstrItinClass itin>:
41  FI16<op, (outs), (ins brtarget:$imm16),
42            !strconcat(asmstr, "\t$imm16 # 16 bit inst"), [], itin>;
43
44//
45//
46// I8 instruction format
47//
48
49class FI816_ins_base<bits<3> _func, string asmstr,
50                     string asmstr2, InstrItinClass itin>:
51  FI816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
52        [], itin>;
53
54class FI816_ins<bits<3> _func, string asmstr,
55                InstrItinClass itin>:
56  FI816_ins_base<_func, asmstr, "\t$imm  # 16 bit inst", itin>;
57 
58class FI816_SP_ins<bits<3> _func, string asmstr,
59                   InstrItinClass itin>:
60  FI816_ins_base<_func, asmstr, "\t$$sp, $imm # 16 bit inst", itin>;
61
62//
63// RI instruction format
64//
65
66
67class FRI16_ins_base<bits<5> op, string asmstr, string asmstr2,
68                     InstrItinClass itin>:
69  FRI16<op, (outs CPU16Regs:$rx), (ins simm16:$imm),
70        !strconcat(asmstr, asmstr2), [], itin>;
71
72class FRI16_ins<bits<5> op, string asmstr,
73                InstrItinClass itin>:
74  FRI16_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;
75
76class FRI16_TCP_ins<bits<5> _op, string asmstr,
77                    InstrItinClass itin>:
78  FRI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),
79            !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin>;
80            
81class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2,
82                     InstrItinClass itin>:
83  FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm),
84        !strconcat(asmstr, asmstr2), [], itin>;
85
86class FRI16R_ins<bits<5> op, string asmstr,
87                InstrItinClass itin>:
88  FRI16R_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;
89
90class F2RI16_ins<bits<5> _op, string asmstr,
91                     InstrItinClass itin>:
92  FRI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
93        !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin> {
94  let Constraints = "$rx_ = $rx";
95}
96
97class FRI16_B_ins<bits<5> _op, string asmstr,
98                  InstrItinClass itin>:
99  FRI16<_op, (outs), (ins  CPU16Regs:$rx, brtarget:$imm),
100        !strconcat(asmstr, "\t$rx, $imm  # 16 bit inst"), [], itin>;
101//
102// Compare a register and immediate and place result in CC
103// Implicit use of T8
104//
105// EXT-CCRR Instruction format
106//
107class FEXT_CCRXI16_ins<string asmstr>:
108  MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, simm16:$imm),
109               !strconcat(asmstr, "\t$rx, $imm\n\tmove\t$cc, $$t8"), []> {
110  let isCodeGenOnly=1;
111  let usesCustomInserter = 1;
112}
113
114// JAL and JALX instruction format
115//
116class FJAL16_ins<bits<1> _X, string asmstr,
117                 InstrItinClass itin>:
118  FJAL16<_X, (outs), (ins simm20:$imm),
119         !strconcat(asmstr, "\t$imm\n\tnop"),[],
120         itin>  {
121  let isCodeGenOnly=1;
122  let Size=6;
123}
124
125class FJALB16_ins<bits<1> _X, string asmstr,
126                 InstrItinClass itin>:
127  FJAL16<_X, (outs), (ins simm20:$imm),
128         !strconcat(asmstr, "\t$imm\t# branch\n\tnop"),[],
129         itin>  {
130  let isCodeGenOnly=1;
131  let Size=6;
132}
133
134//
135// EXT-I instruction format
136//
137class FEXT_I16_ins<bits<5> eop, string asmstr, InstrItinClass itin> :
138  FEXT_I16<eop, (outs), (ins brtarget:$imm16),
139           !strconcat(asmstr, "\t$imm16"),[], itin>;
140
141//
142// EXT-I8 instruction format
143//
144
145class FEXT_I816_ins_base<bits<3> _func, string asmstr,
146                         string asmstr2, InstrItinClass itin>:
147  FEXT_I816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
148            [], itin>;
149
150class FEXT_I816_ins<bits<3> _func, string asmstr,
151                    InstrItinClass itin>:
152  FEXT_I816_ins_base<_func, asmstr, "\t$imm", itin>;
153
154class FEXT_I816_SP_ins<bits<3> _func, string asmstr,
155                       InstrItinClass itin>:
156      FEXT_I816_ins_base<_func, asmstr, "\t$$sp, $imm", itin>;
157
158//
159// Assembler formats in alphabetical order.
160// Natural and pseudos are mixed together.
161//
162// Compare two registers and place result in CC
163// Implicit use of T8
164//
165// CC-RR Instruction format
166//
167class FCCRR16_ins<string asmstr> :
168  MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, CPU16Regs:$ry),
169               !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$cc, $$t8"), []> {
170  let isCodeGenOnly=1;
171  let usesCustomInserter = 1;
172}
173
174//
175// EXT-RI instruction format
176//
177
178class FEXT_RI16_ins_base<bits<5> _op, string asmstr, string asmstr2,
179                         InstrItinClass itin>:
180  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins simm16:$imm),
181                  !strconcat(asmstr, asmstr2), [], itin>;
182
183class FEXT_RI16_ins<bits<5> _op, string asmstr,
184                    InstrItinClass itin>:
185  FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
186
187class FEXT_RI16R_ins_base<bits<5> _op, string asmstr, string asmstr2,
188                         InstrItinClass itin>:
189  FEXT_RI16<_op, (outs ), (ins CPU16Regs:$rx, simm16:$imm),
190                  !strconcat(asmstr, asmstr2), [], itin>;
191
192class FEXT_RI16R_ins<bits<5> _op, string asmstr,
193                    InstrItinClass itin>:
194  FEXT_RI16R_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
195
196class FEXT_RI16_PC_ins<bits<5> _op, string asmstr, InstrItinClass itin>:
197  FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $$pc, $imm", itin>;
198
199class FEXT_RI16_B_ins<bits<5> _op, string asmstr,
200                      InstrItinClass itin>:
201  FEXT_RI16<_op, (outs), (ins  CPU16Regs:$rx, brtarget:$imm),
202            !strconcat(asmstr, "\t$rx, $imm"), [], itin>;
203
204class FEXT_RI16_TCP_ins<bits<5> _op, string asmstr,
205                        InstrItinClass itin>:
206  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),
207            !strconcat(asmstr, "\t$rx, $imm"), [], itin>;
208
209class FEXT_2RI16_ins<bits<5> _op, string asmstr,
210                     InstrItinClass itin>:
211  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
212            !strconcat(asmstr, "\t$rx, $imm"), [], itin> {
213  let Constraints = "$rx_ = $rx";
214}
215
216
217// this has an explicit sp argument that we ignore to work around a problem
218// in the compiler
219class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr,
220                                InstrItinClass itin>:
221  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm),
222            !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
223
224class FEXT_RI16_SP_Store_explicit_ins<bits<5> _op, string asmstr,
225                                InstrItinClass itin>:
226  FEXT_RI16<_op, (outs), (ins  CPU16Regs:$rx, CPUSPReg:$ry, simm16:$imm),
227            !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
228
229//
230// EXT-RRI instruction format
231//
232
233class FEXT_RRI16_mem_ins<bits<5> op, string asmstr, Operand MemOpnd,
234                         InstrItinClass itin>:
235  FEXT_RRI16<op, (outs CPU16Regs:$ry), (ins  MemOpnd:$addr),
236             !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
237
238class FEXT_RRI16_mem2_ins<bits<5> op, string asmstr, Operand MemOpnd,
239                          InstrItinClass itin>:
240  FEXT_RRI16<op, (outs ), (ins  CPU16Regs:$ry, MemOpnd:$addr),
241             !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
242
243//
244//
245// EXT-RRI-A instruction format
246//
247
248class FEXT_RRI_A16_mem_ins<bits<1> op, string asmstr, Operand MemOpnd,
249                           InstrItinClass itin>:
250  FEXT_RRI_A16<op, (outs CPU16Regs:$ry), (ins  MemOpnd:$addr),
251               !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
252
253//
254// EXT-SHIFT instruction format
255//
256class FEXT_SHIFT16_ins<bits<2> _f, string asmstr, InstrItinClass itin>:
257  FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, uimm5:$sa),
258               !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>;
259
260//
261// EXT-T8I8
262//
263class FEXT_T8I816_ins<string asmstr, string asmstr2>:
264  MipsPseudo16<(outs),
265               (ins CPU16Regs:$rx, CPU16Regs:$ry, brtarget:$imm),
266               !strconcat(asmstr2, !strconcat("\t$rx, $ry\n\t",
267               !strconcat(asmstr, "\t$imm"))),[]> {
268  let isCodeGenOnly=1;
269  let usesCustomInserter = 1;
270}
271
272//
273// EXT-T8I8I
274//
275class FEXT_T8I8I16_ins<string asmstr, string asmstr2>:
276  MipsPseudo16<(outs),
277               (ins CPU16Regs:$rx, simm16:$imm, brtarget:$targ),
278               !strconcat(asmstr2, !strconcat("\t$rx, $imm\n\t",
279               !strconcat(asmstr, "\t$targ"))), []> {
280  let isCodeGenOnly=1;
281  let usesCustomInserter = 1;
282}
283//
284
285
286//
287// I8_MOVR32 instruction format (used only by the MOVR32 instructio
288//
289class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>:
290       FI8_MOVR3216<(outs CPU16Regs:$rz), (ins GPR32:$r32),
291       !strconcat(asmstr,  "\t$rz, $r32"), [], itin>;
292
293//
294// I8_MOV32R instruction format (used only by MOV32R instruction)
295//
296
297class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>:
298  FI8_MOV32R16<(outs GPR32:$r32), (ins CPU16Regs:$rz),
299               !strconcat(asmstr,  "\t$r32, $rz"), [], itin>;
300
301//
302// This are pseudo formats for multiply
303// This first one can be changed to non-pseudo now.
304//
305// MULT
306//
307class FMULT16_ins<string asmstr, InstrItinClass itin> :
308  MipsPseudo16<(outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
309               !strconcat(asmstr, "\t$rx, $ry"), []>;
310
311//
312// MULT-LO
313//
314class FMULT16_LO_ins<string asmstr, InstrItinClass itin> :
315  MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
316               !strconcat(asmstr, "\t$rx, $ry\n\tmflo\t$rz"), []> {
317  let isCodeGenOnly=1;
318}
319
320//
321// RR-type instruction format
322//
323
324class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
325  FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
326        !strconcat(asmstr, "\t$rx, $ry"), [], itin> {
327}
328
329class FRRBreakNull16_ins<string asmstr, InstrItinClass itin> :
330  FRRBreak16<(outs), (ins), asmstr, [], itin> {
331  let Code=0;
332}
333
334class FRR16R_ins<bits<5> f, string asmstr, InstrItinClass itin> :
335  FRR16<f, (outs), (ins  CPU16Regs:$rx, CPU16Regs:$ry),
336        !strconcat(asmstr, "\t$rx, $ry"), [], itin> {
337}
338
339class FRRTR16_ins<string asmstr> :
340  MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
341               !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$rz, $$t8"), []> ;
342
343//
344// maybe refactor but need a $zero as a dummy first parameter
345//
346class FRR16_div_ins<bits<5> f, string asmstr, InstrItinClass itin> :
347  FRR16<f, (outs ), (ins CPU16Regs:$rx, CPU16Regs:$ry),
348        !strconcat(asmstr, "\t$$zero, $rx, $ry"), [], itin> ;
349
350class FUnaryRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
351  FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
352        !strconcat(asmstr, "\t$rx, $ry"), [], itin> ;
353
354
355class FRR16_M_ins<bits<5> f, string asmstr,
356                  InstrItinClass itin> :
357  FRR16<f, (outs CPU16Regs:$rx), (ins),
358        !strconcat(asmstr, "\t$rx"), [], itin>;
359
360class FRxRxRy16_ins<bits<5> f, string asmstr,
361                    InstrItinClass itin> :
362  FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
363            !strconcat(asmstr, "\t$rz, $ry"),
364            [], itin> {
365  let Constraints = "$rx = $rz";
366}
367
368let rx=0 in
369class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_,
370                              string asmstr, InstrItinClass itin>:
371  FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t $$ra"),
372              [], itin> ;
373
374
375class FRR16_JALRC_ins<bits<1> nd, bits<1> l, bits<1> ra,
376                      string asmstr, InstrItinClass itin>:
377  FRR16_JALRC<nd, l, ra, (outs), (ins CPU16Regs:$rx),
378              !strconcat(asmstr, "\t $rx"), [], itin> ;
379
380class FRR_SF16_ins
381  <bits<5> _funct, bits<3> _subfunc,
382    string asmstr, InstrItinClass itin>:
383  FRR_SF16<_funct, _subfunc, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_),
384           !strconcat(asmstr, "\t $rx"),
385           [], itin> {
386  let Constraints = "$rx_ = $rx";
387  }
388//
389// RRR-type instruction format
390//
391
392class FRRR16_ins<bits<2> _f, string asmstr,  InstrItinClass itin> :
393  FRRR16<_f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
394         !strconcat(asmstr, "\t$rz, $rx, $ry"), [], itin>;
395
396//
397// These Sel patterns support the generation of conditional move
398// pseudo instructions.
399//
400// The nomenclature uses the components making up the pseudo and may
401// be a bit counter intuitive when compared with the end result we seek.
402// For example using a bqez in the example directly below results in the
403// conditional move being done if the tested register is not zero.
404// I considered in easier to check by keeping the pseudo consistent with
405// it's components but it could have been done differently.
406//
407// The simplest case is when can test and operand directly and do the
408// conditional move based on a simple mips16 conditional
409//  branch instruction.
410// for example:
411// if $op == beqz or bnez:
412//
413// $op1 $rt, .+4
414// move $rd, $rs
415//
416// if $op == beqz, then if $rt != 0, then the conditional assignment
417// $rd = $rs is done.
418
419// if $op == bnez, then if $rt == 0, then the conditional assignment
420// $rd = $rs is done.
421//
422// So this pseudo class only has one operand, i.e. op
423//
424class Sel<string op>:
425  MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs,
426               CPU16Regs:$rt),
427               !strconcat(op, "\t$rt, .+4\n\t\n\tmove $rd, $rs"), []> {
428  //let isCodeGenOnly=1;
429  let Constraints = "$rd = $rd_";
430  let usesCustomInserter = 1;
431}
432
433//
434// The next two instruction classes allow for an operand which tests
435// two operands and returns a value in register T8 and
436//then does a conditional branch based on the value of T8
437//
438
439// op2 can be cmpi or slti/sltiu
440// op1 can bteqz or btnez
441// the operands for op2 are a register and a signed constant
442//
443// $op2 $t, $imm  ;test register t and branch conditionally
444// $op1 .+4       ;op1 is a conditional branch
445// move $rd, $rs
446//
447//
448class SeliT<string op1, string op2>:
449  MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs,
450                                       CPU16Regs:$rl, simm16:$imm),
451               !strconcat(op2,
452               !strconcat("\t$rl, $imm\n\t",
453               !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
454  let isCodeGenOnly=1;
455  let Constraints = "$rd = $rd_";
456  let usesCustomInserter = 1;
457}
458
459//
460// op2 can be cmp or slt/sltu
461// op1 can be bteqz or btnez
462// the operands for op2 are two registers
463// op1 is a conditional branch
464//
465//
466// $op2 $rl, $rr  ;test registers rl,rr
467// $op1 .+4       ;op2 is a conditional branch
468// move $rd, $rs
469//
470//
471class SelT<string op1, string op2>:
472  MipsPseudo16<(outs CPU16Regs:$rd_),
473               (ins CPU16Regs:$rd, CPU16Regs:$rs,
474                CPU16Regs:$rl, CPU16Regs:$rr),
475               !strconcat(op2,
476               !strconcat("\t$rl, $rr\n\t",
477               !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
478  let isCodeGenOnly=1;
479  let Constraints = "$rd = $rd_";
480  let usesCustomInserter = 1;
481}
482
483//
484// 32 bit constant
485//
486def imm32: Operand<i32>;
487
488def Constant32:
489  MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>;
490
491def LwConstant32:
492  MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm, imm32:$constid),
493    "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;
494
495
496//
497// Some general instruction class info
498//
499//
500
501class ArithLogic16Defs<bit isCom=0> {
502  bits<5> shamt = 0;
503  bit isCommutable = isCom;
504  bit isReMaterializable = 1;
505  bit neverHasSideEffects = 1;
506}
507
508class branch16 {
509  bit isBranch = 1;
510  bit isTerminator = 1;
511  bit isBarrier = 1;
512}
513
514class cbranch16 {
515  bit isBranch = 1;
516  bit isTerminator = 1;
517}
518
519class MayLoad {
520  bit mayLoad = 1;
521}
522
523class MayStore {
524  bit mayStore = 1;
525}
526//
527
528
529// Format: ADDIU rx, immediate MIPS16e
530// Purpose: Add Immediate Unsigned Word (2-Operand, Extended)
531// To add a constant to a 32-bit integer.
532//
533def AddiuRxImmX16: FEXT_RI16_ins<0b01001, "addiu", IIAlu>;
534
535def AddiuRxRxImm16: F2RI16_ins<0b01001, "addiu", IIAlu>,
536  ArithLogic16Defs<0> {
537  let AddedComplexity = 5;
538}
539def AddiuRxRxImmX16: FEXT_2RI16_ins<0b01001, "addiu", IIAlu>,
540  ArithLogic16Defs<0> {
541  let isCodeGenOnly = 1;
542}
543
544def AddiuRxRyOffMemX16:
545  FEXT_RRI_A16_mem_ins<0, "addiu", mem16_ea, IIAlu>;
546
547//
548
549// Format: ADDIU rx, pc, immediate MIPS16e
550// Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended)
551// To add a constant to the program counter.
552//
553def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>;
554
555//
556// Format: ADDIU sp, immediate MIPS16e
557// Purpose: Add Immediate Unsigned Word (2-Operand, SP-Relative, Extended)
558// To add a constant to the stack pointer.
559//
560def AddiuSpImm16
561  : FI816_SP_ins<0b011, "addiu", IIAlu> {
562  let Defs = [SP];
563  let Uses = [SP];
564  let AddedComplexity = 5;
565}
566
567def AddiuSpImmX16
568  : FEXT_I816_SP_ins<0b011, "addiu", IIAlu> {
569  let Defs = [SP];
570  let Uses = [SP];
571}
572
573//
574// Format: ADDU rz, rx, ry MIPS16e
575// Purpose: Add Unsigned Word (3-Operand)
576// To add 32-bit integers.
577//
578
579def AdduRxRyRz16: FRRR16_ins<01, "addu", IIAlu>, ArithLogic16Defs<1>;
580
581//
582// Format: AND rx, ry MIPS16e
583// Purpose: AND
584// To do a bitwise logical AND.
585
586def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>;
587
588
589//
590// Format: BEQZ rx, offset MIPS16e
591// Purpose: Branch on Equal to Zero
592// To test a GPR then do a PC-relative conditional branch.
593//
594def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16;
595
596
597//
598// Format: BEQZ rx, offset MIPS16e
599// Purpose: Branch on Equal to Zero (Extended)
600// To test a GPR then do a PC-relative conditional branch.
601//
602def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16;
603
604//
605// Format: B offset MIPS16e
606// Purpose: Unconditional Branch (Extended)
607// To do an unconditional PC-relative branch.
608//
609
610def Bimm16: FI16_ins<0b00010, "b", IIAlu>, branch16;
611
612// Format: B offset MIPS16e
613// Purpose: Unconditional Branch
614// To do an unconditional PC-relative branch.
615//
616def BimmX16: FEXT_I16_ins<0b00010, "b", IIAlu>, branch16;
617
618//
619// Format: BNEZ rx, offset MIPS16e
620// Purpose: Branch on Not Equal to Zero
621// To test a GPR then do a PC-relative conditional branch.
622//
623def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
624
625//
626// Format: BNEZ rx, offset MIPS16e
627// Purpose: Branch on Not Equal to Zero (Extended)
628// To test a GPR then do a PC-relative conditional branch.
629//
630def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
631
632
633//
634//Format: BREAK immediate
635// Purpose: Breakpoint
636// To cause a Breakpoint exception.
637
638def Break16: FRRBreakNull16_ins<"break 0", NoItinerary>; 
639//
640// Format: BTEQZ offset MIPS16e
641// Purpose: Branch on T Equal to Zero (Extended)
642// To test special register T then do a PC-relative conditional branch.
643//
644def Bteqz16: FI816_ins<0b000, "bteqz", IIAlu>, cbranch16 {
645  let Uses = [T8];
646}
647
648def BteqzX16: FEXT_I816_ins<0b000, "bteqz", IIAlu>, cbranch16 {
649  let Uses = [T8];
650}
651
652def BteqzT8CmpX16: FEXT_T8I816_ins<"bteqz", "cmp">, cbranch16;
653
654def BteqzT8CmpiX16: FEXT_T8I8I16_ins<"bteqz", "cmpi">,
655  cbranch16;
656
657def BteqzT8SltX16: FEXT_T8I816_ins<"bteqz", "slt">, cbranch16;
658
659def BteqzT8SltuX16: FEXT_T8I816_ins<"bteqz", "sltu">, cbranch16;
660
661def BteqzT8SltiX16: FEXT_T8I8I16_ins<"bteqz", "slti">, cbranch16;
662
663def BteqzT8SltiuX16: FEXT_T8I8I16_ins<"bteqz", "sltiu">,
664  cbranch16;
665
666//
667// Format: BTNEZ offset MIPS16e
668// Purpose: Branch on T Not Equal to Zero (Extended)
669// To test special register T then do a PC-relative conditional branch.
670//
671
672def Btnez16: FI816_ins<0b001, "btnez", IIAlu>, cbranch16 {
673  let Uses = [T8];
674}
675
676def BtnezX16: FEXT_I816_ins<0b001, "btnez", IIAlu> ,cbranch16 {
677  let Uses = [T8];
678}
679
680def BtnezT8CmpX16: FEXT_T8I816_ins<"btnez", "cmp">, cbranch16;
681
682def BtnezT8CmpiX16: FEXT_T8I8I16_ins<"btnez", "cmpi">, cbranch16;
683
684def BtnezT8SltX16: FEXT_T8I816_ins<"btnez", "slt">, cbranch16;
685
686def BtnezT8SltuX16: FEXT_T8I816_ins<"btnez", "sltu">, cbranch16;
687
688def BtnezT8SltiX16: FEXT_T8I8I16_ins<"btnez", "slti">, cbranch16;
689
690def BtnezT8SltiuX16: FEXT_T8I8I16_ins<"btnez", "sltiu">,
691  cbranch16;
692
693//
694// Format: CMP rx, ry MIPS16e
695// Purpose: Compare
696// To compare the contents of two GPRs.
697//
698def CmpRxRy16: FRR16R_ins<0b01010, "cmp", IIAlu> {
699  let Defs = [T8];
700}
701
702//
703// Format: CMPI rx, immediate MIPS16e
704// Purpose: Compare Immediate
705// To compare a constant with the contents of a GPR.
706//
707def CmpiRxImm16: FRI16R_ins<0b01110, "cmpi", IIAlu> {
708  let Defs = [T8];
709}
710
711//
712// Format: CMPI rx, immediate MIPS16e
713// Purpose: Compare Immediate (Extended)
714// To compare a constant with the contents of a GPR.
715//
716def CmpiRxImmX16: FEXT_RI16R_ins<0b01110, "cmpi", IIAlu> {
717  let Defs = [T8];
718}
719
720
721//
722// Format: DIV rx, ry MIPS16e
723// Purpose: Divide Word
724// To divide 32-bit signed integers.
725//
726def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> {
727  let Defs = [HI0, LO0];
728}
729
730//
731// Format: DIVU rx, ry MIPS16e
732// Purpose: Divide Unsigned Word
733// To divide 32-bit unsigned integers.
734//
735def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> {
736  let Defs = [HI0, LO0];
737}
738//
739// Format: JAL target MIPS16e
740// Purpose: Jump and Link
741// To execute a procedure call within the current 256 MB-aligned
742// region and preserve the current ISA.
743//
744
745def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> {
746  let hasDelaySlot = 0;  // not true, but we add the nop for now
747  let isCall=1;
748  let Defs = [RA];
749}
750
751def JalB16 : FJALB16_ins<0b0, "jal", IIAlu>, branch16 {
752  let hasDelaySlot = 0;  // not true, but we add the nop for now
753  let isBranch=1;
754  let Defs = [RA];
755}
756
757//
758// Format: JR ra MIPS16e
759// Purpose: Jump Register Through Register ra
760// To execute a branch to the instruction address in the return
761// address register.
762//
763
764def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIAlu> {
765  let isBranch = 1;
766  let isIndirectBranch = 1;
767  let hasDelaySlot = 1;
768  let isTerminator=1;
769  let isBarrier=1;
770}
771
772def JrcRa16: FRR16_JALRC_RA_only_ins<1, 1, "jrc", IIAlu> {
773  let isBranch = 1;
774  let isIndirectBranch = 1;
775  let isTerminator=1;
776  let isBarrier=1;
777}
778
779def JrcRx16: FRR16_JALRC_ins<1, 1, 0, "jrc", IIAlu> {
780  let isBranch = 1;
781  let isIndirectBranch = 1;
782  let isTerminator=1;
783  let isBarrier=1;
784}
785//
786// Format: LB ry, offset(rx) MIPS16e
787// Purpose: Load Byte (Extended)
788// To load a byte from memory as a signed value.
789//
790def LbRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lb", mem16, II_LB>, MayLoad{
791  let isCodeGenOnly = 1;
792}
793
794//
795// Format: LBU ry, offset(rx) MIPS16e
796// Purpose: Load Byte Unsigned (Extended)
797// To load a byte from memory as a unsigned value.
798//
799def LbuRxRyOffMemX16:
800  FEXT_RRI16_mem_ins<0b10100, "lbu", mem16, II_LBU>, MayLoad {
801  let isCodeGenOnly = 1;
802}
803
804//
805// Format: LH ry, offset(rx) MIPS16e
806// Purpose: Load Halfword signed (Extended)
807// To load a halfword from memory as a signed value.
808//
809def LhRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lh", mem16, II_LH>, MayLoad{
810  let isCodeGenOnly = 1;
811}
812
813//
814// Format: LHU ry, offset(rx) MIPS16e
815// Purpose: Load Halfword unsigned (Extended)
816// To load a halfword from memory as an unsigned value.
817//
818def LhuRxRyOffMemX16:
819  FEXT_RRI16_mem_ins<0b10100, "lhu", mem16, II_LHU>, MayLoad {
820  let isCodeGenOnly = 1;
821}
822
823//
824// Format: LI rx, immediate MIPS16e
825// Purpose: Load Immediate
826// To load a constant into a GPR.
827//
828def LiRxImm16: FRI16_ins<0b01101, "li", IIAlu>;
829
830//
831// Format: LI rx, immediate MIPS16e
832// Purpose: Load Immediate (Extended)
833// To load a constant into a GPR.
834//
835def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>;
836
837def LiRxImmAlignX16: FEXT_RI16_ins<0b01101, ".align 2\n\tli", IIAlu> {
838  let isCodeGenOnly = 1;
839}
840
841//
842// Format: LW ry, offset(rx) MIPS16e
843// Purpose: Load Word (Extended)
844// To load a word from memory as a signed value.
845//
846def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, II_LW>, MayLoad{
847  let isCodeGenOnly = 1;
848}
849
850// Format: LW rx, offset(sp) MIPS16e
851// Purpose: Load Word (SP-Relative, Extended)
852// To load an SP-relative word from memory as a signed value.
853//
854def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10010, "lw", II_LW>, MayLoad{
855  let Uses = [SP];
856}
857
858def LwRxPcTcp16: FRI16_TCP_ins<0b10110, "lw", II_LW>, MayLoad;
859
860def LwRxPcTcpX16: FEXT_RI16_TCP_ins<0b10110, "lw", II_LW>, MayLoad;
861//
862// Format: MOVE r32, rz MIPS16e
863// Purpose: Move
864// To move the contents of a GPR to a GPR.
865//
866def Move32R16: FI8_MOV32R16_ins<"move", IIAlu>;
867
868//
869// Format: MOVE ry, r32 MIPS16e
870//Purpose: Move
871// To move the contents of a GPR to a GPR.
872//
873def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>;
874
875//
876// Format: MFHI rx MIPS16e
877// Purpose: Move From HI Register
878// To copy the special purpose HI register to a GPR.
879//
880def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> {
881  let Uses = [HI0];
882  let neverHasSideEffects = 1;
883}
884
885//
886// Format: MFLO rx MIPS16e
887// Purpose: Move From LO Register
888// To copy the special purpose LO register to a GPR.
889//
890def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> {
891  let Uses = [LO0];
892  let neverHasSideEffects = 1;
893}
894
895//
896// Pseudo Instruction for mult
897//
898def MultRxRy16:  FMULT16_ins<"mult",  IIAlu> {
899  let isCommutable = 1;
900  let neverHasSideEffects = 1;
901  let Defs = [HI0, LO0];
902}
903
904def MultuRxRy16: FMULT16_ins<"multu", IIAlu> {
905  let isCommutable = 1;
906  let neverHasSideEffects = 1;
907  let Defs = [HI0, LO0];
908}
909
910//
911// Format: MULT rx, ry MIPS16e
912// Purpose: Multiply Word
913// To multiply 32-bit signed integers.
914//
915def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> {
916  let isCommutable = 1;
917  let neverHasSideEffects = 1;
918  let Defs = [HI0, LO0];
919}
920
921//
922// Format: MULTU rx, ry MIPS16e
923// Purpose: Multiply Unsigned Word
924// To multiply 32-bit unsigned integers.
925//
926def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> {
927  let isCommutable = 1;
928  let neverHasSideEffects = 1;
929  let Defs = [HI0, LO0];
930}
931
932//
933// Format: NEG rx, ry MIPS16e
934// Purpose: Negate
935// To negate an integer value.
936//
937def NegRxRy16: FUnaryRR16_ins<0b11101, "neg", IIAlu>;
938
939//
940// Format: NOT rx, ry MIPS16e
941// Purpose: Not
942// To complement an integer value
943//
944def NotRxRy16: FUnaryRR16_ins<0b01111, "not", IIAlu>;
945
946//
947// Format: OR rx, ry MIPS16e
948// Purpose: Or
949// To do a bitwise logical OR.
950//
951def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>;
952
953//
954// Format: RESTORE {ra,}{s0/s1/s0-1,}{framesize}
955// (All args are optional) MIPS16e
956// Purpose: Restore Registers and Deallocate Stack Frame
957// To deallocate a stack frame before exit from a subroutine,
958// restoring return address and static registers, and adjusting
959// stack
960//
961
962def Restore16:
963  FI8_SVRS16<0b1, (outs), (ins variable_ops),
964             "", [], II_RESTORE >, MayLoad {
965  let isCodeGenOnly = 1;
966  let Defs = [SP];
967  let Uses = [SP];
968}
969
970
971def RestoreX16:
972  FI8_SVRS16<0b1, (outs), (ins variable_ops),
973             "", [], II_RESTORE >, MayLoad {
974  let isCodeGenOnly = 1;
975  let Defs = [SP];
976  let Uses = [SP];
977}
978
979//
980// Format: SAVE {ra,}{s0/s1/s0-1,}{framesize} (All arguments are optional)
981// MIPS16e
982// Purpose: Save Registers and Set Up Stack Frame
983// To set up a stack frame on entry to a subroutine,
984// saving return address and static registers, and adjusting stack
985//
986def Save16: 
987  FI8_SVRS16<0b1, (outs), (ins variable_ops),
988             "", [], II_SAVE >, MayStore {
989  let isCodeGenOnly = 1;
990  let Uses = [SP];
991  let Defs = [SP];
992}
993
994def SaveX16:
995  FI8_SVRS16<0b1, (outs), (ins variable_ops),
996             "", [], II_SAVE >, MayStore {
997  let isCodeGenOnly = 1;
998  let Uses = [SP];
999  let Defs = [SP];
1000}
1001//
1002// Format: SB ry, offset(rx) MIPS16e
1003// Purpose: Store Byte (Extended)
1004// To store a byte to memory.
1005//
1006def SbRxRyOffMemX16:
1007  FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, II_SB>, MayStore;
1008
1009//
1010// Format: SEB rx MIPS16e
1011// Purpose: Sign-Extend Byte
1012// Sign-extend least significant byte in register rx.
1013//
1014def SebRx16
1015  : FRR_SF16_ins<0b10001, 0b100, "seb", IIAlu>;
1016
1017//
1018// Format: SEH rx MIPS16e
1019// Purpose: Sign-Extend Halfword
1020// Sign-extend least significant word in register rx.
1021//
1022def SehRx16
1023  : FRR_SF16_ins<0b10001, 0b101, "seh", IIAlu>;
1024
1025//
1026// The Sel(T) instructions are pseudos
1027// T means that they use T8 implicitly.
1028//
1029//
1030// Format: SelBeqZ rd, rs, rt
1031// Purpose: if rt==0, do nothing
1032//          else rs = rt
1033//
1034def SelBeqZ: Sel<"beqz">;
1035
1036//
1037// Format:  SelTBteqZCmp rd, rs, rl, rr
1038// Purpose: b = Cmp rl, rr.
1039//          If b==0 then do nothing.
1040//          if b!=0 then rd = rs
1041//
1042def SelTBteqZCmp: SelT<"bteqz", "cmp">;
1043
1044//
1045// Format:  SelTBteqZCmpi rd, rs, rl, rr
1046// Purpose: b = Cmpi rl, imm.
1047//          If b==0 then do nothing.
1048//          if b!=0 then rd = rs
1049//
1050def SelTBteqZCmpi: SeliT<"bteqz", "cmpi">;
1051
1052//
1053// Format:  SelTBteqZSlt rd, rs, rl, rr
1054// Purpose: b = Slt rl, rr.
1055//          If b==0 then do nothing.
1056//          if b!=0 then rd = rs
1057//
1058def SelTBteqZSlt: SelT<"bteqz", "slt">;
1059
1060//
1061// Format:  SelTBteqZSlti rd, rs, rl, rr
1062// Purpose: b = Slti rl, imm.
1063//          If b==0 then do nothing.
1064//          if b!=0 then rd = rs
1065//
1066def SelTBteqZSlti: SeliT<"bteqz", "slti">;
1067
1068//
1069// Format:  SelTBteqZSltu rd, rs, rl, rr
1070// Purpose: b = Sltu rl, rr.
1071//          If b==0 then do nothing.
1072//          if b!=0 then rd = rs
1073//
1074def SelTBteqZSltu: SelT<"bteqz", "sltu">;
1075
1076//
1077// Format:  SelTBteqZSltiu rd, rs, rl, rr
1078// Purpose: b = Sltiu rl, imm.
1079//          If b==0 then do nothing.
1080//          if b!=0 then rd = rs
1081//
1082def SelTBteqZSltiu: SeliT<"bteqz", "sltiu">;
1083
1084//
1085// Format: SelBnez rd, rs, rt
1086// Purpose: if rt!=0, do nothing
1087//          else rs = rt
1088//
1089def SelBneZ: Sel<"bnez">;
1090
1091//
1092// Format:  SelTBtneZCmp rd, rs, rl, rr
1093// Purpose: b = Cmp rl, rr.
1094//          If b!=0 then do nothing.
1095//          if b0=0 then rd = rs
1096//
1097def SelTBtneZCmp: SelT<"btnez", "cmp">;
1098
1099//
1100// Format:  SelTBtnezCmpi rd, rs, rl, rr
1101// Purpose: b = Cmpi rl, imm.
1102//          If b!=0 then do nothing.
1103//          if b==0 then rd = rs
1104//
1105def SelTBtneZCmpi: SeliT<"btnez", "cmpi">;
1106
1107//
1108// Format:  SelTBtneZSlt rd, rs, rl, rr
1109// Purpose: b = Slt rl, rr.
1110//          If b!=0 then do nothing.
1111//          if b==0 then rd = rs
1112//
1113def SelTBtneZSlt: SelT<"btnez", "slt">;
1114
1115//
1116// Format:  SelTBtneZSlti rd, rs, rl, rr
1117// Purpose: b = Slti rl, imm.
1118//          If b!=0 then do nothing.
1119//          if b==0 then rd = rs
1120//
1121def SelTBtneZSlti: SeliT<"btnez", "slti">;
1122
1123//
1124// Format:  SelTBtneZSltu rd, rs, rl, rr
1125// Purpose: b = Sltu rl, rr.
1126//          If b!=0 then do nothing.
1127//          if b==0 then rd = rs
1128//
1129def SelTBtneZSltu: SelT<"btnez", "sltu">;
1130
1131//
1132// Format:  SelTBtneZSltiu rd, rs, rl, rr
1133// Purpose: b = Slti rl, imm.
1134//          If b!=0 then do nothing.
1135//          if b==0 then rd = rs
1136//
1137def SelTBtneZSltiu: SeliT<"btnez", "sltiu">;
1138//
1139//
1140// Format: SH ry, offset(rx) MIPS16e
1141// Purpose: Store Halfword (Extended)
1142// To store a halfword to memory.
1143//
1144def ShRxRyOffMemX16:
1145  FEXT_RRI16_mem2_ins<0b11001, "sh", mem16, II_SH>, MayStore;
1146
1147//
1148// Format: SLL rx, ry, sa MIPS16e
1149// Purpose: Shift Word Left Logical (Extended)
1150// To execute a left-shift of a word by a fixed number of bits-0 to 31 bits.
1151//
1152def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>;
1153
1154//
1155// Format: SLLV ry, rx MIPS16e
1156// Purpose: Shift Word Left Logical Variable
1157// To execute a left-shift of a word by a variable number of bits.
1158//
1159def SllvRxRy16 : FRxRxRy16_ins<0b00100, "sllv", IIAlu>;
1160
1161// Format: SLTI rx, immediate MIPS16e
1162// Purpose: Set on Less Than Immediate
1163// To record the result of a less-than comparison with a constant.
1164//
1165//
1166def SltiRxImm16: FRI16R_ins<0b01010, "slti", IIAlu> {
1167  let Defs = [T8];
1168}
1169
1170//
1171// Format: SLTI rx, immediate MIPS16e
1172// Purpose: Set on Less Than Immediate (Extended)
1173// To record the result of a less-than comparison with a constant.
1174//
1175//
1176def SltiRxImmX16: FEXT_RI16R_ins<0b01010, "slti", IIAlu> {
1177  let Defs = [T8];
1178}
1179
1180def SltiCCRxImmX16: FEXT_CCRXI16_ins<"slti">;
1181
1182// Format: SLTIU rx, immediate MIPS16e
1183// Purpose: Set on Less Than Immediate Unsigned
1184// To record the result of a less-than comparison with a constant.
1185//
1186//
1187def SltiuRxImm16: FRI16R_ins<0b01011, "sltiu", IIAlu> {
1188  let Defs = [T8];
1189}
1190
1191//
1192// Format: SLTI rx, immediate MIPS16e
1193// Purpose: Set on Less Than Immediate Unsigned (Extended)
1194// To record the result of a less-than comparison with a constant.
1195//
1196//
1197def SltiuRxImmX16: FEXT_RI16R_ins<0b01011, "sltiu", IIAlu> {
1198  let Defs = [T8];
1199}
1200//
1201// Format: SLTIU rx, immediate MIPS16e
1202// Purpose: Set on Less Than Immediate Unsigned (Extended)
1203// To record the result of a less-than comparison with a constant.
1204//
1205def SltiuCCRxImmX16: FEXT_CCRXI16_ins<"sltiu">;
1206
1207//
1208// Format: SLT rx, ry MIPS16e
1209// Purpose: Set on Less Than
1210// To record the result of a less-than comparison.
1211//
1212def SltRxRy16: FRR16R_ins<0b00010, "slt", IIAlu>{
1213  let Defs = [T8];
1214}
1215
1216def SltCCRxRy16: FCCRR16_ins<"slt">;
1217
1218// Format: SLTU rx, ry MIPS16e
1219// Purpose: Set on Less Than Unsigned
1220// To record the result of an unsigned less-than comparison.
1221//
1222def SltuRxRy16: FRR16R_ins<0b00011, "sltu", IIAlu>{
1223  let Defs = [T8];
1224}
1225
1226def SltuRxRyRz16: FRRTR16_ins<"sltu"> {
1227  let isCodeGenOnly=1;
1228  let Defs = [T8];
1229}
1230
1231
1232def SltuCCRxRy16: FCCRR16_ins<"sltu">;
1233//
1234// Format: SRAV ry, rx MIPS16e
1235// Purpose: Shift Word Right Arithmetic Variable
1236// To execute an arithmetic right-shift of a word by a variable
1237// number of bits.
1238//
1239def SravRxRy16: FRxRxRy16_ins<0b00111, "srav", IIAlu>;
1240
1241
1242//
1243// Format: SRA rx, ry, sa MIPS16e
1244// Purpose: Shift Word Right Arithmetic (Extended)
1245// To execute an arithmetic right-shift of a word by a fixed
1246// number of bits-1 to 8 bits.
1247//
1248def SraX16: FEXT_SHIFT16_ins<0b11, "sra", IIAlu>;
1249
1250
1251//
1252// Format: SRLV ry, rx MIPS16e
1253// Purpose: Shift Word Right Logical Variable
1254// To execute a logical right-shift of a word by a variable
1255// number of bits.
1256//
1257def SrlvRxRy16: FRxRxRy16_ins<0b00110, "srlv", IIAlu>;
1258
1259
1260//
1261// Format: SRL rx, ry, sa MIPS16e
1262// Purpose: Shift Word Right Logical (Extended)
1263// To execute a logical right-shift of a word by a fixed
1264// number of bits-1 to 31 bits.
1265//
1266def SrlX16: FEXT_SHIFT16_ins<0b10, "srl", IIAlu>;
1267
1268//
1269// Format: SUBU rz, rx, ry MIPS16e
1270// Purpose: Subtract Unsigned Word
1271// To subtract 32-bit integers
1272//
1273def SubuRxRyRz16: FRRR16_ins<0b11, "subu", IIAlu>, ArithLogic16Defs<0>;
1274
1275//
1276// Format: SW ry, offset(rx) MIPS16e
1277// Purpose: Store Word (Extended)
1278// To store a word to memory.
1279//
1280def SwRxRyOffMemX16:
1281  FEXT_RRI16_mem2_ins<0b11011, "sw", mem16, II_SW>, MayStore;
1282
1283//
1284// Format: SW rx, offset(sp) MIPS16e
1285// Purpose: Store Word rx (SP-Relative)
1286// To store an SP-relative word to memory.
1287//
1288def SwRxSpImmX16: FEXT_RI16_SP_Store_explicit_ins
1289  <0b11010, "sw", II_SW>, MayStore;
1290
1291//
1292//
1293// Format: XOR rx, ry MIPS16e
1294// Purpose: Xor
1295// To do a bitwise logical XOR.
1296//
1297def XorRxRxRy16: FRxRxRy16_ins<0b01110, "xor", IIAlu>, ArithLogic16Defs<1>;
1298
1299class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> {
1300  let Predicates = [InMips16Mode];
1301}
1302
1303// Unary Arith/Logic
1304//
1305class ArithLogicU_pat<PatFrag OpNode, Instruction I> :
1306  Mips16Pat<(OpNode CPU16Regs:$r),
1307            (I CPU16Regs:$r)>;
1308
1309def: ArithLogicU_pat<not, NotRxRy16>;
1310def: ArithLogicU_pat<ineg, NegRxRy16>;
1311
1312class ArithLogic16_pat<SDNode OpNode, Instruction I> :
1313  Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r),
1314            (I CPU16Regs:$l, CPU16Regs:$r)>;
1315
1316def: ArithLogic16_pat<add, AdduRxRyRz16>;
1317def: ArithLogic16_pat<and, AndRxRxRy16>;
1318def: ArithLogic16_pat<mul, MultRxRyRz16>;
1319def: ArithLogic16_pat<or, OrRxRxRy16>;
1320def: ArithLogic16_pat<sub, SubuRxRyRz16>;
1321def: ArithLogic16_pat<xor, XorRxRxRy16>;
1322
1323// Arithmetic and logical instructions with 2 register operands.
1324
1325class ArithLogicI16_pat<SDNode OpNode, PatFrag imm_type, Instruction I> :
1326  Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm),
1327            (I CPU16Regs:$in, imm_type:$imm)>;
1328
1329def: ArithLogicI16_pat<add, immSExt8, AddiuRxRxImm16>;
1330def: ArithLogicI16_pat<add, immSExt16, AddiuRxRxImmX16>;
1331def: ArithLogicI16_pat<shl, immZExt5, SllX16>;
1332def: ArithLogicI16_pat<srl, immZExt5, SrlX16>;
1333def: ArithLogicI16_pat<sra, immZExt5, SraX16>;
1334
1335class shift_rotate_reg16_pat<SDNode OpNode, Instruction I> :
1336  Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra),
1337            (I CPU16Regs:$r, CPU16Regs:$ra)>;
1338
1339def: shift_rotate_reg16_pat<shl, SllvRxRy16>;
1340def: shift_rotate_reg16_pat<sra, SravRxRy16>;
1341def: shift_rotate_reg16_pat<srl, SrlvRxRy16>;
1342
1343class LoadM16_pat<PatFrag OpNode, Instruction I> :
1344  Mips16Pat<(OpNode addr16:$addr), (I addr16:$addr)>;
1345
1346def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16>;
1347def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16>;
1348def: LoadM16_pat<sextloadi16, LhRxRyOffMemX16>;
1349def: LoadM16_pat<zextloadi16, LhuRxRyOffMemX16>;
1350def: LoadM16_pat<load, LwRxRyOffMemX16>;
1351
1352class StoreM16_pat<PatFrag OpNode, Instruction I> :
1353  Mips16Pat<(OpNode CPU16Regs:$r, addr16:$addr),
1354            (I CPU16Regs:$r, addr16:$addr)>;
1355
1356def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16>;
1357def: StoreM16_pat<truncstorei16, ShRxRyOffMemX16>;
1358def: StoreM16_pat<store, SwRxRyOffMemX16>;
1359
1360// Unconditional branch
1361class UncondBranch16_pat<SDNode OpNode, Instruction I>:
1362  Mips16Pat<(OpNode bb:$imm16), (I bb:$imm16)> {
1363    let Predicates = [InMips16Mode];
1364  }
1365
1366def : Mips16Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1367                (Jal16 tglobaladdr:$dst)>;
1368
1369def : Mips16Pat<(MipsJmpLink (i32 texternalsym:$dst)),
1370                (Jal16 texternalsym:$dst)>;
1371
1372// Indirect branch
1373def: Mips16Pat<(brind CPU16Regs:$rs), (JrcRx16 CPU16Regs:$rs)> {
1374  // Ensure that the addition of MIPS32r6/MIPS64r6 support does not change
1375  // MIPS16's behaviour.
1376  let AddedComplexity = 1;
1377}
1378
1379// Jump and Link (Call)
1380let isCall=1, hasDelaySlot=0 in
1381def JumpLinkReg16:
1382  FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs),
1383              "jalrc \t$rs", [(MipsJmpLink CPU16Regs:$rs)], IIBranch> {
1384  let Defs = [RA];
1385}
1386
1387// Mips16 pseudos
1388let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1,
1389  hasExtraSrcRegAllocReq = 1 in
1390def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>;
1391
1392
1393// setcc patterns
1394
1395class SetCC_R16<PatFrag cond_op, Instruction I>:
1396  Mips16Pat<(cond_op CPU16Regs:$rx, CPU16Regs:$ry),
1397            (I CPU16Regs:$rx, CPU16Regs:$ry)>;
1398
1399class SetCC_I16<PatFrag cond_op, PatLeaf imm_type, Instruction I>:
1400  Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16),
1401            (I CPU16Regs:$rx, imm_type:$imm16)>;
1402
1403
1404def: Mips16Pat<(i32  addr16:$addr),
1405               (AddiuRxRyOffMemX16  addr16:$addr)>;
1406
1407
1408// Large (>16 bit) immediate loads
1409def : Mips16Pat<(i32 imm:$imm), (LwConstant32 imm:$imm, -1)>;
1410
1411// Carry MipsPatterns
1412def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs),
1413                (SubuRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
1414def : Mips16Pat<(addc CPU16Regs:$lhs, CPU16Regs:$rhs),
1415                (AdduRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
1416def : Mips16Pat<(addc  CPU16Regs:$src, immSExt16:$imm),
1417                (AddiuRxRxImmX16 CPU16Regs:$src, imm:$imm)>;
1418
1419//
1420// Some branch conditional patterns are not generated by llvm at this time.
1421// Some are for seemingly arbitrary reasons not used: i.e. with signed number
1422// comparison they are used and for unsigned a different pattern is used.
1423// I am pushing upstream from the full mips16 port and it seemed that I needed
1424// these earlier and the mips32 port has these but now I cannot create test
1425// cases that use these patterns. While I sort this all out I will leave these
1426// extra patterns commented out and if I can be sure they are really not used,
1427// I will delete the code. I don't want to check the code in uncommented without
1428// a valid test case. In some cases, the compiler is generating patterns with
1429// setcc instead and earlier I had implemented setcc first so may have masked
1430// the problem. The setcc variants are suboptimal for mips16 so I may wantto
1431// figure out how to enable the brcond patterns or else possibly new
1432// combinations of of brcond and setcc.
1433//
1434//
1435// bcond-seteq
1436//
1437def: Mips16Pat
1438  <(brcond (i32 (seteq CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1439   (BteqzT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1440  >;
1441
1442
1443def: Mips16Pat
1444  <(brcond (i32 (seteq CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1445   (BteqzT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$targ16)
1446  >;
1447
1448def: Mips16Pat
1449  <(brcond (i32 (seteq CPU16Regs:$rx, 0)), bb:$targ16),
1450   (BeqzRxImm16 CPU16Regs:$rx, bb:$targ16)
1451  >;
1452
1453//
1454// bcond-setgt (do we need to have this pair of setlt, setgt??)
1455//
1456def: Mips16Pat
1457  <(brcond (i32 (setgt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1458   (BtnezT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx,  bb:$imm16)
1459  >;
1460
1461//
1462// bcond-setge
1463//
1464def: Mips16Pat
1465  <(brcond (i32 (setge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1466   (BteqzT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1467  >;
1468
1469//
1470// never called because compiler transforms a >= k to a > (k-1)
1471def: Mips16Pat
1472  <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1473   (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$imm16)
1474  >;
1475
1476//
1477// bcond-setlt
1478//
1479def: Mips16Pat
1480  <(brcond (i32 (setlt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1481   (BtnezT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1482  >;
1483
1484def: Mips16Pat
1485  <(brcond (i32 (setlt CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1486   (BtnezT8SltiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$imm16)
1487  >;
1488
1489//
1490// bcond-setle
1491//
1492def: Mips16Pat
1493  <(brcond (i32 (setle CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1494   (BteqzT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx,  bb:$imm16)
1495  >;
1496
1497//
1498// bcond-setne
1499//
1500def: Mips16Pat
1501  <(brcond (i32 (setne CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1502   (BtnezT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1503  >;
1504
1505def: Mips16Pat
1506  <(brcond (i32 (setne CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1507   (BtnezT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$targ16)
1508  >;
1509
1510def: Mips16Pat
1511  <(brcond (i32 (setne CPU16Regs:$rx, 0)), bb:$targ16),
1512   (BnezRxImm16 CPU16Regs:$rx, bb:$targ16)
1513  >;
1514
1515//
1516// This needs to be there but I forget which code will generate it
1517//
1518def: Mips16Pat
1519  <(brcond CPU16Regs:$rx, bb:$targ16),
1520   (BnezRxImm16 CPU16Regs:$rx, bb:$targ16)
1521  >;
1522
1523//
1524
1525//
1526// bcond-setugt
1527//
1528//def: Mips16Pat
1529//  <(brcond (i32 (setugt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1530//   (BtnezT8SltuX16 CPU16Regs:$ry, CPU16Regs:$rx,  bb:$imm16)
1531//  >;
1532
1533//
1534// bcond-setuge
1535//
1536//def: Mips16Pat
1537//  <(brcond (i32 (setuge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1538//   (BteqzT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1539//  >;
1540
1541
1542//
1543// bcond-setult
1544//
1545//def: Mips16Pat
1546//  <(brcond (i32 (setult CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1547//   (BtnezT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1548//  >;
1549
1550def: UncondBranch16_pat<br, Bimm16>;
1551
1552// Small immediates
1553def: Mips16Pat<(i32 immSExt16:$in),
1554               (AddiuRxRxImmX16 (Move32R16 ZERO), immSExt16:$in)>;
1555
1556def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>;
1557
1558//
1559// MipsDivRem
1560//
1561def: Mips16Pat
1562  <(MipsDivRem16 CPU16Regs:$rx, CPU16Regs:$ry),
1563   (DivRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1564
1565//
1566// MipsDivRemU
1567//
1568def: Mips16Pat
1569  <(MipsDivRemU16 CPU16Regs:$rx, CPU16Regs:$ry),
1570   (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1571
1572//  signed a,b
1573//  x = (a>=b)?x:y
1574//
1575//  if !(a < b) x = y
1576//
1577def : Mips16Pat<(select (i32 (setge CPU16Regs:$a, CPU16Regs:$b)),
1578                 CPU16Regs:$x, CPU16Regs:$y),
1579                (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1580                 CPU16Regs:$a, CPU16Regs:$b)>;
1581
1582//  signed a,b
1583//  x = (a>b)?x:y
1584//
1585//  if  (b < a) x = y
1586//
1587def : Mips16Pat<(select (i32 (setgt CPU16Regs:$a, CPU16Regs:$b)),
1588                 CPU16Regs:$x, CPU16Regs:$y),
1589                (SelTBtneZSlt CPU16Regs:$x, CPU16Regs:$y,
1590                 CPU16Regs:$b, CPU16Regs:$a)>;
1591
1592// unsigned a,b
1593// x = (a>=b)?x:y
1594//
1595// if !(a < b) x = y;
1596//
1597def : Mips16Pat<
1598  (select (i32 (setuge CPU16Regs:$a, CPU16Regs:$b)),
1599   CPU16Regs:$x, CPU16Regs:$y),
1600  (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1601   CPU16Regs:$a, CPU16Regs:$b)>;
1602
1603//  unsigned a,b
1604//  x = (a>b)?x:y
1605//
1606//  if (b < a) x = y
1607//
1608def : Mips16Pat<(select (i32 (setugt CPU16Regs:$a, CPU16Regs:$b)),
1609                 CPU16Regs:$x, CPU16Regs:$y),
1610                (SelTBtneZSltu CPU16Regs:$x, CPU16Regs:$y,
1611                 CPU16Regs:$b, CPU16Regs:$a)>;
1612
1613// signed
1614// x = (a >= k)?x:y
1615// due to an llvm optimization, i don't think that this will ever
1616// be used. This is transformed into x = (a > k-1)?x:y
1617//
1618//
1619
1620//def : Mips16Pat<
1621//  (select (i32 (setge CPU16Regs:$lhs, immSExt16:$rhs)),
1622//   CPU16Regs:$T, CPU16Regs:$F),
1623//  (SelTBteqZSlti CPU16Regs:$T, CPU16Regs:$F,
1624//   CPU16Regs:$lhs, immSExt16:$rhs)>;
1625
1626//def : Mips16Pat<
1627//  (select (i32 (setuge CPU16Regs:$lhs, immSExt16:$rhs)),
1628//   CPU16Regs:$T, CPU16Regs:$F),
1629//  (SelTBteqZSltiu CPU16Regs:$T, CPU16Regs:$F,
1630//   CPU16Regs:$lhs, immSExt16:$rhs)>;
1631
1632// signed
1633// x = (a < k)?x:y
1634//
1635// if !(a < k) x = y;
1636//
1637def : Mips16Pat<
1638  (select (i32 (setlt CPU16Regs:$a, immSExt16:$b)),
1639   CPU16Regs:$x, CPU16Regs:$y),
1640  (SelTBtneZSlti CPU16Regs:$x, CPU16Regs:$y,
1641   CPU16Regs:$a, immSExt16:$b)>;
1642
1643
1644//
1645//
1646// signed
1647// x = (a <= b)? x : y
1648//
1649// if  (b < a) x = y
1650//
1651def : Mips16Pat<(select (i32 (setle CPU16Regs:$a, CPU16Regs:$b)),
1652                 CPU16Regs:$x, CPU16Regs:$y),
1653                (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1654                 CPU16Regs:$b, CPU16Regs:$a)>;
1655
1656//
1657// unnsigned
1658// x = (a <= b)? x : y
1659//
1660// if  (b < a) x = y
1661//
1662def : Mips16Pat<(select (i32 (setule CPU16Regs:$a, CPU16Regs:$b)),
1663                 CPU16Regs:$x, CPU16Regs:$y),
1664                (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1665                 CPU16Regs:$b, CPU16Regs:$a)>;
1666
1667//
1668// signed/unsigned
1669// x = (a == b)? x : y
1670//
1671// if (a != b) x = y
1672//
1673def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, CPU16Regs:$b)),
1674                 CPU16Regs:$x, CPU16Regs:$y),
1675                (SelTBteqZCmp CPU16Regs:$x, CPU16Regs:$y,
1676                 CPU16Regs:$b, CPU16Regs:$a)>;
1677
1678//
1679// signed/unsigned
1680// x = (a == 0)? x : y
1681//
1682// if (a != 0) x = y
1683//
1684def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, 0)),
1685                 CPU16Regs:$x, CPU16Regs:$y),
1686                (SelBeqZ CPU16Regs:$x, CPU16Regs:$y,
1687                 CPU16Regs:$a)>;
1688
1689
1690//
1691// signed/unsigned
1692// x = (a == k)? x : y
1693//
1694// if (a != k) x = y
1695//
1696def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, immZExt16:$k)),
1697                 CPU16Regs:$x, CPU16Regs:$y),
1698                (SelTBteqZCmpi CPU16Regs:$x, CPU16Regs:$y,
1699                 CPU16Regs:$a, immZExt16:$k)>;
1700
1701
1702//
1703// signed/unsigned
1704// x = (a != b)? x : y
1705//
1706// if (a == b) x = y
1707//
1708//
1709def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, CPU16Regs:$b)),
1710                 CPU16Regs:$x, CPU16Regs:$y),
1711                (SelTBtneZCmp CPU16Regs:$x, CPU16Regs:$y,
1712                 CPU16Regs:$b, CPU16Regs:$a)>;
1713
1714//
1715// signed/unsigned
1716// x = (a != 0)? x : y
1717//
1718// if (a == 0) x = y
1719//
1720def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, 0)),
1721                 CPU16Regs:$x, CPU16Regs:$y),
1722                (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1723                 CPU16Regs:$a)>;
1724
1725// signed/unsigned
1726// x = (a)? x : y
1727//
1728// if (!a) x = y
1729//
1730def : Mips16Pat<(select  CPU16Regs:$a,
1731                 CPU16Regs:$x, CPU16Regs:$y),
1732      (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1733       CPU16Regs:$a)>;
1734
1735
1736//
1737// signed/unsigned
1738// x = (a != k)? x : y
1739//
1740// if (a == k) x = y
1741//
1742def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, immZExt16:$k)),
1743                 CPU16Regs:$x, CPU16Regs:$y),
1744                (SelTBtneZCmpi CPU16Regs:$x, CPU16Regs:$y,
1745                 CPU16Regs:$a, immZExt16:$k)>;
1746
1747//
1748// When writing C code to test setxx these patterns,
1749// some will be transformed into
1750// other things. So we test using C code but using -O3 and -O0
1751//
1752// seteq
1753//
1754def : Mips16Pat
1755  <(seteq CPU16Regs:$lhs,CPU16Regs:$rhs),
1756   (SltiuCCRxImmX16 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1)>;
1757
1758def : Mips16Pat
1759  <(seteq CPU16Regs:$lhs, 0),
1760   (SltiuCCRxImmX16 CPU16Regs:$lhs, 1)>;
1761
1762
1763//
1764// setge
1765//
1766
1767def: Mips16Pat
1768  <(setge CPU16Regs:$lhs, CPU16Regs:$rhs),
1769   (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1770   (LiRxImmX16 1))>;
1771
1772//
1773// For constants, llvm transforms this to:
1774// x > (k -1) and then reverses the operands to use setlt. So this pattern
1775// is not used now by the compiler. (Presumably checking that k-1 does not
1776// overflow). The compiler never uses this at a the current time, due to
1777// other optimizations.
1778//
1779//def: Mips16Pat
1780//  <(setge CPU16Regs:$lhs, immSExt16:$rhs),
1781//   (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs),
1782//   (LiRxImmX16 1))>;
1783
1784// This catches the x >= -32768 case by transforming it to  x > -32769
1785//
1786def: Mips16Pat
1787  <(setgt CPU16Regs:$lhs, -32769),
1788   (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768),
1789   (LiRxImmX16 1))>;
1790
1791//
1792// setgt
1793//
1794//
1795
1796def: Mips16Pat
1797  <(setgt CPU16Regs:$lhs, CPU16Regs:$rhs),
1798   (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1799
1800//
1801// setle
1802//
1803def: Mips16Pat
1804  <(setle CPU16Regs:$lhs, CPU16Regs:$rhs),
1805   (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImm16 1))>;
1806
1807//
1808// setlt
1809//
1810def: SetCC_R16<setlt, SltCCRxRy16>;
1811
1812def: SetCC_I16<setlt, immSExt16, SltiCCRxImmX16>;
1813
1814//
1815// setne
1816//
1817def : Mips16Pat
1818  <(setne CPU16Regs:$lhs,CPU16Regs:$rhs),
1819   (SltuCCRxRy16 (LiRxImmX16 0),
1820   (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs))>;
1821
1822
1823//
1824// setuge
1825//
1826def: Mips16Pat
1827  <(setuge CPU16Regs:$lhs, CPU16Regs:$rhs),
1828   (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1829   (LiRxImmX16 1))>;
1830
1831// this pattern will never be used because the compiler will transform
1832// x >= k to x > (k - 1) and then use SLT
1833//
1834//def: Mips16Pat
1835//  <(setuge CPU16Regs:$lhs, immZExt16:$rhs),
1836//   (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs),
1837//   (LiRxImmX16 1))>;
1838
1839//
1840// setugt
1841//
1842def: Mips16Pat
1843  <(setugt CPU16Regs:$lhs, CPU16Regs:$rhs),
1844   (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1845
1846//
1847// setule
1848//
1849def: Mips16Pat
1850  <(setule CPU16Regs:$lhs, CPU16Regs:$rhs),
1851   (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>;
1852
1853//
1854// setult
1855//
1856def: SetCC_R16<setult, SltuCCRxRy16>;
1857
1858def: SetCC_I16<setult, immSExt16, SltiuCCRxImmX16>;
1859
1860def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)),
1861               (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>;
1862
1863// hi/lo relocs
1864def : Mips16Pat<(MipsHi tblockaddress:$in),
1865                (SllX16 (LiRxImmX16 tblockaddress:$in), 16)>;
1866def : Mips16Pat<(MipsHi tglobaladdr:$in),
1867                (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>;
1868def : Mips16Pat<(MipsHi tjumptable:$in),
1869                (SllX16 (LiRxImmX16 tjumptable:$in), 16)>;
1870def : Mips16Pat<(MipsHi tglobaltlsaddr:$in),
1871                (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>;
1872
1873def : Mips16Pat<(MipsLo tblockaddress:$in), (LiRxImmX16 tblockaddress:$in)>;
1874
1875// wrapper_pic
1876class Wrapper16Pat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1877  Mips16Pat<(MipsWrapper RC:$gp, node:$in),
1878            (ADDiuOp RC:$gp, node:$in)>;
1879
1880
1881def : Wrapper16Pat<tglobaladdr, AddiuRxRxImmX16, CPU16Regs>;
1882def : Wrapper16Pat<tglobaltlsaddr, AddiuRxRxImmX16, CPU16Regs>;
1883
1884def : Mips16Pat<(i32 (extloadi8   addr16:$src)),
1885                (LbuRxRyOffMemX16  addr16:$src)>;
1886def : Mips16Pat<(i32 (extloadi16  addr16:$src)),
1887                (LhuRxRyOffMemX16  addr16:$src)>;
1888
1889def: Mips16Pat<(trap), (Break16)>;
1890
1891def : Mips16Pat<(sext_inreg CPU16Regs:$val, i8),
1892                (SebRx16 CPU16Regs:$val)>;
1893
1894def : Mips16Pat<(sext_inreg CPU16Regs:$val, i16),
1895                (SehRx16 CPU16Regs:$val)>;
1896
1897def GotPrologue16:   
1898  MipsPseudo16<
1899    (outs CPU16Regs:$rh, CPU16Regs:$rl),
1900    (ins simm16:$immHi, simm16:$immLo),
1901    "li\t$rh, $immHi\n\taddiu\t$rl, $$pc, $immLo\n ",[]> ;
1902
1903// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
1904def cpinst_operand : Operand<i32> {
1905  // let PrintMethod = "printCPInstOperand";
1906}
1907
1908// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1909// the function.  The first operand is the ID# for this instruction, the second
1910// is the index into the MachineConstantPool that this is, the third is the
1911// size in bytes of this constant pool entry.
1912//
1913let neverHasSideEffects = 1, isNotDuplicable = 1 in
1914def CONSTPOOL_ENTRY :
1915MipsPseudo16<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1916                      i32imm:$size), "foo", []>;
1917
1918