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