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