Mips16InstrInfo.td revision 360784
1//===- Mips16InstrInfo.td - Target Description for Mips16  -*- tablegen -*-=//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes Mips16 instructions.
10//
11//===----------------------------------------------------------------------===//
12//
13//
14// Mips Address
15//
16def addr16 : ComplexPattern<iPTR, 2, "selectAddr16", [frameindex]>;
17def addr16sp : ComplexPattern<iPTR, 2, "selectAddr16SP", [frameindex]>;
18
19//
20// Address operand
21def mem16 : Operand<i32> {
22  let PrintMethod = "printMemOperand";
23  let MIOperandInfo = (ops CPU16Regs, simm16);
24  let EncoderMethod = "getMemEncoding";
25}
26
27def mem16sp : Operand<i32> {
28  let PrintMethod = "printMemOperand";
29  // This should be CPUSPReg but the MIPS16 subtarget isn't good enough at
30  // keeping the sp-relative load and the other varieties separate at the
31  // moment. This lie fixes the problem sufficiently well to fix the errors
32  // emitted by -verify-machineinstrs and the output ends up correct as long
33  // as we use an external assembler (which is already a requirement for MIPS16
34  // for several other reasons).
35  let MIOperandInfo = (ops CPU16RegsPlusSP, simm16);
36  let EncoderMethod = "getMemEncoding";
37}
38
39def mem16_ea : Operand<i32> {
40  let PrintMethod = "printMemOperandEA";
41  let MIOperandInfo = (ops CPU16RegsPlusSP, simm16);
42  let EncoderMethod = "getMemEncoding";
43}
44
45def pcrel16 : Operand<i32>;
46
47//
48// I-type instruction format
49//
50// this is only used by bimm. the actual assembly value is a 12 bit signed
51// number
52//
53class FI16_ins<bits<5> op, string asmstr, InstrItinClass itin>:
54  FI16<op, (outs), (ins brtarget:$imm16),
55            !strconcat(asmstr, "\t$imm16 # 16 bit inst"), [], itin>;
56
57//
58//
59// I8 instruction format
60//
61
62class FI816_ins_base<bits<3> _func, string asmstr,
63                     string asmstr2, InstrItinClass itin>:
64  FI816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
65        [], itin>;
66
67class FI816_ins<bits<3> _func, string asmstr,
68                InstrItinClass itin>:
69  FI816_ins_base<_func, asmstr, "\t$imm  # 16 bit inst", itin>;
70
71class FI816_SP_ins<bits<3> _func, string asmstr,
72                   InstrItinClass itin>:
73  FI816_ins_base<_func, asmstr, "\t$$sp, $imm # 16 bit inst", itin>;
74
75//
76// RI instruction format
77//
78
79
80class FRI16_ins_base<bits<5> op, string asmstr, string asmstr2,
81                     InstrItinClass itin>:
82  FRI16<op, (outs CPU16Regs:$rx), (ins simm16:$imm),
83        !strconcat(asmstr, asmstr2), [], itin>;
84
85class FRI16_ins<bits<5> op, string asmstr,
86                InstrItinClass itin>:
87  FRI16_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;
88
89class FRI16_TCP_ins<bits<5> _op, string asmstr,
90                    InstrItinClass itin>:
91  FRI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),
92            !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin>;
93
94class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2,
95                     InstrItinClass itin>:
96  FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm),
97        !strconcat(asmstr, asmstr2), [], itin>;
98
99class FRI16R_ins<bits<5> op, string asmstr,
100                InstrItinClass itin>:
101  FRI16R_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;
102
103class F2RI16_ins<bits<5> _op, string asmstr,
104                     InstrItinClass itin>:
105  FRI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
106        !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin> {
107  let Constraints = "$rx_ = $rx";
108}
109
110class FRI16_B_ins<bits<5> _op, string asmstr,
111                  InstrItinClass itin>:
112  FRI16<_op, (outs), (ins  CPU16Regs:$rx, brtarget:$imm),
113        !strconcat(asmstr, "\t$rx, $imm  # 16 bit inst"), [], itin>;
114//
115// Compare a register and immediate and place result in CC
116// Implicit use of T8
117//
118// EXT-CCRR Instruction format
119//
120class FEXT_CCRXI16_ins<string asmstr>:
121  MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, simm16:$imm),
122               !strconcat(asmstr, "\t$rx, $imm\n\tmove\t$cc, $$t8"), []> {
123  let isCodeGenOnly=1;
124  let usesCustomInserter = 1;
125}
126
127// JAL and JALX instruction format
128//
129class FJAL16_ins<bits<1> _X, string asmstr,
130                 InstrItinClass itin>:
131  FJAL16<_X, (outs), (ins uimm26:$imm),
132         !strconcat(asmstr, "\t$imm\n\tnop"),[],
133         itin>  {
134  let isCodeGenOnly=1;
135  let Size=6;
136}
137
138class FJALB16_ins<bits<1> _X, string asmstr,
139                 InstrItinClass itin>:
140  FJAL16<_X, (outs), (ins uimm26:$imm),
141         !strconcat(asmstr, "\t$imm\t# branch\n\tnop"),[],
142         itin>  {
143  let isCodeGenOnly=1;
144  let Size=6;
145}
146
147//
148// EXT-I instruction format
149//
150class FEXT_I16_ins<bits<5> eop, string asmstr, InstrItinClass itin> :
151  FEXT_I16<eop, (outs), (ins brtarget:$imm16),
152           !strconcat(asmstr, "\t$imm16"),[], itin>;
153
154//
155// EXT-I8 instruction format
156//
157
158class FEXT_I816_ins_base<bits<3> _func, string asmstr,
159                         string asmstr2, InstrItinClass itin>:
160  FEXT_I816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
161            [], itin>;
162
163class FEXT_I816_ins<bits<3> _func, string asmstr,
164                    InstrItinClass itin>:
165  FEXT_I816_ins_base<_func, asmstr, "\t$imm", itin>;
166
167class FEXT_I816_SP_ins<bits<3> _func, string asmstr,
168                       InstrItinClass itin>:
169      FEXT_I816_ins_base<_func, asmstr, "\t$$sp, $imm", itin>;
170
171//
172// Assembler formats in alphabetical order.
173// Natural and pseudos are mixed together.
174//
175// Compare two registers and place result in CC
176// Implicit use of T8
177//
178// CC-RR Instruction format
179//
180class FCCRR16_ins<string asmstr> :
181  MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, CPU16Regs:$ry),
182               !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$cc, $$t8"), []> {
183  let isCodeGenOnly=1;
184  let usesCustomInserter = 1;
185}
186
187//
188// EXT-RI instruction format
189//
190
191class FEXT_RI16_ins_base<bits<5> _op, string asmstr, string asmstr2,
192                         InstrItinClass itin>:
193  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins simm16:$imm),
194                  !strconcat(asmstr, asmstr2), [], itin>;
195
196class FEXT_RI16_ins<bits<5> _op, string asmstr,
197                    InstrItinClass itin>:
198  FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
199
200class FEXT_RI16R_ins_base<bits<5> _op, string asmstr, string asmstr2,
201                         InstrItinClass itin>:
202  FEXT_RI16<_op, (outs ), (ins CPU16Regs:$rx, simm16:$imm),
203                  !strconcat(asmstr, asmstr2), [], itin>;
204
205class FEXT_RI16R_ins<bits<5> _op, string asmstr,
206                    InstrItinClass itin>:
207  FEXT_RI16R_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
208
209class FEXT_RI16_PC_ins<bits<5> _op, string asmstr, InstrItinClass itin>:
210  FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $$pc, $imm", itin>;
211
212class FEXT_RI16_B_ins<bits<5> _op, string asmstr,
213                      InstrItinClass itin>:
214  FEXT_RI16<_op, (outs), (ins  CPU16Regs:$rx, brtarget:$imm),
215            !strconcat(asmstr, "\t$rx, $imm"), [], itin>;
216
217class FEXT_RI16_TCP_ins<bits<5> _op, string asmstr,
218                        InstrItinClass itin>:
219  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),
220            !strconcat(asmstr, "\t$rx, $imm"), [], itin>;
221
222class FEXT_2RI16_ins<bits<5> _op, string asmstr,
223                     InstrItinClass itin>:
224  FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
225            !strconcat(asmstr, "\t$rx, $imm"), [], itin> {
226  let Constraints = "$rx_ = $rx";
227}
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 Constant32 : MipsPseudo16<(outs), (ins simm32:$imm), "\t.word $imm", []>;
487
488def LwConstant32 :
489  MipsPseudo16<(outs CPU16Regs:$rx), (ins simm32:$imm, simm32:$constid),
490               "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;
491
492//
493// Some general instruction class info
494//
495//
496
497class ArithLogic16Defs<bit isCom=0> {
498  bits<5> shamt = 0;
499  bit isCommutable = isCom;
500  bit isReMaterializable = 1;
501  bit hasSideEffects = 0;
502}
503
504class branch16 {
505  bit isBranch = 1;
506  bit isTerminator = 1;
507  bit isBarrier = 1;
508}
509
510class cbranch16 {
511  bit isBranch = 1;
512  bit isTerminator = 1;
513}
514
515class MayLoad {
516  bit mayLoad = 1;
517}
518
519class MayStore {
520  bit mayStore = 1;
521}
522//
523
524
525// Format: ADDIU rx, immediate MIPS16e
526// Purpose: Add Immediate Unsigned Word (2-Operand, Extended)
527// To add a constant to a 32-bit integer.
528//
529def AddiuRxImmX16: FEXT_RI16_ins<0b01001, "addiu", IIM16Alu>;
530
531def AddiuRxRxImm16: F2RI16_ins<0b01001, "addiu", IIM16Alu>,
532  ArithLogic16Defs<0> {
533  let AddedComplexity = 5;
534}
535def AddiuRxRxImmX16: FEXT_2RI16_ins<0b01001, "addiu", IIM16Alu>,
536  ArithLogic16Defs<0> {
537  let isCodeGenOnly = 1;
538}
539
540def AddiuRxRyOffMemX16:
541  FEXT_RRI_A16_mem_ins<0, "addiu", mem16_ea, IIM16Alu>;
542
543//
544
545// Format: ADDIU rx, pc, immediate MIPS16e
546// Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended)
547// To add a constant to the program counter.
548//
549def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIM16Alu>;
550
551//
552// Format: ADDIU sp, immediate MIPS16e
553// Purpose: Add Immediate Unsigned Word (2-Operand, SP-Relative, Extended)
554// To add a constant to the stack pointer.
555//
556def AddiuSpImm16
557  : FI816_SP_ins<0b011, "addiu", IIM16Alu> {
558  let Defs = [SP];
559  let Uses = [SP];
560  let AddedComplexity = 5;
561}
562
563def AddiuSpImmX16
564  : FEXT_I816_SP_ins<0b011, "addiu", IIM16Alu> {
565  let Defs = [SP];
566  let Uses = [SP];
567}
568
569//
570// Format: ADDU rz, rx, ry MIPS16e
571// Purpose: Add Unsigned Word (3-Operand)
572// To add 32-bit integers.
573//
574
575def AdduRxRyRz16: FRRR16_ins<01, "addu", IIM16Alu>, ArithLogic16Defs<1>;
576
577//
578// Format: AND rx, ry MIPS16e
579// Purpose: AND
580// To do a bitwise logical AND.
581
582def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIM16Alu>, ArithLogic16Defs<1>;
583
584
585//
586// Format: BEQZ rx, offset MIPS16e
587// Purpose: Branch on Equal to Zero
588// To test a GPR then do a PC-relative conditional branch.
589//
590def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIM16Alu>, cbranch16;
591
592
593//
594// Format: BEQZ rx, offset MIPS16e
595// Purpose: Branch on Equal to Zero (Extended)
596// To test a GPR then do a PC-relative conditional branch.
597//
598def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIM16Alu>, cbranch16;
599
600//
601// Format: B offset MIPS16e
602// Purpose: Unconditional Branch (Extended)
603// To do an unconditional PC-relative branch.
604//
605
606def Bimm16: FI16_ins<0b00010, "b", IIM16Alu>, branch16;
607
608// Format: B offset MIPS16e
609// Purpose: Unconditional Branch
610// To do an unconditional PC-relative branch.
611//
612def BimmX16: FEXT_I16_ins<0b00010, "b", IIM16Alu>, branch16;
613
614//
615// Format: BNEZ rx, offset MIPS16e
616// Purpose: Branch on Not Equal to Zero
617// To test a GPR then do a PC-relative conditional branch.
618//
619def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIM16Alu>, cbranch16;
620
621//
622// Format: BNEZ rx, offset MIPS16e
623// Purpose: Branch on Not Equal to Zero (Extended)
624// To test a GPR then do a PC-relative conditional branch.
625//
626def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIM16Alu>, cbranch16;
627
628
629//
630//Format: BREAK immediate
631// Purpose: Breakpoint
632// To cause a Breakpoint exception.
633
634def Break16: FRRBreakNull16_ins<"break 0", IIM16Alu>;
635//
636// Format: BTEQZ offset MIPS16e
637// Purpose: Branch on T Equal to Zero (Extended)
638// To test special register T then do a PC-relative conditional branch.
639//
640def Bteqz16: FI816_ins<0b000, "bteqz", IIM16Alu>, cbranch16 {
641  let Uses = [T8];
642}
643
644def BteqzX16: FEXT_I816_ins<0b000, "bteqz", IIM16Alu>, cbranch16 {
645  let Uses = [T8];
646}
647
648def BteqzT8CmpX16: FEXT_T8I816_ins<"bteqz", "cmp">, cbranch16;
649
650def BteqzT8CmpiX16: FEXT_T8I8I16_ins<"bteqz", "cmpi">,
651  cbranch16;
652
653def BteqzT8SltX16: FEXT_T8I816_ins<"bteqz", "slt">, cbranch16;
654
655def BteqzT8SltuX16: FEXT_T8I816_ins<"bteqz", "sltu">, cbranch16;
656
657def BteqzT8SltiX16: FEXT_T8I8I16_ins<"bteqz", "slti">, cbranch16;
658
659def BteqzT8SltiuX16: FEXT_T8I8I16_ins<"bteqz", "sltiu">,
660  cbranch16;
661
662//
663// Format: BTNEZ offset MIPS16e
664// Purpose: Branch on T Not Equal to Zero (Extended)
665// To test special register T then do a PC-relative conditional branch.
666//
667
668def Btnez16: FI816_ins<0b001, "btnez", IIM16Alu>, cbranch16 {
669  let Uses = [T8];
670}
671
672def BtnezX16: FEXT_I816_ins<0b001, "btnez", IIM16Alu> ,cbranch16 {
673  let Uses = [T8];
674}
675
676def BtnezT8CmpX16: FEXT_T8I816_ins<"btnez", "cmp">, cbranch16;
677
678def BtnezT8CmpiX16: FEXT_T8I8I16_ins<"btnez", "cmpi">, cbranch16;
679
680def BtnezT8SltX16: FEXT_T8I816_ins<"btnez", "slt">, cbranch16;
681
682def BtnezT8SltuX16: FEXT_T8I816_ins<"btnez", "sltu">, cbranch16;
683
684def BtnezT8SltiX16: FEXT_T8I8I16_ins<"btnez", "slti">, cbranch16;
685
686def BtnezT8SltiuX16: FEXT_T8I8I16_ins<"btnez", "sltiu">,
687  cbranch16;
688
689//
690// Format: CMP rx, ry MIPS16e
691// Purpose: Compare
692// To compare the contents of two GPRs.
693//
694def CmpRxRy16: FRR16R_ins<0b01010, "cmp", IIM16Alu> {
695  let Defs = [T8];
696}
697
698//
699// Format: CMPI rx, immediate MIPS16e
700// Purpose: Compare Immediate
701// To compare a constant with the contents of a GPR.
702//
703def CmpiRxImm16: FRI16R_ins<0b01110, "cmpi", IIM16Alu> {
704  let Defs = [T8];
705}
706
707//
708// Format: CMPI rx, immediate MIPS16e
709// Purpose: Compare Immediate (Extended)
710// To compare a constant with the contents of a GPR.
711//
712def CmpiRxImmX16: FEXT_RI16R_ins<0b01110, "cmpi", IIM16Alu> {
713  let Defs = [T8];
714}
715
716
717//
718// Format: DIV rx, ry MIPS16e
719// Purpose: Divide Word
720// To divide 32-bit signed integers.
721//
722def DivRxRy16: FRR16_div_ins<0b11010, "div", IIM16Alu> {
723  let Defs = [HI0, LO0];
724}
725
726//
727// Format: DIVU rx, ry MIPS16e
728// Purpose: Divide Unsigned Word
729// To divide 32-bit unsigned integers.
730//
731def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIM16Alu> {
732  let Defs = [HI0, LO0];
733}
734//
735// Format: JAL target MIPS16e
736// Purpose: Jump and Link
737// To execute a procedure call within the current 256 MB-aligned
738// region and preserve the current ISA.
739//
740
741def Jal16 : FJAL16_ins<0b0, "jal", IIM16Alu> {
742  let hasDelaySlot = 0;  // not true, but we add the nop for now
743  let isCall=1;
744  let Defs = [RA];
745}
746
747def JalB16 : FJALB16_ins<0b0, "jal", IIM16Alu>, branch16 {
748  let hasDelaySlot = 0;  // not true, but we add the nop for now
749  let isBranch=1;
750  let Defs = [RA];
751}
752
753//
754// Format: JR ra MIPS16e
755// Purpose: Jump Register Through Register ra
756// To execute a branch to the instruction address in the return
757// address register.
758//
759
760def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIM16Alu> {
761  let isBranch = 1;
762  let isIndirectBranch = 1;
763  let hasDelaySlot = 1;
764  let isTerminator=1;
765  let isBarrier=1;
766  let isReturn=1;
767}
768
769def JrcRa16: FRR16_JALRC_RA_only_ins<1, 1, "jrc", IIM16Alu> {
770  let isBranch = 1;
771  let isIndirectBranch = 1;
772  let isTerminator=1;
773  let isBarrier=1;
774  let isReturn=1;
775}
776
777def JrcRx16: FRR16_JALRC_ins<1, 1, 0, "jrc", IIM16Alu> {
778  let isBranch = 1;
779  let isIndirectBranch = 1;
780  let isTerminator=1;
781  let isBarrier=1;
782}
783//
784// Format: LB ry, offset(rx) MIPS16e
785// Purpose: Load Byte (Extended)
786// To load a byte from memory as a signed value.
787//
788def LbRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lb", mem16, II_LB>, MayLoad{
789  let isCodeGenOnly = 1;
790}
791
792//
793// Format: LBU ry, offset(rx) MIPS16e
794// Purpose: Load Byte Unsigned (Extended)
795// To load a byte from memory as a unsigned value.
796//
797def LbuRxRyOffMemX16:
798  FEXT_RRI16_mem_ins<0b10100, "lbu", mem16, II_LBU>, MayLoad {
799  let isCodeGenOnly = 1;
800}
801
802//
803// Format: LH ry, offset(rx) MIPS16e
804// Purpose: Load Halfword signed (Extended)
805// To load a halfword from memory as a signed value.
806//
807def LhRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lh", mem16, II_LH>, MayLoad{
808  let isCodeGenOnly = 1;
809}
810
811//
812// Format: LHU ry, offset(rx) MIPS16e
813// Purpose: Load Halfword unsigned (Extended)
814// To load a halfword from memory as an unsigned value.
815//
816def LhuRxRyOffMemX16:
817  FEXT_RRI16_mem_ins<0b10100, "lhu", mem16, II_LHU>, MayLoad {
818  let isCodeGenOnly = 1;
819}
820
821//
822// Format: LI rx, immediate MIPS16e
823// Purpose: Load Immediate
824// To load a constant into a GPR.
825//
826def LiRxImm16: FRI16_ins<0b01101, "li", IIM16Alu>;
827
828//
829// Format: LI rx, immediate MIPS16e
830// Purpose: Load Immediate (Extended)
831// To load a constant into a GPR.
832//
833def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIM16Alu>;
834
835def LiRxImmAlignX16: FEXT_RI16_ins<0b01101, ".align 2\n\tli", IIM16Alu> {
836  let isCodeGenOnly = 1;
837}
838
839//
840// Format: LW ry, offset(rx) MIPS16e
841// Purpose: Load Word (Extended)
842// To load a word from memory as a signed value.
843//
844def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, II_LW>, MayLoad{
845  let isCodeGenOnly = 1;
846}
847
848// Format: LW rx, offset(sp) MIPS16e
849// Purpose: Load Word (SP-Relative, Extended)
850// To load an SP-relative word from memory as a signed value.
851//
852def LwRxSpImmX16: FEXT_RRI16_mem_ins<0b10010, "lw", mem16sp, II_LW>, MayLoad;
853
854def LwRxPcTcp16: FRI16_TCP_ins<0b10110, "lw", II_LW>, MayLoad;
855
856def LwRxPcTcpX16: FEXT_RI16_TCP_ins<0b10110, "lw", II_LW>, MayLoad;
857//
858// Format: MOVE r32, rz MIPS16e
859// Purpose: Move
860// To move the contents of a GPR to a GPR.
861//
862def Move32R16: FI8_MOV32R16_ins<"move", IIM16Alu>;
863
864//
865// Format: MOVE ry, r32 MIPS16e
866//Purpose: Move
867// To move the contents of a GPR to a GPR.
868//
869def MoveR3216: FI8_MOVR3216_ins<"move", IIM16Alu> {
870  let isMoveReg = 1;
871}
872
873//
874// Format: MFHI rx MIPS16e
875// Purpose: Move From HI Register
876// To copy the special purpose HI register to a GPR.
877//
878def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIM16Alu> {
879  let Uses = [HI0];
880  let hasSideEffects = 0;
881  let isMoveReg = 1;
882}
883
884//
885// Format: MFLO rx MIPS16e
886// Purpose: Move From LO Register
887// To copy the special purpose LO register to a GPR.
888//
889def Mflo16: FRR16_M_ins<0b10010, "mflo", IIM16Alu> {
890  let Uses = [LO0];
891  let hasSideEffects = 0;
892  let isMoveReg = 0;
893}
894
895//
896// Pseudo Instruction for mult
897//
898def MultRxRy16:  FMULT16_ins<"mult",  IIM16Alu> {
899  let isCommutable = 1;
900  let hasSideEffects = 0;
901  let Defs = [HI0, LO0];
902}
903
904def MultuRxRy16: FMULT16_ins<"multu", IIM16Alu> {
905  let isCommutable = 1;
906  let hasSideEffects = 0;
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", IIM16Alu> {
916  let isCommutable = 1;
917  let hasSideEffects = 0;
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", IIM16Alu> {
927  let isCommutable = 1;
928  let hasSideEffects = 0;
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", IIM16Alu>;
938
939//
940// Format: NOT rx, ry MIPS16e
941// Purpose: Not
942// To complement an integer value
943//
944def NotRxRy16: FUnaryRR16_ins<0b01111, "not", IIM16Alu>;
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", IIM16Alu>, 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", IIM16Alu>;
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", IIM16Alu>;
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", IIM16Alu>;
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", IIM16Alu>;
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", IIM16Alu> {
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", IIM16Alu> {
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", IIM16Alu> {
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", IIM16Alu> {
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", IIM16Alu>{
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", IIM16Alu>{
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", IIM16Alu>;
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", IIM16Alu>;
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", IIM16Alu>;
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", IIM16Alu>;
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", IIM16Alu>, 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: FEXT_RRI16_mem2_ins<0b11011, "sw", mem16, II_SW>, MayStore;
1281
1282//
1283// Format: SW rx, offset(sp) MIPS16e
1284// Purpose: Store Word rx (SP-Relative)
1285// To store an SP-relative word to memory.
1286//
1287def SwRxSpImmX16: FEXT_RRI16_mem2_ins<0b11010, "sw", mem16sp, II_SW>, MayStore;
1288
1289//
1290//
1291// Format: XOR rx, ry MIPS16e
1292// Purpose: Xor
1293// To do a bitwise logical XOR.
1294//
1295def XorRxRxRy16: FRxRxRy16_ins<0b01110, "xor", IIM16Alu>, ArithLogic16Defs<1>;
1296
1297class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> {
1298  let Predicates = [InMips16Mode];
1299}
1300
1301// Unary Arith/Logic
1302//
1303class ArithLogicU_pat<PatFrag OpNode, Instruction I> :
1304  Mips16Pat<(OpNode CPU16Regs:$r),
1305            (I CPU16Regs:$r)>;
1306
1307def: ArithLogicU_pat<not, NotRxRy16>;
1308def: ArithLogicU_pat<ineg, NegRxRy16>;
1309
1310class ArithLogic16_pat<SDNode OpNode, Instruction I> :
1311  Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r),
1312            (I CPU16Regs:$l, CPU16Regs:$r)>;
1313
1314def: ArithLogic16_pat<add, AdduRxRyRz16>;
1315def: ArithLogic16_pat<and, AndRxRxRy16>;
1316def: ArithLogic16_pat<mul, MultRxRyRz16>;
1317def: ArithLogic16_pat<or, OrRxRxRy16>;
1318def: ArithLogic16_pat<sub, SubuRxRyRz16>;
1319def: ArithLogic16_pat<xor, XorRxRxRy16>;
1320
1321// Arithmetic and logical instructions with 2 register operands.
1322
1323class ArithLogicI16_pat<SDNode OpNode, PatFrag imm_type, Instruction I> :
1324  Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm),
1325            (I CPU16Regs:$in, imm_type:$imm)>;
1326
1327def: ArithLogicI16_pat<add, immSExt8, AddiuRxRxImm16>;
1328def: ArithLogicI16_pat<add, immSExt16, AddiuRxRxImmX16>;
1329def: ArithLogicI16_pat<shl, immZExt5, SllX16>;
1330def: ArithLogicI16_pat<srl, immZExt5, SrlX16>;
1331def: ArithLogicI16_pat<sra, immZExt5, SraX16>;
1332
1333class shift_rotate_reg16_pat<SDNode OpNode, Instruction I> :
1334  Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra),
1335            (I CPU16Regs:$r, CPU16Regs:$ra)>;
1336
1337def: shift_rotate_reg16_pat<shl, SllvRxRy16>;
1338def: shift_rotate_reg16_pat<sra, SravRxRy16>;
1339def: shift_rotate_reg16_pat<srl, SrlvRxRy16>;
1340
1341class LoadM16_pat<PatFrag OpNode, Instruction I, ComplexPattern Addr> :
1342  Mips16Pat<(OpNode Addr:$addr), (I Addr:$addr)>;
1343
1344def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16, addr16>;
1345def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16, addr16>;
1346def: LoadM16_pat<sextloadi16, LhRxRyOffMemX16, addr16>;
1347def: LoadM16_pat<zextloadi16, LhuRxRyOffMemX16, addr16>;
1348def: LoadM16_pat<load, LwRxSpImmX16, addr16sp>;
1349
1350class StoreM16_pat<PatFrag OpNode, Instruction I, ComplexPattern Addr> :
1351  Mips16Pat<(OpNode CPU16Regs:$r, Addr:$addr), (I CPU16Regs:$r, Addr:$addr)>;
1352
1353def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16, addr16>;
1354def: StoreM16_pat<truncstorei16, ShRxRyOffMemX16, addr16>;
1355def: StoreM16_pat<store, SwRxSpImmX16, addr16sp>;
1356
1357// Unconditional branch
1358class UncondBranch16_pat<SDNode OpNode, Instruction I>:
1359  Mips16Pat<(OpNode bb:$imm16), (I bb:$imm16)> {
1360    let Predicates = [InMips16Mode];
1361  }
1362
1363def : Mips16Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1364                (Jal16 tglobaladdr:$dst)>;
1365
1366def : Mips16Pat<(MipsJmpLink (i32 texternalsym:$dst)),
1367                (Jal16 texternalsym:$dst)>;
1368
1369// Indirect branch
1370def: Mips16Pat<(brind CPU16Regs:$rs), (JrcRx16 CPU16Regs:$rs)> {
1371  // Ensure that the addition of MIPS32r6/MIPS64r6 support does not change
1372  // MIPS16's behaviour.
1373  let AddedComplexity = 1;
1374}
1375
1376// Jump and Link (Call)
1377let isCall=1, hasDelaySlot=0 in
1378def JumpLinkReg16:
1379  FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs),
1380              "jalrc\t$rs", [(MipsJmpLink CPU16Regs:$rs)], II_JALRC> {
1381  let Defs = [RA];
1382}
1383
1384// Mips16 pseudos
1385let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1,
1386  hasExtraSrcRegAllocReq = 1 in
1387def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>;
1388
1389
1390// setcc patterns
1391
1392class SetCC_R16<PatFrag cond_op, Instruction I>:
1393  Mips16Pat<(cond_op CPU16Regs:$rx, CPU16Regs:$ry),
1394            (I CPU16Regs:$rx, CPU16Regs:$ry)>;
1395
1396class SetCC_I16<PatFrag cond_op, PatLeaf imm_type, Instruction I>:
1397  Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16),
1398            (I CPU16Regs:$rx, imm_type:$imm16)>;
1399
1400
1401def: Mips16Pat<(i32 addr16sp:$addr), (AddiuRxRyOffMemX16 addr16sp:$addr)>;
1402
1403
1404// Large (>16 bit) immediate loads
1405def : Mips16Pat<(i32 imm:$imm), (LwConstant32 imm:$imm, -1)>;
1406
1407//
1408// Some branch conditional patterns are not generated by llvm at this time.
1409// Some are for seemingly arbitrary reasons not used: i.e. with signed number
1410// comparison they are used and for unsigned a different pattern is used.
1411// I am pushing upstream from the full mips16 port and it seemed that I needed
1412// these earlier and the mips32 port has these but now I cannot create test
1413// cases that use these patterns. While I sort this all out I will leave these
1414// extra patterns commented out and if I can be sure they are really not used,
1415// I will delete the code. I don't want to check the code in uncommented without
1416// a valid test case. In some cases, the compiler is generating patterns with
1417// setcc instead and earlier I had implemented setcc first so may have masked
1418// the problem. The setcc variants are suboptimal for mips16 so I may wantto
1419// figure out how to enable the brcond patterns or else possibly new
1420// combinations of brcond and setcc.
1421//
1422//
1423// bcond-seteq
1424//
1425def: Mips16Pat
1426  <(brcond (i32 (seteq CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1427   (BteqzT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1428  >;
1429
1430
1431def: Mips16Pat
1432  <(brcond (i32 (seteq CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1433   (BteqzT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$targ16)
1434  >;
1435
1436def: Mips16Pat
1437  <(brcond (i32 (seteq CPU16Regs:$rx, 0)), bb:$targ16),
1438   (BeqzRxImm16 CPU16Regs:$rx, bb:$targ16)
1439  >;
1440
1441//
1442// bcond-setgt (do we need to have this pair of setlt, setgt??)
1443//
1444def: Mips16Pat
1445  <(brcond (i32 (setgt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1446   (BtnezT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx,  bb:$imm16)
1447  >;
1448
1449//
1450// bcond-setge
1451//
1452def: Mips16Pat
1453  <(brcond (i32 (setge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1454   (BteqzT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1455  >;
1456
1457//
1458// never called because compiler transforms a >= k to a > (k-1)
1459def: Mips16Pat
1460  <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1461   (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$imm16)
1462  >;
1463
1464//
1465// bcond-setlt
1466//
1467def: Mips16Pat
1468  <(brcond (i32 (setlt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1469   (BtnezT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1470  >;
1471
1472def: Mips16Pat
1473  <(brcond (i32 (setlt CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1474   (BtnezT8SltiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$imm16)
1475  >;
1476
1477//
1478// bcond-setle
1479//
1480def: Mips16Pat
1481  <(brcond (i32 (setle CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1482   (BteqzT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx,  bb:$imm16)
1483  >;
1484
1485//
1486// bcond-setne
1487//
1488def: Mips16Pat
1489  <(brcond (i32 (setne CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1490   (BtnezT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1491  >;
1492
1493def: Mips16Pat
1494  <(brcond (i32 (setne CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1495   (BtnezT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm,  bb:$targ16)
1496  >;
1497
1498def: Mips16Pat
1499  <(brcond (i32 (setne CPU16Regs:$rx, 0)), bb:$targ16),
1500   (BnezRxImm16 CPU16Regs:$rx, bb:$targ16)
1501  >;
1502
1503//
1504// This needs to be there but I forget which code will generate it
1505//
1506def: Mips16Pat
1507  <(brcond CPU16Regs:$rx, bb:$targ16),
1508   (BnezRxImm16 CPU16Regs:$rx, bb:$targ16)
1509  >;
1510
1511//
1512
1513//
1514// bcond-setugt
1515//
1516//def: Mips16Pat
1517//  <(brcond (i32 (setugt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1518//   (BtnezT8SltuX16 CPU16Regs:$ry, CPU16Regs:$rx,  bb:$imm16)
1519//  >;
1520
1521//
1522// bcond-setuge
1523//
1524//def: Mips16Pat
1525//  <(brcond (i32 (setuge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1526//   (BteqzT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1527//  >;
1528
1529
1530//
1531// bcond-setult
1532//
1533//def: Mips16Pat
1534//  <(brcond (i32 (setult CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1535//   (BtnezT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry,  bb:$imm16)
1536//  >;
1537
1538def: UncondBranch16_pat<br, Bimm16>;
1539
1540// Small immediates
1541def: Mips16Pat<(i32 immSExt16:$in),
1542               (AddiuRxRxImmX16 (MoveR3216 ZERO), immSExt16:$in)>;
1543
1544def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>;
1545
1546//
1547// MipsDivRem
1548//
1549def: Mips16Pat
1550  <(MipsDivRem16 CPU16Regs:$rx, CPU16Regs:$ry),
1551   (DivRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1552
1553//
1554// MipsDivRemU
1555//
1556def: Mips16Pat
1557  <(MipsDivRemU16 CPU16Regs:$rx, CPU16Regs:$ry),
1558   (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1559
1560//  signed a,b
1561//  x = (a>=b)?x:y
1562//
1563//  if !(a < b) x = y
1564//
1565def : Mips16Pat<(select (i32 (setge CPU16Regs:$a, CPU16Regs:$b)),
1566                 CPU16Regs:$x, CPU16Regs:$y),
1567                (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1568                 CPU16Regs:$a, CPU16Regs:$b)>;
1569
1570//  signed a,b
1571//  x = (a>b)?x:y
1572//
1573//  if  (b < a) x = y
1574//
1575def : Mips16Pat<(select (i32 (setgt CPU16Regs:$a, CPU16Regs:$b)),
1576                 CPU16Regs:$x, CPU16Regs:$y),
1577                (SelTBtneZSlt CPU16Regs:$x, CPU16Regs:$y,
1578                 CPU16Regs:$b, CPU16Regs:$a)>;
1579
1580// unsigned a,b
1581// x = (a>=b)?x:y
1582//
1583// if !(a < b) x = y;
1584//
1585def : Mips16Pat<
1586  (select (i32 (setuge CPU16Regs:$a, CPU16Regs:$b)),
1587   CPU16Regs:$x, CPU16Regs:$y),
1588  (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1589   CPU16Regs:$a, CPU16Regs:$b)>;
1590
1591//  unsigned a,b
1592//  x = (a>b)?x:y
1593//
1594//  if (b < a) x = y
1595//
1596def : Mips16Pat<(select (i32 (setugt CPU16Regs:$a, CPU16Regs:$b)),
1597                 CPU16Regs:$x, CPU16Regs:$y),
1598                (SelTBtneZSltu CPU16Regs:$x, CPU16Regs:$y,
1599                 CPU16Regs:$b, CPU16Regs:$a)>;
1600
1601// signed
1602// x = (a >= k)?x:y
1603// due to an llvm optimization, i don't think that this will ever
1604// be used. This is transformed into x = (a > k-1)?x:y
1605//
1606//
1607
1608//def : Mips16Pat<
1609//  (select (i32 (setge CPU16Regs:$lhs, immSExt16:$rhs)),
1610//   CPU16Regs:$T, CPU16Regs:$F),
1611//  (SelTBteqZSlti CPU16Regs:$T, CPU16Regs:$F,
1612//   CPU16Regs:$lhs, immSExt16:$rhs)>;
1613
1614//def : Mips16Pat<
1615//  (select (i32 (setuge CPU16Regs:$lhs, immSExt16:$rhs)),
1616//   CPU16Regs:$T, CPU16Regs:$F),
1617//  (SelTBteqZSltiu CPU16Regs:$T, CPU16Regs:$F,
1618//   CPU16Regs:$lhs, immSExt16:$rhs)>;
1619
1620// signed
1621// x = (a < k)?x:y
1622//
1623// if !(a < k) x = y;
1624//
1625def : Mips16Pat<
1626  (select (i32 (setlt CPU16Regs:$a, immSExt16:$b)),
1627   CPU16Regs:$x, CPU16Regs:$y),
1628  (SelTBtneZSlti CPU16Regs:$x, CPU16Regs:$y,
1629   CPU16Regs:$a, immSExt16:$b)>;
1630
1631
1632//
1633//
1634// signed
1635// x = (a <= b)? x : y
1636//
1637// if  (b < a) x = y
1638//
1639def : Mips16Pat<(select (i32 (setle CPU16Regs:$a, CPU16Regs:$b)),
1640                 CPU16Regs:$x, CPU16Regs:$y),
1641                (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1642                 CPU16Regs:$b, CPU16Regs:$a)>;
1643
1644//
1645// unnsigned
1646// x = (a <= b)? x : y
1647//
1648// if  (b < a) x = y
1649//
1650def : Mips16Pat<(select (i32 (setule CPU16Regs:$a, CPU16Regs:$b)),
1651                 CPU16Regs:$x, CPU16Regs:$y),
1652                (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1653                 CPU16Regs:$b, CPU16Regs:$a)>;
1654
1655//
1656// signed/unsigned
1657// x = (a == b)? x : y
1658//
1659// if (a != b) x = y
1660//
1661def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, CPU16Regs:$b)),
1662                 CPU16Regs:$x, CPU16Regs:$y),
1663                (SelTBteqZCmp CPU16Regs:$x, CPU16Regs:$y,
1664                 CPU16Regs:$b, CPU16Regs:$a)>;
1665
1666//
1667// signed/unsigned
1668// x = (a == 0)? x : y
1669//
1670// if (a != 0) x = y
1671//
1672def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, 0)),
1673                 CPU16Regs:$x, CPU16Regs:$y),
1674                (SelBeqZ CPU16Regs:$x, CPU16Regs:$y,
1675                 CPU16Regs:$a)>;
1676
1677
1678//
1679// signed/unsigned
1680// x = (a == k)? x : y
1681//
1682// if (a != k) x = y
1683//
1684def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, immZExt16:$k)),
1685                 CPU16Regs:$x, CPU16Regs:$y),
1686                (SelTBteqZCmpi CPU16Regs:$x, CPU16Regs:$y,
1687                 CPU16Regs:$a, immZExt16:$k)>;
1688
1689
1690//
1691// signed/unsigned
1692// x = (a != b)? x : y
1693//
1694// if (a == b) x = y
1695//
1696//
1697def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, CPU16Regs:$b)),
1698                 CPU16Regs:$x, CPU16Regs:$y),
1699                (SelTBtneZCmp CPU16Regs:$x, CPU16Regs:$y,
1700                 CPU16Regs:$b, CPU16Regs:$a)>;
1701
1702//
1703// signed/unsigned
1704// x = (a != 0)? x : y
1705//
1706// if (a == 0) x = y
1707//
1708def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, 0)),
1709                 CPU16Regs:$x, CPU16Regs:$y),
1710                (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1711                 CPU16Regs:$a)>;
1712
1713// signed/unsigned
1714// x = (a)? x : y
1715//
1716// if (!a) x = y
1717//
1718def : Mips16Pat<(select  CPU16Regs:$a,
1719                 CPU16Regs:$x, CPU16Regs:$y),
1720      (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1721       CPU16Regs:$a)>;
1722
1723
1724//
1725// signed/unsigned
1726// x = (a != k)? x : y
1727//
1728// if (a == k) x = y
1729//
1730def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, immZExt16:$k)),
1731                 CPU16Regs:$x, CPU16Regs:$y),
1732                (SelTBtneZCmpi CPU16Regs:$x, CPU16Regs:$y,
1733                 CPU16Regs:$a, immZExt16:$k)>;
1734
1735//
1736// When writing C code to test setxx these patterns,
1737// some will be transformed into
1738// other things. So we test using C code but using -O3 and -O0
1739//
1740// seteq
1741//
1742def : Mips16Pat
1743  <(seteq CPU16Regs:$lhs,CPU16Regs:$rhs),
1744   (SltiuCCRxImmX16 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1)>;
1745
1746def : Mips16Pat
1747  <(seteq CPU16Regs:$lhs, 0),
1748   (SltiuCCRxImmX16 CPU16Regs:$lhs, 1)>;
1749
1750
1751//
1752// setge
1753//
1754
1755def: Mips16Pat
1756  <(setge CPU16Regs:$lhs, CPU16Regs:$rhs),
1757   (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1758   (LiRxImmX16 1))>;
1759
1760//
1761// For constants, llvm transforms this to:
1762// x > (k - 1) and then reverses the operands to use setlt. So this pattern
1763// is not used now by the compiler. (Presumably checking that k-1 does not
1764// overflow). The compiler never uses this at the current time, due to
1765// other optimizations.
1766//
1767//def: Mips16Pat
1768//  <(setge CPU16Regs:$lhs, immSExt16:$rhs),
1769//   (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs),
1770//   (LiRxImmX16 1))>;
1771
1772// This catches the x >= -32768 case by transforming it to  x > -32769
1773//
1774def: Mips16Pat
1775  <(setgt CPU16Regs:$lhs, -32769),
1776   (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768),
1777   (LiRxImmX16 1))>;
1778
1779//
1780// setgt
1781//
1782//
1783
1784def: Mips16Pat
1785  <(setgt CPU16Regs:$lhs, CPU16Regs:$rhs),
1786   (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1787
1788//
1789// setle
1790//
1791def: Mips16Pat
1792  <(setle CPU16Regs:$lhs, CPU16Regs:$rhs),
1793   (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImm16 1))>;
1794
1795//
1796// setlt
1797//
1798def: SetCC_R16<setlt, SltCCRxRy16>;
1799
1800def: SetCC_I16<setlt, immSExt16, SltiCCRxImmX16>;
1801
1802//
1803// setne
1804//
1805def : Mips16Pat
1806  <(setne CPU16Regs:$lhs,CPU16Regs:$rhs),
1807   (SltuCCRxRy16 (LiRxImmX16 0),
1808   (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs))>;
1809
1810
1811//
1812// setuge
1813//
1814def: Mips16Pat
1815  <(setuge CPU16Regs:$lhs, CPU16Regs:$rhs),
1816   (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1817   (LiRxImmX16 1))>;
1818
1819// this pattern will never be used because the compiler will transform
1820// x >= k to x > (k - 1) and then use SLT
1821//
1822//def: Mips16Pat
1823//  <(setuge CPU16Regs:$lhs, immZExt16:$rhs),
1824//   (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs),
1825//   (LiRxImmX16 1))>;
1826
1827//
1828// setugt
1829//
1830def: Mips16Pat
1831  <(setugt CPU16Regs:$lhs, CPU16Regs:$rhs),
1832   (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1833
1834//
1835// setule
1836//
1837def: Mips16Pat
1838  <(setule CPU16Regs:$lhs, CPU16Regs:$rhs),
1839   (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>;
1840
1841//
1842// setult
1843//
1844def: SetCC_R16<setult, SltuCCRxRy16>;
1845
1846def: SetCC_I16<setult, immSExt16, SltiuCCRxImmX16>;
1847
1848def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)),
1849               (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>;
1850
1851// hi/lo relocs
1852def : Mips16Pat<(MipsHi tblockaddress:$in),
1853                (SllX16 (LiRxImmX16 tblockaddress:$in), 16)>;
1854def : Mips16Pat<(MipsHi tglobaladdr:$in),
1855                (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>;
1856def : Mips16Pat<(MipsHi tjumptable:$in),
1857                (SllX16 (LiRxImmX16 tjumptable:$in), 16)>;
1858
1859def : Mips16Pat<(MipsLo tblockaddress:$in), (LiRxImmX16 tblockaddress:$in)>;
1860
1861def : Mips16Pat<(MipsTlsHi tglobaltlsaddr:$in),
1862                (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>;
1863
1864// wrapper_pic
1865class Wrapper16Pat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1866  Mips16Pat<(MipsWrapper RC:$gp, node:$in),
1867            (ADDiuOp RC:$gp, node:$in)>;
1868
1869
1870def : Wrapper16Pat<tglobaladdr, AddiuRxRxImmX16, CPU16Regs>;
1871def : Wrapper16Pat<tglobaltlsaddr, AddiuRxRxImmX16, CPU16Regs>;
1872
1873def : Mips16Pat<(i32 (extloadi8   addr16:$src)),
1874                (LbuRxRyOffMemX16  addr16:$src)>;
1875def : Mips16Pat<(i32 (extloadi16  addr16:$src)),
1876                (LhuRxRyOffMemX16  addr16:$src)>;
1877
1878def: Mips16Pat<(trap), (Break16)>;
1879
1880def : Mips16Pat<(sext_inreg CPU16Regs:$val, i8),
1881                (SebRx16 CPU16Regs:$val)>;
1882
1883def : Mips16Pat<(sext_inreg CPU16Regs:$val, i16),
1884                (SehRx16 CPU16Regs:$val)>;
1885
1886def GotPrologue16:
1887  MipsPseudo16<
1888    (outs CPU16Regs:$rh, CPU16Regs:$rl),
1889    (ins simm16:$immHi, simm16:$immLo),
1890    "li\t$rh, $immHi\n\taddiu\t$rl, $$pc, $immLo\n ",[]> ;
1891
1892// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
1893def cpinst_operand : Operand<i32> {
1894  // let PrintMethod = "printCPInstOperand";
1895}
1896
1897// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
1898// the function.  The first operand is the ID# for this instruction, the second
1899// is the index into the MachineConstantPool that this is, the third is the
1900// size in bytes of this constant pool entry.
1901//
1902let hasSideEffects = 0, isNotDuplicable = 1 in
1903def CONSTPOOL_ENTRY :
1904MipsPseudo16<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
1905                      i32imm:$size), "foo", []>;
1906
1907// Instruction Aliases
1908
1909let EncodingPredicates = [InMips16Mode] in
1910def : MipsInstAlias<"nop", (Move32R16 ZERO, S0)>;
1911