blob: ee45df5644df08c2297ecd45fe02d671e57290a8 [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 :
Akira Hatanaka040d2252013-03-14 18:33:23 +000018 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 Kotler30cedf62013-08-04 01:13:25 +000024 let MIOperandInfo = (ops CPU16Regs, simm16, CPU16RegsPlusSP);
Reed Kotler3589dd72012-10-28 06:02:37 +000025 let EncoderMethod = "getMemEncoding";
26}
27
28def mem16_ea : Operand<i32> {
29 let PrintMethod = "printMemOperandEA";
Reed Kotler30cedf62013-08-04 01:13:25 +000030 let MIOperandInfo = (ops CPU16RegsPlusSP, simm16);
Reed Kotler0f2e44a2012-10-10 01:58:16 +000031 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
Reed Kotlerd8217192013-02-19 00:20:58 +000054class FRI16_ins_base<bits<5> op, string asmstr, string asmstr2,
55 InstrItinClass itin>:
56 FRI16<op, (outs CPU16Regs:$rx), (ins simm16:$imm),
57 !strconcat(asmstr, asmstr2), [], itin>;
58
59class FRI16_ins<bits<5> op, string asmstr,
60 InstrItinClass itin>:
61 FRI16_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;
Reed Kotler7b503c22013-02-20 05:45:15 +000062
63class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2,
64 InstrItinClass itin>:
65 FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm),
66 !strconcat(asmstr, asmstr2), [], itin>;
67
68class FRI16R_ins<bits<5> op, string asmstr,
69 InstrItinClass itin>:
70 FRI16R_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>;
71
Reed Kotlerb9bf8dc2013-02-08 21:42:56 +000072class F2RI16_ins<bits<5> _op, string asmstr,
73 InstrItinClass itin>:
74 FRI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
75 !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin> {
76 let Constraints = "$rx_ = $rx";
77}
78
Reed Kotler97ba5f22013-02-21 04:22:38 +000079class FRI16_B_ins<bits<5> _op, string asmstr,
80 InstrItinClass itin>:
81 FRI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm),
82 !strconcat(asmstr, "\t$rx, $imm # 16 bit inst"), [], itin>;
Reed Kotlerb9bf8dc2013-02-08 21:42:56 +000083//
Reed Kotler164bb372012-10-23 01:35:48 +000084// Compare a register and immediate and place result in CC
85// Implicit use of T8
86//
87// EXT-CCRR Instruction format
88//
Reed Kotler61b474f2013-02-16 23:39:52 +000089class FEXT_CCRXI16_ins<string asmstr>:
90 MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, simm16:$imm),
91 !strconcat(asmstr, "\t$rx, $imm\n\tmove\t$cc, $$t8"), []> {
Reed Kotler164bb372012-10-23 01:35:48 +000092 let isCodeGenOnly=1;
Reed Kotlerbd1058a2013-02-25 02:25:47 +000093 let usesCustomInserter = 1;
Reed Kotler164bb372012-10-23 01:35:48 +000094}
95
Reed Kotlerf8933f82013-02-02 04:07:35 +000096// JAL and JALX instruction format
97//
98class FJAL16_ins<bits<1> _X, string asmstr,
99 InstrItinClass itin>:
100 FJAL16<_X, (outs), (ins simm20:$imm),
101 !strconcat(asmstr, "\t$imm\n\tnop"),[],
102 itin> {
103 let isCodeGenOnly=1;
104}
Reed Kotler164bb372012-10-23 01:35:48 +0000105//
Reed Kotler67439242012-10-17 22:29:54 +0000106// EXT-I instruction format
107//
108class FEXT_I16_ins<bits<5> eop, string asmstr, InstrItinClass itin> :
109 FEXT_I16<eop, (outs), (ins brtarget:$imm16),
110 !strconcat(asmstr, "\t$imm16"),[], itin>;
111
112//
113// EXT-I8 instruction format
114//
115
116class FEXT_I816_ins_base<bits<3> _func, string asmstr,
117 string asmstr2, InstrItinClass itin>:
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000118 FEXT_I816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
Reed Kotler67439242012-10-17 22:29:54 +0000119 [], itin>;
120
121class FEXT_I816_ins<bits<3> _func, string asmstr,
122 InstrItinClass itin>:
123 FEXT_I816_ins_base<_func, asmstr, "\t$imm", itin>;
124
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000125class FEXT_I816_SP_ins<bits<3> _func, string asmstr,
126 InstrItinClass itin>:
127 FEXT_I816_ins_base<_func, asmstr, "\t$$sp, $imm", itin>;
128
Reed Kotler67439242012-10-17 22:29:54 +0000129//
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000130// Assembler formats in alphabetical order.
131// Natural and pseudos are mixed together.
132//
Reed Kotler164bb372012-10-23 01:35:48 +0000133// Compare two registers and place result in CC
134// Implicit use of T8
135//
136// CC-RR Instruction format
137//
Reed Kotler61b474f2013-02-16 23:39:52 +0000138class FCCRR16_ins<string asmstr> :
139 MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, CPU16Regs:$ry),
140 !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$cc, $$t8"), []> {
Reed Kotler164bb372012-10-23 01:35:48 +0000141 let isCodeGenOnly=1;
Reed Kotlerbd1058a2013-02-25 02:25:47 +0000142 let usesCustomInserter = 1;
Reed Kotler164bb372012-10-23 01:35:48 +0000143}
144
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000145//
Reed Kotler210ebe92012-09-28 02:26:24 +0000146// EXT-RI instruction format
147//
148
149class FEXT_RI16_ins_base<bits<5> _op, string asmstr, string asmstr2,
150 InstrItinClass itin>:
151 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins simm16:$imm),
152 !strconcat(asmstr, asmstr2), [], itin>;
153
154class FEXT_RI16_ins<bits<5> _op, string asmstr,
155 InstrItinClass itin>:
156 FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
157
Reed Kotler7b503c22013-02-20 05:45:15 +0000158class FEXT_RI16R_ins_base<bits<5> _op, string asmstr, string asmstr2,
159 InstrItinClass itin>:
160 FEXT_RI16<_op, (outs ), (ins CPU16Regs:$rx, simm16:$imm),
161 !strconcat(asmstr, asmstr2), [], itin>;
162
163class FEXT_RI16R_ins<bits<5> _op, string asmstr,
164 InstrItinClass itin>:
165 FEXT_RI16R_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
166
Reed Kotler210ebe92012-09-28 02:26:24 +0000167class FEXT_RI16_PC_ins<bits<5> _op, string asmstr, InstrItinClass itin>:
168 FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $$pc, $imm", itin>;
169
Reed Kotler67439242012-10-17 22:29:54 +0000170class FEXT_RI16_B_ins<bits<5> _op, string asmstr,
171 InstrItinClass itin>:
172 FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm),
173 !strconcat(asmstr, "\t$rx, $imm"), [], itin>;
174
Reed Kotler210ebe92012-09-28 02:26:24 +0000175class FEXT_2RI16_ins<bits<5> _op, string asmstr,
176 InstrItinClass itin>:
177 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
178 !strconcat(asmstr, "\t$rx, $imm"), [], itin> {
179 let Constraints = "$rx_ = $rx";
180}
Reed Kotler24032212012-10-05 18:27:54 +0000181
Reed Kotler67439242012-10-17 22:29:54 +0000182
Reed Kotler210ebe92012-09-28 02:26:24 +0000183// this has an explicit sp argument that we ignore to work around a problem
184// in the compiler
185class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr,
186 InstrItinClass itin>:
187 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm),
Reed Kotler24032212012-10-05 18:27:54 +0000188 !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
Reed Kotler210ebe92012-09-28 02:26:24 +0000189
Reed Kotler30cedf62013-08-04 01:13:25 +0000190class FEXT_RI16_SP_Store_explicit_ins<bits<5> _op, string asmstr,
191 InstrItinClass itin>:
192 FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, CPUSPReg:$ry, simm16:$imm),
193 !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
194
Reed Kotler210ebe92012-09-28 02:26:24 +0000195//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000196// EXT-RRI instruction format
197//
198
199class FEXT_RRI16_mem_ins<bits<5> op, string asmstr, Operand MemOpnd,
200 InstrItinClass itin>:
201 FEXT_RRI16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr),
202 !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
203
Akira Hatanaka22bec282012-08-03 22:57:02 +0000204class FEXT_RRI16_mem2_ins<bits<5> op, string asmstr, Operand MemOpnd,
205 InstrItinClass itin>:
206 FEXT_RRI16<op, (outs ), (ins CPU16Regs:$ry, MemOpnd:$addr),
207 !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
208
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000209//
Reed Kotler3589dd72012-10-28 06:02:37 +0000210//
211// EXT-RRI-A instruction format
212//
213
214class FEXT_RRI_A16_mem_ins<bits<1> op, string asmstr, Operand MemOpnd,
215 InstrItinClass itin>:
216 FEXT_RRI_A16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr),
217 !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
218
219//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000220// EXT-SHIFT instruction format
221//
222class FEXT_SHIFT16_ins<bits<2> _f, string asmstr, InstrItinClass itin>:
Akira Hatanaka31213532013-09-07 00:02:02 +0000223 FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, uimm5:$sa),
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000224 !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>;
225
Reed Kotler67439242012-10-17 22:29:54 +0000226//
227// EXT-T8I8
228//
Reed Kotler61b474f2013-02-16 23:39:52 +0000229class FEXT_T8I816_ins<string asmstr, string asmstr2>:
230 MipsPseudo16<(outs),
231 (ins CPU16Regs:$rx, CPU16Regs:$ry, brtarget:$imm),
232 !strconcat(asmstr2, !strconcat("\t$rx, $ry\n\t",
233 !strconcat(asmstr, "\t$imm"))),[]> {
Reed Kotler67439242012-10-17 22:29:54 +0000234 let isCodeGenOnly=1;
Reed Kotlere2bead72013-02-24 06:16:39 +0000235 let usesCustomInserter = 1;
Reed Kotler67439242012-10-17 22:29:54 +0000236}
237
238//
239// EXT-T8I8I
240//
Reed Kotler61b474f2013-02-16 23:39:52 +0000241class FEXT_T8I8I16_ins<string asmstr, string asmstr2>:
242 MipsPseudo16<(outs),
243 (ins CPU16Regs:$rx, simm16:$imm, brtarget:$targ),
244 !strconcat(asmstr2, !strconcat("\t$rx, $imm\n\t",
245 !strconcat(asmstr, "\t$targ"))), []> {
Reed Kotler67439242012-10-17 22:29:54 +0000246 let isCodeGenOnly=1;
Reed Kotler7a86b3d2013-02-24 23:17:51 +0000247 let usesCustomInserter = 1;
Reed Kotler67439242012-10-17 22:29:54 +0000248}
249//
250
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000251
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000252//
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000253// I8_MOVR32 instruction format (used only by the MOVR32 instructio
254//
255class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>:
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000256 FI8_MOVR3216<(outs CPU16Regs:$rz), (ins GPR32:$r32),
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000257 !strconcat(asmstr, "\t$rz, $r32"), [], itin>;
258
259//
260// I8_MOV32R instruction format (used only by MOV32R instruction)
261//
262
263class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>:
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000264 FI8_MOV32R16<(outs GPR32:$r32), (ins CPU16Regs:$rz),
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000265 !strconcat(asmstr, "\t$r32, $rz"), [], itin>;
266
267//
268// This are pseudo formats for multiply
269// This first one can be changed to non pseudo now.
270//
271// MULT
272//
273class FMULT16_ins<string asmstr, InstrItinClass itin> :
274 MipsPseudo16<(outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
275 !strconcat(asmstr, "\t$rx, $ry"), []>;
276
277//
278// MULT-LO
279//
280class FMULT16_LO_ins<string asmstr, InstrItinClass itin> :
281 MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
282 !strconcat(asmstr, "\t$rx, $ry\n\tmflo\t$rz"), []> {
283 let isCodeGenOnly=1;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000284}
285
286//
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000287// RR-type instruction format
288//
289
290class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
291 FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
292 !strconcat(asmstr, "\t$rx, $ry"), [], itin> {
293}
Reed Kotlercf11c592012-10-12 02:01:09 +0000294
Reed Kotlerbb870e22013-08-07 04:00:26 +0000295class FRRBreakNull16_ins<string asmstr, InstrItinClass itin> :
296 FRRBreak16<(outs), (ins), asmstr, [], itin> {
297 let Code=0;
298}
299
Reed Kotler80070bd2013-02-23 23:37:03 +0000300class FRR16R_ins<bits<5> f, string asmstr, InstrItinClass itin> :
301 FRR16<f, (outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
302 !strconcat(asmstr, "\t$rx, $ry"), [], itin> {
303}
304
Reed Kotler61b474f2013-02-16 23:39:52 +0000305class FRRTR16_ins<string asmstr> :
306 MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
307 !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$rz, $$t8"), []> ;
Reed Kotler287f0442012-10-26 04:46:26 +0000308
Reed Kotlercf11c592012-10-12 02:01:09 +0000309//
310// maybe refactor but need a $zero as a dummy first parameter
311//
312class FRR16_div_ins<bits<5> f, string asmstr, InstrItinClass itin> :
313 FRR16<f, (outs ), (ins CPU16Regs:$rx, CPU16Regs:$ry),
314 !strconcat(asmstr, "\t$$zero, $rx, $ry"), [], itin> ;
315
Reed Kotler4e1c6292012-10-26 16:18:19 +0000316class FUnaryRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
317 FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
318 !strconcat(asmstr, "\t$rx, $ry"), [], itin> ;
319
320
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000321class FRR16_M_ins<bits<5> f, string asmstr,
322 InstrItinClass itin> :
323 FRR16<f, (outs CPU16Regs:$rx), (ins),
324 !strconcat(asmstr, "\t$rx"), [], itin>;
325
326class FRxRxRy16_ins<bits<5> f, string asmstr,
327 InstrItinClass itin> :
328 FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
329 !strconcat(asmstr, "\t$rz, $ry"),
330 [], itin> {
331 let Constraints = "$rx = $rz";
332}
333
334let rx=0 in
335class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_,
336 string asmstr, InstrItinClass itin>:
337 FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t $$ra"),
338 [], itin> ;
339
Reed Kotlere6c31572012-10-28 23:08:07 +0000340
341class FRR16_JALRC_ins<bits<1> nd, bits<1> l, bits<1> ra,
342 string asmstr, InstrItinClass itin>:
Jack Carter7ab15fa2013-01-19 02:00:40 +0000343 FRR16_JALRC<nd, l, ra, (outs), (ins CPU16Regs:$rx),
Reed Kotlere6c31572012-10-28 23:08:07 +0000344 !strconcat(asmstr, "\t $rx"), [], itin> ;
345
Reed Kotler445d0ad2013-10-07 20:46:19 +0000346class FRR_SF16_ins
347 <bits<5> _funct, bits<3> _subfunc,
348 string asmstr, InstrItinClass itin>:
349 FRR_SF16<_funct, _subfunc, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_),
350 !strconcat(asmstr, "\t $rx"),
351 [], itin> {
352 let Constraints = "$rx_ = $rx";
353 }
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000354//
355// RRR-type instruction format
356//
357
358class FRRR16_ins<bits<2> _f, string asmstr, InstrItinClass itin> :
359 FRRR16<_f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
360 !strconcat(asmstr, "\t$rz, $rx, $ry"), [], itin>;
361
362//
Reed Kotler097556d2012-10-25 21:33:30 +0000363// These Sel patterns support the generation of conditional move
364// pseudo instructions.
365//
366// The nomenclature uses the components making up the pseudo and may
367// be a bit counter intuitive when compared with the end result we seek.
368// For example using a bqez in the example directly below results in the
369// conditional move being done if the tested register is not zero.
370// I considered in easier to check by keeping the pseudo consistent with
371// it's components but it could have been done differently.
372//
373// The simplest case is when can test and operand directly and do the
374// conditional move based on a simple mips16 conditional
375// branch instruction.
376// for example:
377// if $op == beqz or bnez:
378//
379// $op1 $rt, .+4
380// move $rd, $rs
381//
382// if $op == beqz, then if $rt != 0, then the conditional assignment
383// $rd = $rs is done.
384
385// if $op == bnez, then if $rt == 0, then the conditional assignment
386// $rd = $rs is done.
387//
388// So this pseudo class only has one operand, i.e. op
389//
Reed Kotler61b474f2013-02-16 23:39:52 +0000390class Sel<string op>:
391 MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs,
392 CPU16Regs:$rt),
393 !strconcat(op, "\t$rt, .+4\n\t\n\tmove $rd, $rs"), []> {
394 //let isCodeGenOnly=1;
Reed Kotler097556d2012-10-25 21:33:30 +0000395 let Constraints = "$rd = $rd_";
Reed Kotler97ba5f22013-02-21 04:22:38 +0000396 let usesCustomInserter = 1;
Reed Kotler097556d2012-10-25 21:33:30 +0000397}
398
399//
400// The next two instruction classes allow for an operand which tests
401// two operands and returns a value in register T8 and
402//then does a conditional branch based on the value of T8
403//
404
405// op2 can be cmpi or slti/sltiu
406// op1 can bteqz or btnez
407// the operands for op2 are a register and a signed constant
408//
409// $op2 $t, $imm ;test register t and branch conditionally
410// $op1 .+4 ;op1 is a conditional branch
411// move $rd, $rs
412//
413//
Reed Kotler61b474f2013-02-16 23:39:52 +0000414class SeliT<string op1, string op2>:
415 MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs,
416 CPU16Regs:$rl, simm16:$imm),
417 !strconcat(op2,
418 !strconcat("\t$rl, $imm\n\t",
419 !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
Reed Kotler097556d2012-10-25 21:33:30 +0000420 let isCodeGenOnly=1;
421 let Constraints = "$rd = $rd_";
Reed Kotler4416cda2013-02-22 05:10:51 +0000422 let usesCustomInserter = 1;
Reed Kotler097556d2012-10-25 21:33:30 +0000423}
424
425//
426// op2 can be cmp or slt/sltu
427// op1 can be bteqz or btnez
428// the operands for op2 are two registers
429// op1 is a conditional branch
430//
431//
432// $op2 $rl, $rr ;test registers rl,rr
433// $op1 .+4 ;op2 is a conditional branch
434// move $rd, $rs
435//
436//
Reed Kotler61b474f2013-02-16 23:39:52 +0000437class SelT<string op1, string op2>:
Reed Kotler7b503c22013-02-20 05:45:15 +0000438 MipsPseudo16<(outs CPU16Regs:$rd_),
Reed Kotler61b474f2013-02-16 23:39:52 +0000439 (ins CPU16Regs:$rd, CPU16Regs:$rs,
Reed Kotler097556d2012-10-25 21:33:30 +0000440 CPU16Regs:$rl, CPU16Regs:$rr),
Reed Kotler61b474f2013-02-16 23:39:52 +0000441 !strconcat(op2,
442 !strconcat("\t$rl, $rr\n\t",
443 !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
Reed Kotler097556d2012-10-25 21:33:30 +0000444 let isCodeGenOnly=1;
445 let Constraints = "$rd = $rd_";
Reed Kotlerdacee2b2013-02-23 03:09:56 +0000446 let usesCustomInserter = 1;
Reed Kotler097556d2012-10-25 21:33:30 +0000447}
448
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000449//
450// 32 bit constant
451//
452def imm32: Operand<i32>;
453
454def Constant32:
455 MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>;
Jack Carter7ab15fa2013-01-19 02:00:40 +0000456
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000457def LwConstant32:
Reed Kotler30cedf62013-08-04 01:13:25 +0000458 MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm),
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000459 "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;
460
Reed Kotler097556d2012-10-25 21:33:30 +0000461
462//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000463// Some general instruction class info
464//
465//
466
467class ArithLogic16Defs<bit isCom=0> {
468 bits<5> shamt = 0;
469 bit isCommutable = isCom;
470 bit isReMaterializable = 1;
471 bit neverHasSideEffects = 1;
472}
473
Reed Kotler67439242012-10-17 22:29:54 +0000474class branch16 {
475 bit isBranch = 1;
476 bit isTerminator = 1;
477 bit isBarrier = 1;
478}
479
480class cbranch16 {
481 bit isBranch = 1;
482 bit isTerminator = 1;
483}
484
Reed Kotler210ebe92012-09-28 02:26:24 +0000485class MayLoad {
486 bit mayLoad = 1;
487}
488
489class MayStore {
490 bit mayStore = 1;
491}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000492//
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000493
Reed Kotler61b474f2013-02-16 23:39:52 +0000494
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000495// Format: ADDIU rx, immediate MIPS16e
496// Purpose: Add Immediate Unsigned Word (2-Operand, Extended)
497// To add a constant to a 32-bit integer.
498//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000499def AddiuRxImmX16: FEXT_RI16_ins<0b01001, "addiu", IIAlu>;
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000500
Reed Kotlerb9bf8dc2013-02-08 21:42:56 +0000501def AddiuRxRxImm16: F2RI16_ins<0b01001, "addiu", IIAlu>,
502 ArithLogic16Defs<0> {
503 let AddedComplexity = 5;
504}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000505def AddiuRxRxImmX16: FEXT_2RI16_ins<0b01001, "addiu", IIAlu>,
Reed Kotlerec8a5492013-02-14 03:05:25 +0000506 ArithLogic16Defs<0> {
507 let isCodeGenOnly = 1;
508}
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000509
Reed Kotler3589dd72012-10-28 06:02:37 +0000510def AddiuRxRyOffMemX16:
511 FEXT_RRI_A16_mem_ins<0, "addiu", mem16_ea, IIAlu>;
512
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000513//
514
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000515// Format: ADDIU rx, pc, immediate MIPS16e
516// Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended)
517// To add a constant to the program counter.
518//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000519def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>;
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000520
521//
522// Format: ADDIU sp, immediate MIPS16e
523// Purpose: Add Immediate Unsigned Word (2-Operand, SP-Relative, Extended)
524// To add a constant to the stack pointer.
525//
Reed Kotlerf662cff2013-02-13 20:28:27 +0000526def AddiuSpImm16
527 : FI816_SP_ins<0b011, "addiu", IIAlu> {
528 let Defs = [SP];
529 let Uses = [SP];
530 let AddedComplexity = 5;
531}
532
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000533def AddiuSpImmX16
534 : FEXT_I816_SP_ins<0b011, "addiu", IIAlu> {
535 let Defs = [SP];
536 let Uses = [SP];
Jack Carter7ab15fa2013-01-19 02:00:40 +0000537}
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000538
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000539//
540// Format: ADDU rz, rx, ry MIPS16e
541// Purpose: Add Unsigned Word (3-Operand)
542// To add 32-bit integers.
543//
544
Akira Hatanaka22bec282012-08-03 22:57:02 +0000545def AdduRxRyRz16: FRRR16_ins<01, "addu", IIAlu>, ArithLogic16Defs<1>;
546
547//
548// Format: AND rx, ry MIPS16e
549// Purpose: AND
550// To do a bitwise logical AND.
551
552def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>;
Reed Kotler67439242012-10-17 22:29:54 +0000553
554
555//
556// Format: BEQZ rx, offset MIPS16e
Reed Kotler97ba5f22013-02-21 04:22:38 +0000557// Purpose: Branch on Equal to Zero
558// To test a GPR then do a PC-relative conditional branch.
559//
560def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16;
561
562
563//
564// Format: BEQZ rx, offset MIPS16e
Reed Kotler67439242012-10-17 22:29:54 +0000565// Purpose: Branch on Equal to Zero (Extended)
566// To test a GPR then do a PC-relative conditional branch.
567//
568def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16;
569
570// Format: B offset MIPS16e
571// Purpose: Unconditional Branch
572// To do an unconditional PC-relative branch.
573//
574def BimmX16: FEXT_I16_ins<0b00010, "b", IIAlu>, branch16;
575
576//
577// Format: BNEZ rx, offset MIPS16e
Reed Kotler97ba5f22013-02-21 04:22:38 +0000578// Purpose: Branch on Not Equal to Zero
579// To test a GPR then do a PC-relative conditional branch.
580//
581def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
582
583//
584// Format: BNEZ rx, offset MIPS16e
Reed Kotler67439242012-10-17 22:29:54 +0000585// Purpose: Branch on Not Equal to Zero (Extended)
586// To test a GPR then do a PC-relative conditional branch.
587//
588def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
589
Reed Kotlerbb870e22013-08-07 04:00:26 +0000590
591//
592//Format: BREAK immediate
593// Purpose: Breakpoint
594// To cause a Breakpoint exception.
595
596def Break16: FRRBreakNull16_ins<"break 0", NoItinerary>;
Reed Kotler67439242012-10-17 22:29:54 +0000597//
598// Format: BTEQZ offset MIPS16e
599// Purpose: Branch on T Equal to Zero (Extended)
600// To test special register T then do a PC-relative conditional branch.
601//
Reed Kotlercb374092013-02-18 00:59:04 +0000602def BteqzX16: FEXT_I816_ins<0b000, "bteqz", IIAlu>, cbranch16 {
603 let Uses = [T8];
604}
Reed Kotler67439242012-10-17 22:29:54 +0000605
Reed Kotler61b474f2013-02-16 23:39:52 +0000606def BteqzT8CmpX16: FEXT_T8I816_ins<"bteqz", "cmp">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000607
Reed Kotler61b474f2013-02-16 23:39:52 +0000608def BteqzT8CmpiX16: FEXT_T8I8I16_ins<"bteqz", "cmpi">,
Reed Kotler67439242012-10-17 22:29:54 +0000609 cbranch16;
610
Reed Kotler61b474f2013-02-16 23:39:52 +0000611def BteqzT8SltX16: FEXT_T8I816_ins<"bteqz", "slt">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000612
Reed Kotler61b474f2013-02-16 23:39:52 +0000613def BteqzT8SltuX16: FEXT_T8I816_ins<"bteqz", "sltu">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000614
Reed Kotler61b474f2013-02-16 23:39:52 +0000615def BteqzT8SltiX16: FEXT_T8I8I16_ins<"bteqz", "slti">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000616
Reed Kotler61b474f2013-02-16 23:39:52 +0000617def BteqzT8SltiuX16: FEXT_T8I8I16_ins<"bteqz", "sltiu">,
Reed Kotler67439242012-10-17 22:29:54 +0000618 cbranch16;
619
620//
621// Format: BTNEZ offset MIPS16e
622// Purpose: Branch on T Not Equal to Zero (Extended)
623// To test special register T then do a PC-relative conditional branch.
624//
Reed Kotlercb374092013-02-18 00:59:04 +0000625def BtnezX16: FEXT_I816_ins<0b001, "btnez", IIAlu> ,cbranch16 {
626 let Uses = [T8];
627}
Reed Kotler67439242012-10-17 22:29:54 +0000628
Reed Kotler61b474f2013-02-16 23:39:52 +0000629def BtnezT8CmpX16: FEXT_T8I816_ins<"btnez", "cmp">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000630
Reed Kotler61b474f2013-02-16 23:39:52 +0000631def BtnezT8CmpiX16: FEXT_T8I8I16_ins<"btnez", "cmpi">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000632
Reed Kotler61b474f2013-02-16 23:39:52 +0000633def BtnezT8SltX16: FEXT_T8I816_ins<"btnez", "slt">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000634
Reed Kotler61b474f2013-02-16 23:39:52 +0000635def BtnezT8SltuX16: FEXT_T8I816_ins<"btnez", "sltu">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000636
Reed Kotler61b474f2013-02-16 23:39:52 +0000637def BtnezT8SltiX16: FEXT_T8I8I16_ins<"btnez", "slti">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000638
Reed Kotler61b474f2013-02-16 23:39:52 +0000639def BtnezT8SltiuX16: FEXT_T8I8I16_ins<"btnez", "sltiu">,
Reed Kotler67439242012-10-17 22:29:54 +0000640 cbranch16;
641
Reed Kotlercf11c592012-10-12 02:01:09 +0000642//
Reed Kotlercb374092013-02-18 00:59:04 +0000643// Format: CMP rx, ry MIPS16e
644// Purpose: Compare
645// To compare the contents of two GPRs.
646//
Reed Kotler80070bd2013-02-23 23:37:03 +0000647def CmpRxRy16: FRR16R_ins<0b01010, "cmp", IIAlu> {
Reed Kotlercb374092013-02-18 00:59:04 +0000648 let Defs = [T8];
649}
650
Reed Kotlerd8217192013-02-19 00:20:58 +0000651//
652// Format: CMPI rx, immediate MIPS16e
653// Purpose: Compare Immediate
654// To compare a constant with the contents of a GPR.
655//
Reed Kotler80070bd2013-02-23 23:37:03 +0000656def CmpiRxImm16: FRI16R_ins<0b01110, "cmpi", IIAlu> {
Reed Kotlerd8217192013-02-19 00:20:58 +0000657 let Defs = [T8];
658}
659
660//
661// Format: CMPI rx, immediate MIPS16e
662// Purpose: Compare Immediate (Extended)
663// To compare a constant with the contents of a GPR.
664//
Reed Kotler80070bd2013-02-23 23:37:03 +0000665def CmpiRxImmX16: FEXT_RI16R_ins<0b01110, "cmpi", IIAlu> {
Reed Kotlerd8217192013-02-19 00:20:58 +0000666 let Defs = [T8];
667}
668
Reed Kotlercb374092013-02-18 00:59:04 +0000669
670//
Reed Kotlercf11c592012-10-12 02:01:09 +0000671// Format: DIV rx, ry MIPS16e
672// Purpose: Divide Word
673// To divide 32-bit signed integers.
674//
675def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> {
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000676 let Defs = [HI0, LO0];
Reed Kotlercf11c592012-10-12 02:01:09 +0000677}
678
679//
680// Format: DIVU rx, ry MIPS16e
681// Purpose: Divide Unsigned Word
682// To divide 32-bit unsigned integers.
683//
684def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> {
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000685 let Defs = [HI0, LO0];
Reed Kotlercf11c592012-10-12 02:01:09 +0000686}
Reed Kotlerf8933f82013-02-02 04:07:35 +0000687//
688// Format: JAL target MIPS16e
689// Purpose: Jump and Link
690// To execute a procedure call within the current 256 MB-aligned
691// region and preserve the current ISA.
692//
Reed Kotlercf11c592012-10-12 02:01:09 +0000693
Reed Kotlerf8933f82013-02-02 04:07:35 +0000694def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> {
Reed Kotlerf8933f82013-02-02 04:07:35 +0000695 let hasDelaySlot = 0; // not true, but we add the nop for now
Reed Kotlerfd132b92013-08-01 00:59:06 +0000696 let isCall=1;
Reed Kotlerf8933f82013-02-02 04:07:35 +0000697}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000698
699//
700// Format: JR ra MIPS16e
701// Purpose: Jump Register Through Register ra
702// To execute a branch to the instruction address in the return
703// address register.
704//
705
Reed Kotler3589dd72012-10-28 06:02:37 +0000706def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIAlu> {
707 let isBranch = 1;
708 let isIndirectBranch = 1;
709 let hasDelaySlot = 1;
710 let isTerminator=1;
711 let isBarrier=1;
712}
Reed Kotlere6c31572012-10-28 23:08:07 +0000713
Reed Kotlerec8a5492013-02-14 03:05:25 +0000714def JrcRa16: FRR16_JALRC_RA_only_ins<1, 1, "jrc", IIAlu> {
Reed Kotlera8117532012-10-30 00:54:49 +0000715 let isBranch = 1;
716 let isIndirectBranch = 1;
717 let isTerminator=1;
718 let isBarrier=1;
719}
720
Reed Kotlere6c31572012-10-28 23:08:07 +0000721def JrcRx16: FRR16_JALRC_ins<1, 1, 0, "jrc", IIAlu> {
722 let isBranch = 1;
723 let isIndirectBranch = 1;
724 let isTerminator=1;
725 let isBarrier=1;
726}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000727//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000728// Format: LB ry, offset(rx) MIPS16e
729// Purpose: Load Byte (Extended)
730// To load a byte from memory as a signed value.
731//
Reed Kotlerec8a5492013-02-14 03:05:25 +0000732def LbRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lb", mem16, IILoad>, MayLoad{
733 let isCodeGenOnly = 1;
734}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000735
736//
737// Format: LBU ry, offset(rx) MIPS16e
738// Purpose: Load Byte Unsigned (Extended)
739// To load a byte from memory as a unsigned value.
740//
Reed Kotler210ebe92012-09-28 02:26:24 +0000741def LbuRxRyOffMemX16:
Reed Kotlerec8a5492013-02-14 03:05:25 +0000742 FEXT_RRI16_mem_ins<0b10100, "lbu", mem16, IILoad>, MayLoad {
743 let isCodeGenOnly = 1;
744}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000745
746//
747// Format: LH ry, offset(rx) MIPS16e
748// Purpose: Load Halfword signed (Extended)
749// To load a halfword from memory as a signed value.
750//
Reed Kotlerec8a5492013-02-14 03:05:25 +0000751def LhRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lh", mem16, IILoad>, MayLoad{
752 let isCodeGenOnly = 1;
753}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000754
755//
756// Format: LHU ry, offset(rx) MIPS16e
757// Purpose: Load Halfword unsigned (Extended)
758// To load a halfword from memory as an unsigned value.
759//
Reed Kotler210ebe92012-09-28 02:26:24 +0000760def LhuRxRyOffMemX16:
Reed Kotlerec8a5492013-02-14 03:05:25 +0000761 FEXT_RRI16_mem_ins<0b10100, "lhu", mem16, IILoad>, MayLoad {
762 let isCodeGenOnly = 1;
763}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000764
765//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000766// Format: LI rx, immediate MIPS16e
Reed Kotler7b503c22013-02-20 05:45:15 +0000767// Purpose: Load Immediate
768// To load a constant into a GPR.
769//
770def LiRxImm16: FRI16_ins<0b01101, "li", IIAlu>;
771
772//
773// Format: LI rx, immediate MIPS16e
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000774// Purpose: Load Immediate (Extended)
775// To load a constant into a GPR.
776//
777def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>;
778
Reed Kotlerd6aadc72013-09-18 22:46:09 +0000779def LiRxImmAlignX16: FEXT_RI16_ins<0b01101, ".align 2\n\tli", IIAlu> {
780 let isCodeGenOnly = 1;
781}
782
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000783//
784// Format: LW ry, offset(rx) MIPS16e
785// Purpose: Load Word (Extended)
786// To load a word from memory as a signed value.
787//
Reed Kotlerec8a5492013-02-14 03:05:25 +0000788def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IILoad>, MayLoad{
789 let isCodeGenOnly = 1;
790}
Reed Kotler210ebe92012-09-28 02:26:24 +0000791
792// Format: LW rx, offset(sp) MIPS16e
793// Purpose: Load Word (SP-Relative, Extended)
794// To load an SP-relative word from memory as a signed value.
795//
Reed Kotler3aad7622012-12-19 04:06:15 +0000796def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10110, "lw", IILoad>, MayLoad{
797 let Uses = [SP];
798}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000799
800//
801// Format: MOVE r32, rz MIPS16e
802// Purpose: Move
803// To move the contents of a GPR to a GPR.
804//
Akira Hatanaka0fbaec22012-09-14 03:21:56 +0000805def Move32R16: FI8_MOV32R16_ins<"move", IIAlu>;
806
807//
808// Format: MOVE ry, r32 MIPS16e
809//Purpose: Move
810// To move the contents of a GPR to a GPR.
811//
812def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000813
814//
Reed Kotler24032212012-10-05 18:27:54 +0000815// Format: MFHI rx MIPS16e
816// Purpose: Move From HI Register
817// To copy the special purpose HI register to a GPR.
818//
819def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> {
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000820 let Uses = [HI0];
Reed Kotler24032212012-10-05 18:27:54 +0000821 let neverHasSideEffects = 1;
822}
823
824//
825// Format: MFLO rx MIPS16e
826// Purpose: Move From LO Register
827// To copy the special purpose LO register to a GPR.
828//
829def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> {
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000830 let Uses = [LO0];
Reed Kotler24032212012-10-05 18:27:54 +0000831 let neverHasSideEffects = 1;
832}
833
834//
835// Pseudo Instruction for mult
836//
837def MultRxRy16: FMULT16_ins<"mult", IIAlu> {
838 let isCommutable = 1;
839 let neverHasSideEffects = 1;
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000840 let Defs = [HI0, LO0];
Reed Kotler24032212012-10-05 18:27:54 +0000841}
842
843def MultuRxRy16: FMULT16_ins<"multu", IIAlu> {
844 let isCommutable = 1;
845 let neverHasSideEffects = 1;
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000846 let Defs = [HI0, LO0];
Reed Kotler24032212012-10-05 18:27:54 +0000847}
848
849//
850// Format: MULT rx, ry MIPS16e
851// Purpose: Multiply Word
852// To multiply 32-bit signed integers.
853//
854def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> {
855 let isCommutable = 1;
856 let neverHasSideEffects = 1;
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000857 let Defs = [HI0, LO0];
Reed Kotler24032212012-10-05 18:27:54 +0000858}
859
860//
861// Format: MULTU rx, ry MIPS16e
862// Purpose: Multiply Unsigned Word
863// To multiply 32-bit unsigned integers.
864//
865def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> {
866 let isCommutable = 1;
867 let neverHasSideEffects = 1;
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000868 let Defs = [HI0, LO0];
Reed Kotler24032212012-10-05 18:27:54 +0000869}
870
871//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000872// Format: NEG rx, ry MIPS16e
873// Purpose: Negate
874// To negate an integer value.
875//
Reed Kotler4e1c6292012-10-26 16:18:19 +0000876def NegRxRy16: FUnaryRR16_ins<0b11101, "neg", IIAlu>;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000877
878//
879// Format: NOT rx, ry MIPS16e
880// Purpose: Not
881// To complement an integer value
882//
Reed Kotler4e1c6292012-10-26 16:18:19 +0000883def NotRxRy16: FUnaryRR16_ins<0b01111, "not", IIAlu>;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000884
885//
886// Format: OR rx, ry MIPS16e
887// Purpose: Or
888// To do a bitwise logical OR.
889//
890def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>;
891
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000892//
893// Format: RESTORE {ra,}{s0/s1/s0-1,}{framesize}
894// (All args are optional) MIPS16e
895// Purpose: Restore Registers and Deallocate Stack Frame
896// To deallocate a stack frame before exit from a subroutine,
897// restoring return address and static registers, and adjusting
898// stack
899//
900
901// fixed form for restoring RA and the frame
902// for direct object emitter, encoding needs to be adjusted for the
903// frame size
904//
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000905let ra=1, s=0,s0=1,s1=1 in
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000906def RestoreRaF16:
907 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
Reed Kotler9c285b32013-08-04 23:56:53 +0000908 "restore\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IILoad >, MayLoad {
Reed Kotler27a72292012-10-31 05:21:10 +0000909 let isCodeGenOnly = 1;
Reed Kotler9c285b32013-08-04 23:56:53 +0000910 let Defs = [S0, S1, S2, RA, SP];
Reed Kotler3aad7622012-12-19 04:06:15 +0000911 let Uses = [SP];
Reed Kotler27a72292012-10-31 05:21:10 +0000912}
913
914// Use Restore to increment SP since SP is not a Mip 16 register, this
915// is an easy way to do that which does not require a register.
916//
917let ra=0, s=0,s0=0,s1=0 in
918def RestoreIncSpF16:
919 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
920 "restore\t$frame_size", [], IILoad >, MayLoad {
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000921 let isCodeGenOnly = 1;
Reed Kotler3aad7622012-12-19 04:06:15 +0000922 let Defs = [SP];
923 let Uses = [SP];
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000924}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000925
926//
927// Format: SAVE {ra,}{s0/s1/s0-1,}{framesize} (All arguments are optional)
928// MIPS16e
929// Purpose: Save Registers and Set Up Stack Frame
930// To set up a stack frame on entry to a subroutine,
931// saving return address and static registers, and adjusting stack
932//
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000933let ra=1, s=1,s0=1,s1=1 in
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000934def SaveRaF16:
935 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
Reed Kotler9c285b32013-08-04 23:56:53 +0000936 "save\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IIStore >, MayStore {
Reed Kotler27a72292012-10-31 05:21:10 +0000937 let isCodeGenOnly = 1;
Reed Kotler9c285b32013-08-04 23:56:53 +0000938 let Uses = [RA, SP, S0, S1, S2];
Reed Kotler3aad7622012-12-19 04:06:15 +0000939 let Defs = [SP];
Reed Kotler27a72292012-10-31 05:21:10 +0000940}
941
942//
943// Use Save to decrement the SP by a constant since SP is not
944// a Mips16 register.
945//
946let ra=0, s=0,s0=0,s1=0 in
947def SaveDecSpF16:
948 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
949 "save\t$frame_size", [], IIStore >, MayStore {
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000950 let isCodeGenOnly = 1;
Reed Kotler3aad7622012-12-19 04:06:15 +0000951 let Uses = [SP];
952 let Defs = [SP];
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000953}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000954//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000955// Format: SB ry, offset(rx) MIPS16e
956// Purpose: Store Byte (Extended)
957// To store a byte to memory.
958//
Reed Kotler210ebe92012-09-28 02:26:24 +0000959def SbRxRyOffMemX16:
960 FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, IIStore>, MayStore;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000961
962//
Reed Kotler445d0ad2013-10-07 20:46:19 +0000963// Format: SEB rx MIPS16e
964// Purpose: Sign-Extend Byte
965// Sign-extend least significant byte in register rx.
966//
967def SebRx16
968 : FRR_SF16_ins<0b10001, 0b100, "seb", IIAlu>;
969
970//
971// Format: SEH rx MIPS16e
972// Purpose: Sign-Extend Halfword
973// Sign-extend least significant word in register rx.
974//
975def SehRx16
976 : FRR_SF16_ins<0b10001, 0b101, "seh", IIAlu>;
977
978//
Reed Kotler097556d2012-10-25 21:33:30 +0000979// The Sel(T) instructions are pseudos
980// T means that they use T8 implicitly.
981//
982//
983// Format: SelBeqZ rd, rs, rt
984// Purpose: if rt==0, do nothing
985// else rs = rt
986//
Reed Kotler61b474f2013-02-16 23:39:52 +0000987def SelBeqZ: Sel<"beqz">;
Reed Kotler097556d2012-10-25 21:33:30 +0000988
989//
990// Format: SelTBteqZCmp rd, rs, rl, rr
991// Purpose: b = Cmp rl, rr.
992// If b==0 then do nothing.
993// if b!=0 then rd = rs
994//
Reed Kotler61b474f2013-02-16 23:39:52 +0000995def SelTBteqZCmp: SelT<"bteqz", "cmp">;
Reed Kotler097556d2012-10-25 21:33:30 +0000996
997//
998// Format: SelTBteqZCmpi rd, rs, rl, rr
999// Purpose: b = Cmpi rl, imm.
1000// If b==0 then do nothing.
1001// if b!=0 then rd = rs
1002//
Reed Kotler61b474f2013-02-16 23:39:52 +00001003def SelTBteqZCmpi: SeliT<"bteqz", "cmpi">;
Reed Kotler097556d2012-10-25 21:33:30 +00001004
1005//
1006// Format: SelTBteqZSlt rd, rs, rl, rr
1007// Purpose: b = Slt rl, rr.
1008// If b==0 then do nothing.
1009// if b!=0 then rd = rs
1010//
Reed Kotler61b474f2013-02-16 23:39:52 +00001011def SelTBteqZSlt: SelT<"bteqz", "slt">;
Reed Kotler097556d2012-10-25 21:33:30 +00001012
1013//
1014// Format: SelTBteqZSlti rd, rs, rl, rr
1015// Purpose: b = Slti rl, imm.
1016// If b==0 then do nothing.
1017// if b!=0 then rd = rs
1018//
Reed Kotler61b474f2013-02-16 23:39:52 +00001019def SelTBteqZSlti: SeliT<"bteqz", "slti">;
Reed Kotler097556d2012-10-25 21:33:30 +00001020
1021//
1022// Format: SelTBteqZSltu rd, rs, rl, rr
1023// Purpose: b = Sltu rl, rr.
1024// If b==0 then do nothing.
1025// if b!=0 then rd = rs
1026//
Reed Kotler61b474f2013-02-16 23:39:52 +00001027def SelTBteqZSltu: SelT<"bteqz", "sltu">;
Reed Kotler097556d2012-10-25 21:33:30 +00001028
1029//
1030// Format: SelTBteqZSltiu rd, rs, rl, rr
1031// Purpose: b = Sltiu rl, imm.
1032// If b==0 then do nothing.
1033// if b!=0 then rd = rs
1034//
Reed Kotler61b474f2013-02-16 23:39:52 +00001035def SelTBteqZSltiu: SeliT<"bteqz", "sltiu">;
Reed Kotler097556d2012-10-25 21:33:30 +00001036
1037//
1038// Format: SelBnez rd, rs, rt
1039// Purpose: if rt!=0, do nothing
1040// else rs = rt
1041//
Reed Kotler61b474f2013-02-16 23:39:52 +00001042def SelBneZ: Sel<"bnez">;
Reed Kotler097556d2012-10-25 21:33:30 +00001043
1044//
1045// Format: SelTBtneZCmp rd, rs, rl, rr
1046// Purpose: b = Cmp rl, rr.
1047// If b!=0 then do nothing.
1048// if b0=0 then rd = rs
1049//
Reed Kotler61b474f2013-02-16 23:39:52 +00001050def SelTBtneZCmp: SelT<"btnez", "cmp">;
Reed Kotler097556d2012-10-25 21:33:30 +00001051
1052//
1053// Format: SelTBtnezCmpi rd, rs, rl, rr
1054// Purpose: b = Cmpi rl, imm.
1055// If b!=0 then do nothing.
1056// if b==0 then rd = rs
1057//
Reed Kotler61b474f2013-02-16 23:39:52 +00001058def SelTBtneZCmpi: SeliT<"btnez", "cmpi">;
Reed Kotler097556d2012-10-25 21:33:30 +00001059
1060//
1061// Format: SelTBtneZSlt rd, rs, rl, rr
1062// Purpose: b = Slt rl, rr.
1063// If b!=0 then do nothing.
1064// if b==0 then rd = rs
1065//
Reed Kotler61b474f2013-02-16 23:39:52 +00001066def SelTBtneZSlt: SelT<"btnez", "slt">;
Reed Kotler097556d2012-10-25 21:33:30 +00001067
1068//
1069// Format: SelTBtneZSlti rd, rs, rl, rr
1070// Purpose: b = Slti rl, imm.
1071// If b!=0 then do nothing.
1072// if b==0 then rd = rs
1073//
Reed Kotler61b474f2013-02-16 23:39:52 +00001074def SelTBtneZSlti: SeliT<"btnez", "slti">;
Reed Kotler097556d2012-10-25 21:33:30 +00001075
1076//
1077// Format: SelTBtneZSltu rd, rs, rl, rr
1078// Purpose: b = Sltu rl, rr.
1079// If b!=0 then do nothing.
1080// if b==0 then rd = rs
1081//
Reed Kotler61b474f2013-02-16 23:39:52 +00001082def SelTBtneZSltu: SelT<"btnez", "sltu">;
Reed Kotler097556d2012-10-25 21:33:30 +00001083
1084//
1085// Format: SelTBtneZSltiu rd, rs, rl, rr
1086// Purpose: b = Slti rl, imm.
1087// If b!=0 then do nothing.
1088// if b==0 then rd = rs
1089//
Reed Kotler61b474f2013-02-16 23:39:52 +00001090def SelTBtneZSltiu: SeliT<"btnez", "sltiu">;
Reed Kotler097556d2012-10-25 21:33:30 +00001091//
1092//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001093// Format: SH ry, offset(rx) MIPS16e
1094// Purpose: Store Halfword (Extended)
1095// To store a halfword to memory.
1096//
Reed Kotler210ebe92012-09-28 02:26:24 +00001097def ShRxRyOffMemX16:
1098 FEXT_RRI16_mem2_ins<0b11001, "sh", mem16, IIStore>, MayStore;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001099
1100//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001101// Format: SLL rx, ry, sa MIPS16e
1102// Purpose: Shift Word Left Logical (Extended)
1103// To execute a left-shift of a word by a fixed number of bits—0 to 31 bits.
1104//
1105def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>;
1106
1107//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001108// Format: SLLV ry, rx MIPS16e
1109// Purpose: Shift Word Left Logical Variable
1110// To execute a left-shift of a word by a variable number of bits.
1111//
1112def SllvRxRy16 : FRxRxRy16_ins<0b00100, "sllv", IIAlu>;
1113
Reed Kotler3e457f52013-02-19 03:56:57 +00001114// Format: SLTI rx, immediate MIPS16e
1115// Purpose: Set on Less Than Immediate
1116// To record the result of a less-than comparison with a constant.
1117//
1118//
Reed Kotler7b503c22013-02-20 05:45:15 +00001119def SltiRxImm16: FRI16R_ins<0b01010, "slti", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001120 let Defs = [T8];
1121}
1122
Reed Kotler164bb372012-10-23 01:35:48 +00001123//
1124// Format: SLTI rx, immediate MIPS16e
1125// Purpose: Set on Less Than Immediate (Extended)
1126// To record the result of a less-than comparison with a constant.
1127//
Reed Kotler3e457f52013-02-19 03:56:57 +00001128//
Reed Kotler7b503c22013-02-20 05:45:15 +00001129def SltiRxImmX16: FEXT_RI16R_ins<0b01010, "slti", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001130 let Defs = [T8];
1131}
1132
Reed Kotler61b474f2013-02-16 23:39:52 +00001133def SltiCCRxImmX16: FEXT_CCRXI16_ins<"slti">;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001134
Reed Kotler3e457f52013-02-19 03:56:57 +00001135// Format: SLTIU rx, immediate MIPS16e
1136// Purpose: Set on Less Than Immediate Unsigned
1137// To record the result of a less-than comparison with a constant.
1138//
1139//
Reed Kotler7b503c22013-02-20 05:45:15 +00001140def SltiuRxImm16: FRI16R_ins<0b01011, "sltiu", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001141 let Defs = [T8];
1142}
1143
1144//
1145// Format: SLTI rx, immediate MIPS16e
1146// Purpose: Set on Less Than Immediate Unsigned (Extended)
1147// To record the result of a less-than comparison with a constant.
1148//
1149//
Reed Kotler7b503c22013-02-20 05:45:15 +00001150def SltiuRxImmX16: FEXT_RI16R_ins<0b01011, "sltiu", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001151 let Defs = [T8];
1152}
Akira Hatanaka22bec282012-08-03 22:57:02 +00001153//
Reed Kotler164bb372012-10-23 01:35:48 +00001154// Format: SLTIU rx, immediate MIPS16e
1155// Purpose: Set on Less Than Immediate Unsigned (Extended)
1156// To record the result of a less-than comparison with a constant.
1157//
Reed Kotler61b474f2013-02-16 23:39:52 +00001158def SltiuCCRxImmX16: FEXT_CCRXI16_ins<"sltiu">;
Reed Kotler164bb372012-10-23 01:35:48 +00001159
1160//
1161// Format: SLT rx, ry MIPS16e
1162// Purpose: Set on Less Than
1163// To record the result of a less-than comparison.
1164//
Reed Kotler80070bd2013-02-23 23:37:03 +00001165def SltRxRy16: FRR16R_ins<0b00010, "slt", IIAlu>{
Reed Kotler7b503c22013-02-20 05:45:15 +00001166 let Defs = [T8];
1167}
Reed Kotler164bb372012-10-23 01:35:48 +00001168
Reed Kotler61b474f2013-02-16 23:39:52 +00001169def SltCCRxRy16: FCCRR16_ins<"slt">;
Reed Kotler164bb372012-10-23 01:35:48 +00001170
1171// Format: SLTU rx, ry MIPS16e
1172// Purpose: Set on Less Than Unsigned
1173// To record the result of an unsigned less-than comparison.
1174//
Reed Kotler80070bd2013-02-23 23:37:03 +00001175def SltuRxRy16: FRR16R_ins<0b00011, "sltu", IIAlu>{
Reed Kotler7b503c22013-02-20 05:45:15 +00001176 let Defs = [T8];
1177}
Reed Kotler6879e562013-02-18 04:55:38 +00001178
Reed Kotler61b474f2013-02-16 23:39:52 +00001179def SltuRxRyRz16: FRRTR16_ins<"sltu"> {
Reed Kotler287f0442012-10-26 04:46:26 +00001180 let isCodeGenOnly=1;
Reed Kotler7b503c22013-02-20 05:45:15 +00001181 let Defs = [T8];
Reed Kotler287f0442012-10-26 04:46:26 +00001182}
Reed Kotler164bb372012-10-23 01:35:48 +00001183
1184
Reed Kotler61b474f2013-02-16 23:39:52 +00001185def SltuCCRxRy16: FCCRR16_ins<"sltu">;
Reed Kotler164bb372012-10-23 01:35:48 +00001186//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001187// Format: SRAV ry, rx MIPS16e
1188// Purpose: Shift Word Right Arithmetic Variable
1189// To execute an arithmetic right-shift of a word by a variable
1190// number of bits.
1191//
1192def SravRxRy16: FRxRxRy16_ins<0b00111, "srav", IIAlu>;
1193
1194
1195//
1196// Format: SRA rx, ry, sa MIPS16e
1197// Purpose: Shift Word Right Arithmetic (Extended)
1198// To execute an arithmetic right-shift of a word by a fixed
1199// number of bits—1 to 8 bits.
1200//
1201def SraX16: FEXT_SHIFT16_ins<0b11, "sra", IIAlu>;
1202
1203
1204//
1205// Format: SRLV ry, rx MIPS16e
1206// Purpose: Shift Word Right Logical Variable
1207// To execute a logical right-shift of a word by a variable
1208// number of bits.
1209//
1210def SrlvRxRy16: FRxRxRy16_ins<0b00110, "srlv", IIAlu>;
1211
1212
1213//
1214// Format: SRL rx, ry, sa MIPS16e
1215// Purpose: Shift Word Right Logical (Extended)
1216// To execute a logical right-shift of a word by a fixed
1217// number of bits—1 to 31 bits.
1218//
1219def SrlX16: FEXT_SHIFT16_ins<0b10, "srl", IIAlu>;
1220
1221//
1222// Format: SUBU rz, rx, ry MIPS16e
1223// Purpose: Subtract Unsigned Word
1224// To subtract 32-bit integers
1225//
1226def SubuRxRyRz16: FRRR16_ins<0b11, "subu", IIAlu>, ArithLogic16Defs<0>;
1227
1228//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001229// Format: SW ry, offset(rx) MIPS16e
1230// Purpose: Store Word (Extended)
1231// To store a word to memory.
1232//
Reed Kotler210ebe92012-09-28 02:26:24 +00001233def SwRxRyOffMemX16:
1234 FEXT_RRI16_mem2_ins<0b11011, "sw", mem16, IIStore>, MayStore;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001235
1236//
Reed Kotler210ebe92012-09-28 02:26:24 +00001237// Format: SW rx, offset(sp) MIPS16e
1238// Purpose: Store Word rx (SP-Relative)
1239// To store an SP-relative word to memory.
1240//
Reed Kotler30cedf62013-08-04 01:13:25 +00001241def SwRxSpImmX16: FEXT_RI16_SP_Store_explicit_ins
1242 <0b11010, "sw", IIStore>, MayStore;
Reed Kotler210ebe92012-09-28 02:26:24 +00001243
1244//
1245//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001246// Format: XOR rx, ry MIPS16e
1247// Purpose: Xor
1248// To do a bitwise logical XOR.
1249//
1250def XorRxRxRy16: FRxRxRy16_ins<0b01110, "xor", IIAlu>, ArithLogic16Defs<1>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001251
Akira Hatanaka765c3122012-06-21 20:39:10 +00001252class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> {
1253 let Predicates = [InMips16Mode];
1254}
1255
Akira Hatanaka22bec282012-08-03 22:57:02 +00001256// Unary Arith/Logic
1257//
1258class ArithLogicU_pat<PatFrag OpNode, Instruction I> :
1259 Mips16Pat<(OpNode CPU16Regs:$r),
1260 (I CPU16Regs:$r)>;
Akira Hatanakabff8e312012-05-31 02:59:44 +00001261
Akira Hatanaka22bec282012-08-03 22:57:02 +00001262def: ArithLogicU_pat<not, NotRxRy16>;
1263def: ArithLogicU_pat<ineg, NegRxRy16>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001264
Akira Hatanaka22bec282012-08-03 22:57:02 +00001265class ArithLogic16_pat<SDNode OpNode, Instruction I> :
1266 Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r),
1267 (I CPU16Regs:$l, CPU16Regs:$r)>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001268
Akira Hatanaka22bec282012-08-03 22:57:02 +00001269def: ArithLogic16_pat<add, AdduRxRyRz16>;
1270def: ArithLogic16_pat<and, AndRxRxRy16>;
Reed Kotler24032212012-10-05 18:27:54 +00001271def: ArithLogic16_pat<mul, MultRxRyRz16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001272def: ArithLogic16_pat<or, OrRxRxRy16>;
1273def: ArithLogic16_pat<sub, SubuRxRyRz16>;
1274def: ArithLogic16_pat<xor, XorRxRxRy16>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001275
Akira Hatanaka22bec282012-08-03 22:57:02 +00001276// Arithmetic and logical instructions with 2 register operands.
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001277
Akira Hatanaka22bec282012-08-03 22:57:02 +00001278class ArithLogicI16_pat<SDNode OpNode, PatFrag imm_type, Instruction I> :
1279 Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm),
1280 (I CPU16Regs:$in, imm_type:$imm)>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001281
Reed Kotlerb9bf8dc2013-02-08 21:42:56 +00001282def: ArithLogicI16_pat<add, immSExt8, AddiuRxRxImm16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001283def: ArithLogicI16_pat<add, immSExt16, AddiuRxRxImmX16>;
1284def: ArithLogicI16_pat<shl, immZExt5, SllX16>;
1285def: ArithLogicI16_pat<srl, immZExt5, SrlX16>;
1286def: ArithLogicI16_pat<sra, immZExt5, SraX16>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001287
Akira Hatanaka22bec282012-08-03 22:57:02 +00001288class shift_rotate_reg16_pat<SDNode OpNode, Instruction I> :
1289 Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra),
1290 (I CPU16Regs:$r, CPU16Regs:$ra)>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001291
Akira Hatanaka22bec282012-08-03 22:57:02 +00001292def: shift_rotate_reg16_pat<shl, SllvRxRy16>;
1293def: shift_rotate_reg16_pat<sra, SravRxRy16>;
1294def: shift_rotate_reg16_pat<srl, SrlvRxRy16>;
1295
1296class LoadM16_pat<PatFrag OpNode, Instruction I> :
Reed Kotler3589dd72012-10-28 06:02:37 +00001297 Mips16Pat<(OpNode addr16:$addr), (I addr16:$addr)>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001298
1299def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16>;
1300def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16>;
Akira Hatanaka3e7ba762012-09-15 01:52:08 +00001301def: LoadM16_pat<sextloadi16, LhRxRyOffMemX16>;
1302def: LoadM16_pat<zextloadi16, LhuRxRyOffMemX16>;
1303def: LoadM16_pat<load, LwRxRyOffMemX16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001304
1305class StoreM16_pat<PatFrag OpNode, Instruction I> :
Reed Kotler3589dd72012-10-28 06:02:37 +00001306 Mips16Pat<(OpNode CPU16Regs:$r, addr16:$addr),
1307 (I CPU16Regs:$r, addr16:$addr)>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001308
1309def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16>;
Akira Hatanaka3e7ba762012-09-15 01:52:08 +00001310def: StoreM16_pat<truncstorei16, ShRxRyOffMemX16>;
1311def: StoreM16_pat<store, SwRxRyOffMemX16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001312
Reed Kotler67439242012-10-17 22:29:54 +00001313// Unconditional branch
1314class UncondBranch16_pat<SDNode OpNode, Instruction I>:
1315 Mips16Pat<(OpNode bb:$imm16), (I bb:$imm16)> {
Reed Kotlerec60f7d2013-02-07 03:49:51 +00001316 let Predicates = [InMips16Mode];
Reed Kotler67439242012-10-17 22:29:54 +00001317 }
Akira Hatanakabff8e312012-05-31 02:59:44 +00001318
Reed Kotlerf8933f82013-02-02 04:07:35 +00001319def : Mips16Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1320 (Jal16 tglobaladdr:$dst)>;
1321
Reed Kotler4a230ff2013-02-07 04:34:51 +00001322def : Mips16Pat<(MipsJmpLink (i32 texternalsym:$dst)),
1323 (Jal16 texternalsym:$dst)>;
1324
Reed Kotlere6c31572012-10-28 23:08:07 +00001325// Indirect branch
1326def: Mips16Pat<
Jack Carter7ab15fa2013-01-19 02:00:40 +00001327 (brind CPU16Regs:$rs),
1328 (JrcRx16 CPU16Regs:$rs)>;
Reed Kotlere6c31572012-10-28 23:08:07 +00001329
Akira Hatanakabff8e312012-05-31 02:59:44 +00001330// Jump and Link (Call)
Reed Kotlera8117532012-10-30 00:54:49 +00001331let isCall=1, hasDelaySlot=0 in
Akira Hatanakabff8e312012-05-31 02:59:44 +00001332def JumpLinkReg16:
Akira Hatanakaf640f042012-07-17 22:55:34 +00001333 FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs),
Reed Kotlera8117532012-10-30 00:54:49 +00001334 "jalrc \t$rs", [(MipsJmpLink CPU16Regs:$rs)], IIBranch>;
Akira Hatanakaf640f042012-07-17 22:55:34 +00001335
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001336// Mips16 pseudos
1337let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1,
1338 hasExtraSrcRegAllocReq = 1 in
1339def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>;
1340
Reed Kotler67439242012-10-17 22:29:54 +00001341
Reed Kotler164bb372012-10-23 01:35:48 +00001342// setcc patterns
1343
1344class SetCC_R16<PatFrag cond_op, Instruction I>:
1345 Mips16Pat<(cond_op CPU16Regs:$rx, CPU16Regs:$ry),
1346 (I CPU16Regs:$rx, CPU16Regs:$ry)>;
1347
1348class SetCC_I16<PatFrag cond_op, PatLeaf imm_type, Instruction I>:
1349 Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16),
Reed Kotler097556d2012-10-25 21:33:30 +00001350 (I CPU16Regs:$rx, imm_type:$imm16)>;
Reed Kotler164bb372012-10-23 01:35:48 +00001351
Reed Kotler3589dd72012-10-28 06:02:37 +00001352
1353def: Mips16Pat<(i32 addr16:$addr),
1354 (AddiuRxRyOffMemX16 addr16:$addr)>;
1355
1356
Reed Kotlere47873a2012-10-26 03:09:34 +00001357// Large (>16 bit) immediate loads
1358def : Mips16Pat<(i32 imm:$imm),
1359 (OrRxRxRy16 (SllX16 (LiRxImmX16 (HI16 imm:$imm)), 16),
1360 (LiRxImmX16 (LO16 imm:$imm)))>;
Reed Kotler164bb372012-10-23 01:35:48 +00001361
Reed Kotler287f0442012-10-26 04:46:26 +00001362// Carry MipsPatterns
1363def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs),
1364 (SubuRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
1365def : Mips16Pat<(addc CPU16Regs:$lhs, CPU16Regs:$rhs),
1366 (AdduRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
1367def : Mips16Pat<(addc CPU16Regs:$src, immSExt16:$imm),
1368 (AddiuRxRxImmX16 CPU16Regs:$src, imm:$imm)>;
1369
Reed Kotler67439242012-10-17 22:29:54 +00001370//
1371// Some branch conditional patterns are not generated by llvm at this time.
1372// Some are for seemingly arbitrary reasons not used: i.e. with signed number
1373// comparison they are used and for unsigned a different pattern is used.
1374// I am pushing upstream from the full mips16 port and it seemed that I needed
1375// these earlier and the mips32 port has these but now I cannot create test
1376// cases that use these patterns. While I sort this all out I will leave these
1377// extra patterns commented out and if I can be sure they are really not used,
1378// I will delete the code. I don't want to check the code in uncommented without
1379// a valid test case. In some cases, the compiler is generating patterns with
1380// setcc instead and earlier I had implemented setcc first so may have masked
1381// the problem. The setcc variants are suboptimal for mips16 so I may wantto
1382// figure out how to enable the brcond patterns or else possibly new
1383// combinations of of brcond and setcc.
1384//
1385//
1386// bcond-seteq
1387//
1388def: Mips16Pat
1389 <(brcond (i32 (seteq CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1390 (BteqzT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1391 >;
1392
1393
1394def: Mips16Pat
1395 <(brcond (i32 (seteq CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1396 (BteqzT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$targ16)
1397 >;
1398
1399def: Mips16Pat
1400 <(brcond (i32 (seteq CPU16Regs:$rx, 0)), bb:$targ16),
1401 (BeqzRxImmX16 CPU16Regs:$rx, bb:$targ16)
1402 >;
1403
1404//
1405// bcond-setgt (do we need to have this pair of setlt, setgt??)
1406//
1407def: Mips16Pat
1408 <(brcond (i32 (setgt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1409 (BtnezT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16)
1410 >;
1411
1412//
1413// bcond-setge
1414//
1415def: Mips16Pat
1416 <(brcond (i32 (setge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1417 (BteqzT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1418 >;
1419
1420//
1421// never called because compiler transforms a >= k to a > (k-1)
Reed Kotler164bb372012-10-23 01:35:48 +00001422def: Mips16Pat
1423 <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1424 (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16)
1425 >;
Reed Kotler67439242012-10-17 22:29:54 +00001426
1427//
1428// bcond-setlt
1429//
1430def: Mips16Pat
1431 <(brcond (i32 (setlt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1432 (BtnezT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1433 >;
1434
1435def: Mips16Pat
1436 <(brcond (i32 (setlt CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1437 (BtnezT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16)
1438 >;
1439
1440//
1441// bcond-setle
1442//
1443def: Mips16Pat
1444 <(brcond (i32 (setle CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1445 (BteqzT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16)
1446 >;
1447
1448//
1449// bcond-setne
1450//
1451def: Mips16Pat
1452 <(brcond (i32 (setne CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1453 (BtnezT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1454 >;
1455
1456def: Mips16Pat
1457 <(brcond (i32 (setne CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1458 (BtnezT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$targ16)
1459 >;
1460
1461def: Mips16Pat
1462 <(brcond (i32 (setne CPU16Regs:$rx, 0)), bb:$targ16),
1463 (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16)
1464 >;
1465
1466//
1467// This needs to be there but I forget which code will generate it
1468//
1469def: Mips16Pat
1470 <(brcond CPU16Regs:$rx, bb:$targ16),
1471 (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16)
1472 >;
1473
1474//
1475
1476//
1477// bcond-setugt
1478//
1479//def: Mips16Pat
1480// <(brcond (i32 (setugt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1481// (BtnezT8SltuX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16)
1482// >;
1483
1484//
1485// bcond-setuge
1486//
1487//def: Mips16Pat
1488// <(brcond (i32 (setuge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1489// (BteqzT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1490// >;
1491
1492
1493//
1494// bcond-setult
1495//
1496//def: Mips16Pat
1497// <(brcond (i32 (setult CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1498// (BtnezT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1499// >;
1500
1501def: UncondBranch16_pat<br, BimmX16>;
1502
Akira Hatanaka765c3122012-06-21 20:39:10 +00001503// Small immediates
Reed Kotler67439242012-10-17 22:29:54 +00001504def: Mips16Pat<(i32 immSExt16:$in),
1505 (AddiuRxRxImmX16 (Move32R16 ZERO), immSExt16:$in)>;
1506
Akira Hatanaka22bec282012-08-03 22:57:02 +00001507def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>;
Akira Hatanaka64626fc2012-07-26 02:24:43 +00001508
Reed Kotlercf11c592012-10-12 02:01:09 +00001509//
1510// MipsDivRem
1511//
1512def: Mips16Pat
Akira Hatanakabe8612f2013-03-30 01:36:35 +00001513 <(MipsDivRem16 CPU16Regs:$rx, CPU16Regs:$ry),
Reed Kotlercf11c592012-10-12 02:01:09 +00001514 (DivRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1515
1516//
1517// MipsDivRemU
1518//
1519def: Mips16Pat
Akira Hatanakabe8612f2013-03-30 01:36:35 +00001520 <(MipsDivRemU16 CPU16Regs:$rx, CPU16Regs:$ry),
Reed Kotlercf11c592012-10-12 02:01:09 +00001521 (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1522
Reed Kotler097556d2012-10-25 21:33:30 +00001523// signed a,b
1524// x = (a>=b)?x:y
1525//
1526// if !(a < b) x = y
1527//
1528def : Mips16Pat<(select (i32 (setge CPU16Regs:$a, CPU16Regs:$b)),
1529 CPU16Regs:$x, CPU16Regs:$y),
1530 (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1531 CPU16Regs:$a, CPU16Regs:$b)>;
1532
1533// signed a,b
1534// x = (a>b)?x:y
1535//
1536// if (b < a) x = y
1537//
1538def : Mips16Pat<(select (i32 (setgt CPU16Regs:$a, CPU16Regs:$b)),
1539 CPU16Regs:$x, CPU16Regs:$y),
1540 (SelTBtneZSlt CPU16Regs:$x, CPU16Regs:$y,
1541 CPU16Regs:$b, CPU16Regs:$a)>;
1542
1543// unsigned a,b
1544// x = (a>=b)?x:y
1545//
1546// if !(a < b) x = y;
1547//
1548def : Mips16Pat<
1549 (select (i32 (setuge CPU16Regs:$a, CPU16Regs:$b)),
1550 CPU16Regs:$x, CPU16Regs:$y),
1551 (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1552 CPU16Regs:$a, CPU16Regs:$b)>;
1553
1554// unsigned a,b
1555// x = (a>b)?x:y
1556//
1557// if (b < a) x = y
1558//
1559def : Mips16Pat<(select (i32 (setugt CPU16Regs:$a, CPU16Regs:$b)),
1560 CPU16Regs:$x, CPU16Regs:$y),
1561 (SelTBtneZSltu CPU16Regs:$x, CPU16Regs:$y,
1562 CPU16Regs:$b, CPU16Regs:$a)>;
1563
1564// signed
1565// x = (a >= k)?x:y
1566// due to an llvm optimization, i don't think that this will ever
1567// be used. This is transformed into x = (a > k-1)?x:y
1568//
1569//
1570
1571//def : Mips16Pat<
1572// (select (i32 (setge CPU16Regs:$lhs, immSExt16:$rhs)),
1573// CPU16Regs:$T, CPU16Regs:$F),
1574// (SelTBteqZSlti CPU16Regs:$T, CPU16Regs:$F,
1575// CPU16Regs:$lhs, immSExt16:$rhs)>;
1576
1577//def : Mips16Pat<
1578// (select (i32 (setuge CPU16Regs:$lhs, immSExt16:$rhs)),
1579// CPU16Regs:$T, CPU16Regs:$F),
1580// (SelTBteqZSltiu CPU16Regs:$T, CPU16Regs:$F,
1581// CPU16Regs:$lhs, immSExt16:$rhs)>;
1582
1583// signed
1584// x = (a < k)?x:y
1585//
1586// if !(a < k) x = y;
1587//
1588def : Mips16Pat<
1589 (select (i32 (setlt CPU16Regs:$a, immSExt16:$b)),
1590 CPU16Regs:$x, CPU16Regs:$y),
1591 (SelTBtneZSlti CPU16Regs:$x, CPU16Regs:$y,
1592 CPU16Regs:$a, immSExt16:$b)>;
1593
1594
1595//
1596//
1597// signed
1598// x = (a <= b)? x : y
1599//
1600// if (b < a) x = y
1601//
1602def : Mips16Pat<(select (i32 (setle CPU16Regs:$a, CPU16Regs:$b)),
1603 CPU16Regs:$x, CPU16Regs:$y),
1604 (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1605 CPU16Regs:$b, CPU16Regs:$a)>;
1606
1607//
1608// unnsigned
1609// x = (a <= b)? x : y
1610//
1611// if (b < a) x = y
1612//
1613def : Mips16Pat<(select (i32 (setule CPU16Regs:$a, CPU16Regs:$b)),
1614 CPU16Regs:$x, CPU16Regs:$y),
1615 (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1616 CPU16Regs:$b, CPU16Regs:$a)>;
1617
1618//
1619// signed/unsigned
1620// x = (a == b)? x : y
1621//
1622// if (a != b) x = y
1623//
1624def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, CPU16Regs:$b)),
1625 CPU16Regs:$x, CPU16Regs:$y),
1626 (SelTBteqZCmp CPU16Regs:$x, CPU16Regs:$y,
1627 CPU16Regs:$b, CPU16Regs:$a)>;
1628
1629//
1630// signed/unsigned
1631// x = (a == 0)? x : y
1632//
1633// if (a != 0) x = y
1634//
1635def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, 0)),
1636 CPU16Regs:$x, CPU16Regs:$y),
1637 (SelBeqZ CPU16Regs:$x, CPU16Regs:$y,
1638 CPU16Regs:$a)>;
1639
1640
1641//
1642// signed/unsigned
1643// x = (a == k)? x : y
1644//
1645// if (a != k) x = y
1646//
1647def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, immZExt16:$k)),
1648 CPU16Regs:$x, CPU16Regs:$y),
1649 (SelTBteqZCmpi CPU16Regs:$x, CPU16Regs:$y,
1650 CPU16Regs:$a, immZExt16:$k)>;
1651
1652
1653//
1654// signed/unsigned
1655// x = (a != b)? x : y
1656//
1657// if (a == b) x = y
1658//
1659//
1660def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, CPU16Regs:$b)),
1661 CPU16Regs:$x, CPU16Regs:$y),
1662 (SelTBtneZCmp CPU16Regs:$x, CPU16Regs:$y,
1663 CPU16Regs:$b, CPU16Regs:$a)>;
1664
1665//
1666// signed/unsigned
1667// x = (a != 0)? x : y
1668//
1669// if (a == 0) x = y
1670//
1671def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, 0)),
1672 CPU16Regs:$x, CPU16Regs:$y),
1673 (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1674 CPU16Regs:$a)>;
1675
1676// signed/unsigned
1677// x = (a)? x : y
1678//
1679// if (!a) x = y
1680//
1681def : Mips16Pat<(select CPU16Regs:$a,
1682 CPU16Regs:$x, CPU16Regs:$y),
1683 (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1684 CPU16Regs:$a)>;
1685
1686
1687//
1688// signed/unsigned
1689// x = (a != k)? x : y
1690//
1691// if (a == k) x = y
1692//
1693def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, immZExt16:$k)),
1694 CPU16Regs:$x, CPU16Regs:$y),
1695 (SelTBtneZCmpi CPU16Regs:$x, CPU16Regs:$y,
1696 CPU16Regs:$a, immZExt16:$k)>;
Reed Kotlercf11c592012-10-12 02:01:09 +00001697
Reed Kotler164bb372012-10-23 01:35:48 +00001698//
1699// When writing C code to test setxx these patterns,
1700// some will be transformed into
1701// other things. So we test using C code but using -O3 and -O0
1702//
1703// seteq
1704//
1705def : Mips16Pat
1706 <(seteq CPU16Regs:$lhs,CPU16Regs:$rhs),
1707 (SltiuCCRxImmX16 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1)>;
1708
1709def : Mips16Pat
1710 <(seteq CPU16Regs:$lhs, 0),
1711 (SltiuCCRxImmX16 CPU16Regs:$lhs, 1)>;
1712
1713
1714//
1715// setge
1716//
1717
1718def: Mips16Pat
1719 <(setge CPU16Regs:$lhs, CPU16Regs:$rhs),
1720 (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1721 (LiRxImmX16 1))>;
1722
1723//
1724// For constants, llvm transforms this to:
1725// x > (k -1) and then reverses the operands to use setlt. So this pattern
1726// is not used now by the compiler. (Presumably checking that k-1 does not
1727// overflow). The compiler never uses this at a the current time, due to
1728// other optimizations.
1729//
1730//def: Mips16Pat
1731// <(setge CPU16Regs:$lhs, immSExt16:$rhs),
1732// (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs),
1733// (LiRxImmX16 1))>;
1734
1735// This catches the x >= -32768 case by transforming it to x > -32769
1736//
1737def: Mips16Pat
1738 <(setgt CPU16Regs:$lhs, -32769),
1739 (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768),
1740 (LiRxImmX16 1))>;
1741
1742//
1743// setgt
1744//
1745//
1746
1747def: Mips16Pat
1748 <(setgt CPU16Regs:$lhs, CPU16Regs:$rhs),
1749 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1750
1751//
1752// setle
1753//
1754def: Mips16Pat
1755 <(setle CPU16Regs:$lhs, CPU16Regs:$rhs),
Reed Kotler7b503c22013-02-20 05:45:15 +00001756 (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImm16 1))>;
Reed Kotler164bb372012-10-23 01:35:48 +00001757
1758//
1759// setlt
1760//
1761def: SetCC_R16<setlt, SltCCRxRy16>;
1762
1763def: SetCC_I16<setlt, immSExt16, SltiCCRxImmX16>;
1764
1765//
1766// setne
1767//
1768def : Mips16Pat
1769 <(setne CPU16Regs:$lhs,CPU16Regs:$rhs),
1770 (SltuCCRxRy16 (LiRxImmX16 0),
1771 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs))>;
1772
1773
1774//
1775// setuge
1776//
1777def: Mips16Pat
1778 <(setuge CPU16Regs:$lhs, CPU16Regs:$rhs),
1779 (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1780 (LiRxImmX16 1))>;
1781
1782// this pattern will never be used because the compiler will transform
1783// x >= k to x > (k - 1) and then use SLT
1784//
1785//def: Mips16Pat
1786// <(setuge CPU16Regs:$lhs, immZExt16:$rhs),
1787// (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs),
Reed Kotler097556d2012-10-25 21:33:30 +00001788// (LiRxImmX16 1))>;
Reed Kotler164bb372012-10-23 01:35:48 +00001789
1790//
1791// setugt
1792//
1793def: Mips16Pat
1794 <(setugt CPU16Regs:$lhs, CPU16Regs:$rhs),
1795 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1796
1797//
1798// setule
1799//
1800def: Mips16Pat
1801 <(setule CPU16Regs:$lhs, CPU16Regs:$rhs),
1802 (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>;
1803
1804//
1805// setult
1806//
1807def: SetCC_R16<setult, SltuCCRxRy16>;
1808
1809def: SetCC_I16<setult, immSExt16, SltiuCCRxImmX16>;
1810
Reed Kotler7e4d9962012-10-27 00:57:14 +00001811def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)),
1812 (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>;
1813
1814// hi/lo relocs
Reed Kotler1b5b5c92013-10-04 22:01:40 +00001815def : Mips16Pat<(MipsHi tblockaddress:$in),
1816 (SllX16 (LiRxImmX16 tblockaddress:$in), 16)>;
Reed Kotler7b503c22013-02-20 05:45:15 +00001817def : Mips16Pat<(MipsHi tglobaladdr:$in),
Reed Kotlerf8933f82013-02-02 04:07:35 +00001818 (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>;
Reed Kotler9cb8e7b2013-02-13 08:32:14 +00001819def : Mips16Pat<(MipsHi tjumptable:$in),
1820 (SllX16 (LiRxImmX16 tjumptable:$in), 16)>;
Jack Carter7ab15fa2013-01-19 02:00:40 +00001821def : Mips16Pat<(MipsHi tglobaltlsaddr:$in),
Reed Kotler7e4d9962012-10-27 00:57:14 +00001822 (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>;
1823
Reed Kotler1b5b5c92013-10-04 22:01:40 +00001824def : Mips16Pat<(MipsLo tblockaddress:$in), (LiRxImmX16 tblockaddress:$in)>;
1825
Reed Kotlerb650f6b2012-10-26 22:57:32 +00001826// wrapper_pic
1827class Wrapper16Pat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1828 Mips16Pat<(MipsWrapper RC:$gp, node:$in),
1829 (ADDiuOp RC:$gp, node:$in)>;
1830
1831
Reed Kotler3589dd72012-10-28 06:02:37 +00001832def : Wrapper16Pat<tglobaladdr, AddiuRxRxImmX16, CPU16Regs>;
Reed Kotlerb650f6b2012-10-26 22:57:32 +00001833def : Wrapper16Pat<tglobaltlsaddr, AddiuRxRxImmX16, CPU16Regs>;
1834
Reed Kotler740981e2012-10-29 19:39:04 +00001835def : Mips16Pat<(i32 (extloadi8 addr16:$src)),
1836 (LbuRxRyOffMemX16 addr16:$src)>;
1837def : Mips16Pat<(i32 (extloadi16 addr16:$src)),
Chandler Carruthf12e3a62012-11-30 11:45:22 +00001838 (LhuRxRyOffMemX16 addr16:$src)>;
Reed Kotlerbb870e22013-08-07 04:00:26 +00001839
1840def: Mips16Pat<(trap), (Break16)>;
1841
Reed Kotler445d0ad2013-10-07 20:46:19 +00001842def : Mips16Pat<(sext_inreg CPU16Regs:$val, i8),
1843 (SebRx16 CPU16Regs:$val)>;
1844
1845def : Mips16Pat<(sext_inreg CPU16Regs:$val, i16),
1846 (SehRx16 CPU16Regs:$val)>;
1847
Reed Kotlerd6aadc72013-09-18 22:46:09 +00001848def GotPrologue16:
1849 MipsPseudo16<
1850 (outs CPU16Regs:$rh, CPU16Regs:$rl),
1851 (ins simm16:$immHi, simm16:$immLo),
1852 ".align 2\n\tli\t$rh, $immHi\n\taddiu\t$rl, $$pc, $immLo\n ",[]> ;