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