blob: e11b1a75e3e9aea28d82f0d77e63f7a45c6bb648 [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
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;
93}
94
Reed Kotlerf8933f82013-02-02 04:07:35 +000095// JAL and JALX instruction format
96//
97class FJAL16_ins<bits<1> _X, string asmstr,
98 InstrItinClass itin>:
99 FJAL16<_X, (outs), (ins simm20:$imm),
100 !strconcat(asmstr, "\t$imm\n\tnop"),[],
101 itin> {
102 let isCodeGenOnly=1;
103}
Reed Kotler164bb372012-10-23 01:35:48 +0000104//
Reed Kotler67439242012-10-17 22:29:54 +0000105// EXT-I instruction format
106//
107class FEXT_I16_ins<bits<5> eop, string asmstr, InstrItinClass itin> :
108 FEXT_I16<eop, (outs), (ins brtarget:$imm16),
109 !strconcat(asmstr, "\t$imm16"),[], itin>;
110
111//
112// EXT-I8 instruction format
113//
114
115class FEXT_I816_ins_base<bits<3> _func, string asmstr,
116 string asmstr2, InstrItinClass itin>:
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000117 FEXT_I816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
Reed Kotler67439242012-10-17 22:29:54 +0000118 [], itin>;
119
120class FEXT_I816_ins<bits<3> _func, string asmstr,
121 InstrItinClass itin>:
122 FEXT_I816_ins_base<_func, asmstr, "\t$imm", itin>;
123
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000124class FEXT_I816_SP_ins<bits<3> _func, string asmstr,
125 InstrItinClass itin>:
126 FEXT_I816_ins_base<_func, asmstr, "\t$$sp, $imm", itin>;
127
Reed Kotler67439242012-10-17 22:29:54 +0000128//
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000129// Assembler formats in alphabetical order.
130// Natural and pseudos are mixed together.
131//
Reed Kotler164bb372012-10-23 01:35:48 +0000132// Compare two registers and place result in CC
133// Implicit use of T8
134//
135// CC-RR Instruction format
136//
Reed Kotler61b474f2013-02-16 23:39:52 +0000137class FCCRR16_ins<string asmstr> :
138 MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, CPU16Regs:$ry),
139 !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$cc, $$t8"), []> {
Reed Kotler164bb372012-10-23 01:35:48 +0000140 let isCodeGenOnly=1;
141}
142
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000143//
Reed Kotler210ebe92012-09-28 02:26:24 +0000144// EXT-RI instruction format
145//
146
147class FEXT_RI16_ins_base<bits<5> _op, string asmstr, string asmstr2,
148 InstrItinClass itin>:
149 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins simm16:$imm),
150 !strconcat(asmstr, asmstr2), [], itin>;
151
152class FEXT_RI16_ins<bits<5> _op, string asmstr,
153 InstrItinClass itin>:
154 FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
155
Reed Kotler7b503c22013-02-20 05:45:15 +0000156class FEXT_RI16R_ins_base<bits<5> _op, string asmstr, string asmstr2,
157 InstrItinClass itin>:
158 FEXT_RI16<_op, (outs ), (ins CPU16Regs:$rx, simm16:$imm),
159 !strconcat(asmstr, asmstr2), [], itin>;
160
161class FEXT_RI16R_ins<bits<5> _op, string asmstr,
162 InstrItinClass itin>:
163 FEXT_RI16R_ins_base<_op, asmstr, "\t$rx, $imm", itin>;
164
Reed Kotler210ebe92012-09-28 02:26:24 +0000165class FEXT_RI16_PC_ins<bits<5> _op, string asmstr, InstrItinClass itin>:
166 FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $$pc, $imm", itin>;
167
Reed Kotler67439242012-10-17 22:29:54 +0000168class FEXT_RI16_B_ins<bits<5> _op, string asmstr,
169 InstrItinClass itin>:
170 FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm),
171 !strconcat(asmstr, "\t$rx, $imm"), [], itin>;
172
Reed Kotler210ebe92012-09-28 02:26:24 +0000173class FEXT_2RI16_ins<bits<5> _op, string asmstr,
174 InstrItinClass itin>:
175 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm),
176 !strconcat(asmstr, "\t$rx, $imm"), [], itin> {
177 let Constraints = "$rx_ = $rx";
178}
Reed Kotler24032212012-10-05 18:27:54 +0000179
Reed Kotler67439242012-10-17 22:29:54 +0000180
Reed Kotler210ebe92012-09-28 02:26:24 +0000181// this has an explicit sp argument that we ignore to work around a problem
182// in the compiler
183class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr,
184 InstrItinClass itin>:
185 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm),
Reed Kotler24032212012-10-05 18:27:54 +0000186 !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
Reed Kotler210ebe92012-09-28 02:26:24 +0000187
188//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000189// EXT-RRI instruction format
190//
191
192class FEXT_RRI16_mem_ins<bits<5> op, string asmstr, Operand MemOpnd,
193 InstrItinClass itin>:
194 FEXT_RRI16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr),
195 !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
196
Akira Hatanaka22bec282012-08-03 22:57:02 +0000197class FEXT_RRI16_mem2_ins<bits<5> op, string asmstr, Operand MemOpnd,
198 InstrItinClass itin>:
199 FEXT_RRI16<op, (outs ), (ins CPU16Regs:$ry, MemOpnd:$addr),
200 !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
201
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000202//
Reed Kotler3589dd72012-10-28 06:02:37 +0000203//
204// EXT-RRI-A instruction format
205//
206
207class FEXT_RRI_A16_mem_ins<bits<1> op, string asmstr, Operand MemOpnd,
208 InstrItinClass itin>:
209 FEXT_RRI_A16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr),
210 !strconcat(asmstr, "\t$ry, $addr"), [], itin>;
211
212//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000213// EXT-SHIFT instruction format
214//
215class FEXT_SHIFT16_ins<bits<2> _f, string asmstr, InstrItinClass itin>:
Akira Hatanaka22bec282012-08-03 22:57:02 +0000216 FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, shamt:$sa),
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000217 !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>;
218
Reed Kotler67439242012-10-17 22:29:54 +0000219//
220// EXT-T8I8
221//
Reed Kotler61b474f2013-02-16 23:39:52 +0000222class FEXT_T8I816_ins<string asmstr, string asmstr2>:
223 MipsPseudo16<(outs),
224 (ins CPU16Regs:$rx, CPU16Regs:$ry, brtarget:$imm),
225 !strconcat(asmstr2, !strconcat("\t$rx, $ry\n\t",
226 !strconcat(asmstr, "\t$imm"))),[]> {
Reed Kotler67439242012-10-17 22:29:54 +0000227 let isCodeGenOnly=1;
Reed Kotlere2bead72013-02-24 06:16:39 +0000228 let usesCustomInserter = 1;
Reed Kotler67439242012-10-17 22:29:54 +0000229}
230
231//
232// EXT-T8I8I
233//
Reed Kotler61b474f2013-02-16 23:39:52 +0000234class FEXT_T8I8I16_ins<string asmstr, string asmstr2>:
235 MipsPseudo16<(outs),
236 (ins CPU16Regs:$rx, simm16:$imm, brtarget:$targ),
237 !strconcat(asmstr2, !strconcat("\t$rx, $imm\n\t",
238 !strconcat(asmstr, "\t$targ"))), []> {
Reed Kotler67439242012-10-17 22:29:54 +0000239 let isCodeGenOnly=1;
Reed Kotler7a86b3d2013-02-24 23:17:51 +0000240 let usesCustomInserter = 1;
Reed Kotler67439242012-10-17 22:29:54 +0000241}
242//
243
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000244
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000245//
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000246// I8_MOVR32 instruction format (used only by the MOVR32 instructio
247//
248class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>:
249 FI8_MOVR3216<(outs CPU16Regs:$rz), (ins CPURegs:$r32),
250 !strconcat(asmstr, "\t$rz, $r32"), [], itin>;
251
252//
253// I8_MOV32R instruction format (used only by MOV32R instruction)
254//
255
256class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>:
257 FI8_MOV32R16<(outs CPURegs:$r32), (ins CPU16Regs:$rz),
258 !strconcat(asmstr, "\t$r32, $rz"), [], itin>;
259
260//
261// This are pseudo formats for multiply
262// This first one can be changed to non pseudo now.
263//
264// MULT
265//
266class FMULT16_ins<string asmstr, InstrItinClass itin> :
267 MipsPseudo16<(outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
268 !strconcat(asmstr, "\t$rx, $ry"), []>;
269
270//
271// MULT-LO
272//
273class FMULT16_LO_ins<string asmstr, InstrItinClass itin> :
274 MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
275 !strconcat(asmstr, "\t$rx, $ry\n\tmflo\t$rz"), []> {
276 let isCodeGenOnly=1;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000277}
278
279//
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000280// RR-type instruction format
281//
282
283class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
284 FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
285 !strconcat(asmstr, "\t$rx, $ry"), [], itin> {
286}
Reed Kotlercf11c592012-10-12 02:01:09 +0000287
Reed Kotler80070bd2013-02-23 23:37:03 +0000288class FRR16R_ins<bits<5> f, string asmstr, InstrItinClass itin> :
289 FRR16<f, (outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
290 !strconcat(asmstr, "\t$rx, $ry"), [], itin> {
291}
292
Reed Kotler61b474f2013-02-16 23:39:52 +0000293class FRRTR16_ins<string asmstr> :
294 MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
295 !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$rz, $$t8"), []> ;
Reed Kotler287f0442012-10-26 04:46:26 +0000296
Reed Kotlercf11c592012-10-12 02:01:09 +0000297//
298// maybe refactor but need a $zero as a dummy first parameter
299//
300class FRR16_div_ins<bits<5> f, string asmstr, InstrItinClass itin> :
301 FRR16<f, (outs ), (ins CPU16Regs:$rx, CPU16Regs:$ry),
302 !strconcat(asmstr, "\t$$zero, $rx, $ry"), [], itin> ;
303
Reed Kotler4e1c6292012-10-26 16:18:19 +0000304class FUnaryRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
305 FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
306 !strconcat(asmstr, "\t$rx, $ry"), [], itin> ;
307
308
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000309class FRR16_M_ins<bits<5> f, string asmstr,
310 InstrItinClass itin> :
311 FRR16<f, (outs CPU16Regs:$rx), (ins),
312 !strconcat(asmstr, "\t$rx"), [], itin>;
313
314class FRxRxRy16_ins<bits<5> f, string asmstr,
315 InstrItinClass itin> :
316 FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
317 !strconcat(asmstr, "\t$rz, $ry"),
318 [], itin> {
319 let Constraints = "$rx = $rz";
320}
321
322let rx=0 in
323class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_,
324 string asmstr, InstrItinClass itin>:
325 FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t $$ra"),
326 [], itin> ;
327
Reed Kotlere6c31572012-10-28 23:08:07 +0000328
329class FRR16_JALRC_ins<bits<1> nd, bits<1> l, bits<1> ra,
330 string asmstr, InstrItinClass itin>:
Jack Carter7ab15fa2013-01-19 02:00:40 +0000331 FRR16_JALRC<nd, l, ra, (outs), (ins CPU16Regs:$rx),
Reed Kotlere6c31572012-10-28 23:08:07 +0000332 !strconcat(asmstr, "\t $rx"), [], itin> ;
333
Reed Kotler0f2e44a2012-10-10 01:58:16 +0000334//
335// RRR-type instruction format
336//
337
338class FRRR16_ins<bits<2> _f, string asmstr, InstrItinClass itin> :
339 FRRR16<_f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
340 !strconcat(asmstr, "\t$rz, $rx, $ry"), [], itin>;
341
342//
Reed Kotler097556d2012-10-25 21:33:30 +0000343// These Sel patterns support the generation of conditional move
344// pseudo instructions.
345//
346// The nomenclature uses the components making up the pseudo and may
347// be a bit counter intuitive when compared with the end result we seek.
348// For example using a bqez in the example directly below results in the
349// conditional move being done if the tested register is not zero.
350// I considered in easier to check by keeping the pseudo consistent with
351// it's components but it could have been done differently.
352//
353// The simplest case is when can test and operand directly and do the
354// conditional move based on a simple mips16 conditional
355// branch instruction.
356// for example:
357// if $op == beqz or bnez:
358//
359// $op1 $rt, .+4
360// move $rd, $rs
361//
362// if $op == beqz, then if $rt != 0, then the conditional assignment
363// $rd = $rs is done.
364
365// if $op == bnez, then if $rt == 0, then the conditional assignment
366// $rd = $rs is done.
367//
368// So this pseudo class only has one operand, i.e. op
369//
Reed Kotler61b474f2013-02-16 23:39:52 +0000370class Sel<string op>:
371 MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs,
372 CPU16Regs:$rt),
373 !strconcat(op, "\t$rt, .+4\n\t\n\tmove $rd, $rs"), []> {
374 //let isCodeGenOnly=1;
Reed Kotler097556d2012-10-25 21:33:30 +0000375 let Constraints = "$rd = $rd_";
Reed Kotler97ba5f22013-02-21 04:22:38 +0000376 let usesCustomInserter = 1;
Reed Kotler097556d2012-10-25 21:33:30 +0000377}
378
379//
380// The next two instruction classes allow for an operand which tests
381// two operands and returns a value in register T8 and
382//then does a conditional branch based on the value of T8
383//
384
385// op2 can be cmpi or slti/sltiu
386// op1 can bteqz or btnez
387// the operands for op2 are a register and a signed constant
388//
389// $op2 $t, $imm ;test register t and branch conditionally
390// $op1 .+4 ;op1 is a conditional branch
391// move $rd, $rs
392//
393//
Reed Kotler61b474f2013-02-16 23:39:52 +0000394class SeliT<string op1, string op2>:
395 MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs,
396 CPU16Regs:$rl, simm16:$imm),
397 !strconcat(op2,
398 !strconcat("\t$rl, $imm\n\t",
399 !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
Reed Kotler097556d2012-10-25 21:33:30 +0000400 let isCodeGenOnly=1;
401 let Constraints = "$rd = $rd_";
Reed Kotler4416cda2013-02-22 05:10:51 +0000402 let usesCustomInserter = 1;
Reed Kotler097556d2012-10-25 21:33:30 +0000403}
404
405//
406// op2 can be cmp or slt/sltu
407// op1 can be bteqz or btnez
408// the operands for op2 are two registers
409// op1 is a conditional branch
410//
411//
412// $op2 $rl, $rr ;test registers rl,rr
413// $op1 .+4 ;op2 is a conditional branch
414// move $rd, $rs
415//
416//
Reed Kotler61b474f2013-02-16 23:39:52 +0000417class SelT<string op1, string op2>:
Reed Kotler7b503c22013-02-20 05:45:15 +0000418 MipsPseudo16<(outs CPU16Regs:$rd_),
Reed Kotler61b474f2013-02-16 23:39:52 +0000419 (ins CPU16Regs:$rd, CPU16Regs:$rs,
Reed Kotler097556d2012-10-25 21:33:30 +0000420 CPU16Regs:$rl, CPU16Regs:$rr),
Reed Kotler61b474f2013-02-16 23:39:52 +0000421 !strconcat(op2,
422 !strconcat("\t$rl, $rr\n\t",
423 !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
Reed Kotler097556d2012-10-25 21:33:30 +0000424 let isCodeGenOnly=1;
425 let Constraints = "$rd = $rd_";
Reed Kotlerdacee2b2013-02-23 03:09:56 +0000426 let usesCustomInserter = 1;
Reed Kotler097556d2012-10-25 21:33:30 +0000427}
428
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000429//
430// 32 bit constant
431//
432def imm32: Operand<i32>;
433
434def Constant32:
435 MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>;
Jack Carter7ab15fa2013-01-19 02:00:40 +0000436
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000437def LwConstant32:
438 MipsPseudo16<(outs), (ins CPU16Regs:$rx, imm32:$imm),
439 "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;
440
Reed Kotler097556d2012-10-25 21:33:30 +0000441
442//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000443// Some general instruction class info
444//
445//
446
447class ArithLogic16Defs<bit isCom=0> {
448 bits<5> shamt = 0;
449 bit isCommutable = isCom;
450 bit isReMaterializable = 1;
451 bit neverHasSideEffects = 1;
452}
453
Reed Kotler67439242012-10-17 22:29:54 +0000454class branch16 {
455 bit isBranch = 1;
456 bit isTerminator = 1;
457 bit isBarrier = 1;
458}
459
460class cbranch16 {
461 bit isBranch = 1;
462 bit isTerminator = 1;
463}
464
Reed Kotler210ebe92012-09-28 02:26:24 +0000465class MayLoad {
466 bit mayLoad = 1;
467}
468
469class MayStore {
470 bit mayStore = 1;
471}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000472//
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000473
Reed Kotler61b474f2013-02-16 23:39:52 +0000474
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000475// Format: ADDIU rx, immediate MIPS16e
476// Purpose: Add Immediate Unsigned Word (2-Operand, Extended)
477// To add a constant to a 32-bit integer.
478//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000479def AddiuRxImmX16: FEXT_RI16_ins<0b01001, "addiu", IIAlu>;
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000480
Reed Kotlerb9bf8dc2013-02-08 21:42:56 +0000481def AddiuRxRxImm16: F2RI16_ins<0b01001, "addiu", IIAlu>,
482 ArithLogic16Defs<0> {
483 let AddedComplexity = 5;
484}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000485def AddiuRxRxImmX16: FEXT_2RI16_ins<0b01001, "addiu", IIAlu>,
Reed Kotlerec8a5492013-02-14 03:05:25 +0000486 ArithLogic16Defs<0> {
487 let isCodeGenOnly = 1;
488}
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000489
Reed Kotler3589dd72012-10-28 06:02:37 +0000490def AddiuRxRyOffMemX16:
491 FEXT_RRI_A16_mem_ins<0, "addiu", mem16_ea, IIAlu>;
492
Akira Hatanaka64626fc2012-07-26 02:24:43 +0000493//
494
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000495// Format: ADDIU rx, pc, immediate MIPS16e
496// Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended)
497// To add a constant to the program counter.
498//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000499def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>;
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000500
501//
502// Format: ADDIU sp, immediate MIPS16e
503// Purpose: Add Immediate Unsigned Word (2-Operand, SP-Relative, Extended)
504// To add a constant to the stack pointer.
505//
Reed Kotlerf662cff2013-02-13 20:28:27 +0000506def AddiuSpImm16
507 : FI816_SP_ins<0b011, "addiu", IIAlu> {
508 let Defs = [SP];
509 let Uses = [SP];
510 let AddedComplexity = 5;
511}
512
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000513def AddiuSpImmX16
514 : FEXT_I816_SP_ins<0b011, "addiu", IIAlu> {
515 let Defs = [SP];
516 let Uses = [SP];
Jack Carter7ab15fa2013-01-19 02:00:40 +0000517}
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000518
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000519//
520// Format: ADDU rz, rx, ry MIPS16e
521// Purpose: Add Unsigned Word (3-Operand)
522// To add 32-bit integers.
523//
524
Akira Hatanaka22bec282012-08-03 22:57:02 +0000525def AdduRxRyRz16: FRRR16_ins<01, "addu", IIAlu>, ArithLogic16Defs<1>;
526
527//
528// Format: AND rx, ry MIPS16e
529// Purpose: AND
530// To do a bitwise logical AND.
531
532def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>;
Reed Kotler67439242012-10-17 22:29:54 +0000533
534
535//
536// Format: BEQZ rx, offset MIPS16e
Reed Kotler97ba5f22013-02-21 04:22:38 +0000537// Purpose: Branch on Equal to Zero
538// To test a GPR then do a PC-relative conditional branch.
539//
540def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16;
541
542
543//
544// Format: BEQZ rx, offset MIPS16e
Reed Kotler67439242012-10-17 22:29:54 +0000545// Purpose: Branch on Equal to Zero (Extended)
546// To test a GPR then do a PC-relative conditional branch.
547//
548def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16;
549
550// Format: B offset MIPS16e
551// Purpose: Unconditional Branch
552// To do an unconditional PC-relative branch.
553//
554def BimmX16: FEXT_I16_ins<0b00010, "b", IIAlu>, branch16;
555
556//
557// Format: BNEZ rx, offset MIPS16e
Reed Kotler97ba5f22013-02-21 04:22:38 +0000558// Purpose: Branch on Not Equal to Zero
559// To test a GPR then do a PC-relative conditional branch.
560//
561def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
562
563//
564// Format: BNEZ rx, offset MIPS16e
Reed Kotler67439242012-10-17 22:29:54 +0000565// Purpose: Branch on Not Equal to Zero (Extended)
566// To test a GPR then do a PC-relative conditional branch.
567//
568def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
569
570//
571// Format: BTEQZ offset MIPS16e
572// Purpose: Branch on T Equal to Zero (Extended)
573// To test special register T then do a PC-relative conditional branch.
574//
Reed Kotlercb374092013-02-18 00:59:04 +0000575def BteqzX16: FEXT_I816_ins<0b000, "bteqz", IIAlu>, cbranch16 {
576 let Uses = [T8];
577}
Reed Kotler67439242012-10-17 22:29:54 +0000578
Reed Kotler61b474f2013-02-16 23:39:52 +0000579def BteqzT8CmpX16: FEXT_T8I816_ins<"bteqz", "cmp">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000580
Reed Kotler61b474f2013-02-16 23:39:52 +0000581def BteqzT8CmpiX16: FEXT_T8I8I16_ins<"bteqz", "cmpi">,
Reed Kotler67439242012-10-17 22:29:54 +0000582 cbranch16;
583
Reed Kotler61b474f2013-02-16 23:39:52 +0000584def BteqzT8SltX16: FEXT_T8I816_ins<"bteqz", "slt">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000585
Reed Kotler61b474f2013-02-16 23:39:52 +0000586def BteqzT8SltuX16: FEXT_T8I816_ins<"bteqz", "sltu">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000587
Reed Kotler61b474f2013-02-16 23:39:52 +0000588def BteqzT8SltiX16: FEXT_T8I8I16_ins<"bteqz", "slti">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000589
Reed Kotler61b474f2013-02-16 23:39:52 +0000590def BteqzT8SltiuX16: FEXT_T8I8I16_ins<"bteqz", "sltiu">,
Reed Kotler67439242012-10-17 22:29:54 +0000591 cbranch16;
592
593//
594// Format: BTNEZ offset MIPS16e
595// Purpose: Branch on T Not Equal to Zero (Extended)
596// To test special register T then do a PC-relative conditional branch.
597//
Reed Kotlercb374092013-02-18 00:59:04 +0000598def BtnezX16: FEXT_I816_ins<0b001, "btnez", IIAlu> ,cbranch16 {
599 let Uses = [T8];
600}
Reed Kotler67439242012-10-17 22:29:54 +0000601
Reed Kotler61b474f2013-02-16 23:39:52 +0000602def BtnezT8CmpX16: FEXT_T8I816_ins<"btnez", "cmp">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000603
Reed Kotler61b474f2013-02-16 23:39:52 +0000604def BtnezT8CmpiX16: FEXT_T8I8I16_ins<"btnez", "cmpi">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000605
Reed Kotler61b474f2013-02-16 23:39:52 +0000606def BtnezT8SltX16: FEXT_T8I816_ins<"btnez", "slt">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000607
Reed Kotler61b474f2013-02-16 23:39:52 +0000608def BtnezT8SltuX16: FEXT_T8I816_ins<"btnez", "sltu">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000609
Reed Kotler61b474f2013-02-16 23:39:52 +0000610def BtnezT8SltiX16: FEXT_T8I8I16_ins<"btnez", "slti">, cbranch16;
Reed Kotler67439242012-10-17 22:29:54 +0000611
Reed Kotler61b474f2013-02-16 23:39:52 +0000612def BtnezT8SltiuX16: FEXT_T8I8I16_ins<"btnez", "sltiu">,
Reed Kotler67439242012-10-17 22:29:54 +0000613 cbranch16;
614
Reed Kotlercf11c592012-10-12 02:01:09 +0000615//
Reed Kotlercb374092013-02-18 00:59:04 +0000616// Format: CMP rx, ry MIPS16e
617// Purpose: Compare
618// To compare the contents of two GPRs.
619//
Reed Kotler80070bd2013-02-23 23:37:03 +0000620def CmpRxRy16: FRR16R_ins<0b01010, "cmp", IIAlu> {
Reed Kotlercb374092013-02-18 00:59:04 +0000621 let Defs = [T8];
622}
623
Reed Kotlerd8217192013-02-19 00:20:58 +0000624//
625// Format: CMPI rx, immediate MIPS16e
626// Purpose: Compare Immediate
627// To compare a constant with the contents of a GPR.
628//
Reed Kotler80070bd2013-02-23 23:37:03 +0000629def CmpiRxImm16: FRI16R_ins<0b01110, "cmpi", IIAlu> {
Reed Kotlerd8217192013-02-19 00:20:58 +0000630 let Defs = [T8];
631}
632
633//
634// Format: CMPI rx, immediate MIPS16e
635// Purpose: Compare Immediate (Extended)
636// To compare a constant with the contents of a GPR.
637//
Reed Kotler80070bd2013-02-23 23:37:03 +0000638def CmpiRxImmX16: FEXT_RI16R_ins<0b01110, "cmpi", IIAlu> {
Reed Kotlerd8217192013-02-19 00:20:58 +0000639 let Defs = [T8];
640}
641
Reed Kotlercb374092013-02-18 00:59:04 +0000642
643//
Reed Kotlercf11c592012-10-12 02:01:09 +0000644// Format: DIV rx, ry MIPS16e
645// Purpose: Divide Word
646// To divide 32-bit signed integers.
647//
648def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> {
649 let Defs = [HI, LO];
650}
651
652//
653// Format: DIVU rx, ry MIPS16e
654// Purpose: Divide Unsigned Word
655// To divide 32-bit unsigned integers.
656//
657def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> {
658 let Defs = [HI, LO];
659}
Reed Kotlerf8933f82013-02-02 04:07:35 +0000660//
661// Format: JAL target MIPS16e
662// Purpose: Jump and Link
663// To execute a procedure call within the current 256 MB-aligned
664// region and preserve the current ISA.
665//
Reed Kotlercf11c592012-10-12 02:01:09 +0000666
Reed Kotlerf8933f82013-02-02 04:07:35 +0000667def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> {
668 let isBranch = 1;
669 let hasDelaySlot = 0; // not true, but we add the nop for now
670 let isTerminator=1;
671 let isBarrier=1;
672}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000673
674//
675// Format: JR ra MIPS16e
676// Purpose: Jump Register Through Register ra
677// To execute a branch to the instruction address in the return
678// address register.
679//
680
Reed Kotler3589dd72012-10-28 06:02:37 +0000681def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIAlu> {
682 let isBranch = 1;
683 let isIndirectBranch = 1;
684 let hasDelaySlot = 1;
685 let isTerminator=1;
686 let isBarrier=1;
687}
Reed Kotlere6c31572012-10-28 23:08:07 +0000688
Reed Kotlerec8a5492013-02-14 03:05:25 +0000689def JrcRa16: FRR16_JALRC_RA_only_ins<1, 1, "jrc", IIAlu> {
Reed Kotlera8117532012-10-30 00:54:49 +0000690 let isBranch = 1;
691 let isIndirectBranch = 1;
692 let isTerminator=1;
693 let isBarrier=1;
694}
695
Reed Kotlere6c31572012-10-28 23:08:07 +0000696def JrcRx16: FRR16_JALRC_ins<1, 1, 0, "jrc", IIAlu> {
697 let isBranch = 1;
698 let isIndirectBranch = 1;
699 let isTerminator=1;
700 let isBarrier=1;
701}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000702//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000703// Format: LB ry, offset(rx) MIPS16e
704// Purpose: Load Byte (Extended)
705// To load a byte from memory as a signed value.
706//
Reed Kotlerec8a5492013-02-14 03:05:25 +0000707def LbRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lb", mem16, IILoad>, MayLoad{
708 let isCodeGenOnly = 1;
709}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000710
711//
712// Format: LBU ry, offset(rx) MIPS16e
713// Purpose: Load Byte Unsigned (Extended)
714// To load a byte from memory as a unsigned value.
715//
Reed Kotler210ebe92012-09-28 02:26:24 +0000716def LbuRxRyOffMemX16:
Reed Kotlerec8a5492013-02-14 03:05:25 +0000717 FEXT_RRI16_mem_ins<0b10100, "lbu", mem16, IILoad>, MayLoad {
718 let isCodeGenOnly = 1;
719}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000720
721//
722// Format: LH ry, offset(rx) MIPS16e
723// Purpose: Load Halfword signed (Extended)
724// To load a halfword from memory as a signed value.
725//
Reed Kotlerec8a5492013-02-14 03:05:25 +0000726def LhRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lh", mem16, IILoad>, MayLoad{
727 let isCodeGenOnly = 1;
728}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000729
730//
731// Format: LHU ry, offset(rx) MIPS16e
732// Purpose: Load Halfword unsigned (Extended)
733// To load a halfword from memory as an unsigned value.
734//
Reed Kotler210ebe92012-09-28 02:26:24 +0000735def LhuRxRyOffMemX16:
Reed Kotlerec8a5492013-02-14 03:05:25 +0000736 FEXT_RRI16_mem_ins<0b10100, "lhu", mem16, IILoad>, MayLoad {
737 let isCodeGenOnly = 1;
738}
Akira Hatanaka22bec282012-08-03 22:57:02 +0000739
740//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000741// Format: LI rx, immediate MIPS16e
Reed Kotler7b503c22013-02-20 05:45:15 +0000742// Purpose: Load Immediate
743// To load a constant into a GPR.
744//
745def LiRxImm16: FRI16_ins<0b01101, "li", IIAlu>;
746
747//
748// Format: LI rx, immediate MIPS16e
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000749// Purpose: Load Immediate (Extended)
750// To load a constant into a GPR.
751//
752def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>;
753
754//
755// Format: LW ry, offset(rx) MIPS16e
756// Purpose: Load Word (Extended)
757// To load a word from memory as a signed value.
758//
Reed Kotlerec8a5492013-02-14 03:05:25 +0000759def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IILoad>, MayLoad{
760 let isCodeGenOnly = 1;
761}
Reed Kotler210ebe92012-09-28 02:26:24 +0000762
763// Format: LW rx, offset(sp) MIPS16e
764// Purpose: Load Word (SP-Relative, Extended)
765// To load an SP-relative word from memory as a signed value.
766//
Reed Kotler3aad7622012-12-19 04:06:15 +0000767def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10110, "lw", IILoad>, MayLoad{
768 let Uses = [SP];
769}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000770
771//
772// Format: MOVE r32, rz MIPS16e
773// Purpose: Move
774// To move the contents of a GPR to a GPR.
775//
Akira Hatanaka0fbaec22012-09-14 03:21:56 +0000776def Move32R16: FI8_MOV32R16_ins<"move", IIAlu>;
777
778//
779// Format: MOVE ry, r32 MIPS16e
780//Purpose: Move
781// To move the contents of a GPR to a GPR.
782//
783def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000784
785//
Reed Kotler24032212012-10-05 18:27:54 +0000786// Format: MFHI rx MIPS16e
787// Purpose: Move From HI Register
788// To copy the special purpose HI register to a GPR.
789//
790def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> {
791 let Uses = [HI];
792 let neverHasSideEffects = 1;
793}
794
795//
796// Format: MFLO rx MIPS16e
797// Purpose: Move From LO Register
798// To copy the special purpose LO register to a GPR.
799//
800def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> {
801 let Uses = [LO];
802 let neverHasSideEffects = 1;
803}
804
805//
806// Pseudo Instruction for mult
807//
808def MultRxRy16: FMULT16_ins<"mult", IIAlu> {
809 let isCommutable = 1;
810 let neverHasSideEffects = 1;
811 let Defs = [HI, LO];
812}
813
814def MultuRxRy16: FMULT16_ins<"multu", IIAlu> {
815 let isCommutable = 1;
816 let neverHasSideEffects = 1;
817 let Defs = [HI, LO];
818}
819
820//
821// Format: MULT rx, ry MIPS16e
822// Purpose: Multiply Word
823// To multiply 32-bit signed integers.
824//
825def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> {
826 let isCommutable = 1;
827 let neverHasSideEffects = 1;
828 let Defs = [HI, LO];
829}
830
831//
832// Format: MULTU rx, ry MIPS16e
833// Purpose: Multiply Unsigned Word
834// To multiply 32-bit unsigned integers.
835//
836def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> {
837 let isCommutable = 1;
838 let neverHasSideEffects = 1;
839 let Defs = [HI, LO];
840}
841
842//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000843// Format: NEG rx, ry MIPS16e
844// Purpose: Negate
845// To negate an integer value.
846//
Reed Kotler4e1c6292012-10-26 16:18:19 +0000847def NegRxRy16: FUnaryRR16_ins<0b11101, "neg", IIAlu>;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000848
849//
850// Format: NOT rx, ry MIPS16e
851// Purpose: Not
852// To complement an integer value
853//
Reed Kotler4e1c6292012-10-26 16:18:19 +0000854def NotRxRy16: FUnaryRR16_ins<0b01111, "not", IIAlu>;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000855
856//
857// Format: OR rx, ry MIPS16e
858// Purpose: Or
859// To do a bitwise logical OR.
860//
861def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>;
862
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000863//
864// Format: RESTORE {ra,}{s0/s1/s0-1,}{framesize}
865// (All args are optional) MIPS16e
866// Purpose: Restore Registers and Deallocate Stack Frame
867// To deallocate a stack frame before exit from a subroutine,
868// restoring return address and static registers, and adjusting
869// stack
870//
871
872// fixed form for restoring RA and the frame
873// for direct object emitter, encoding needs to be adjusted for the
874// frame size
875//
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000876let ra=1, s=0,s0=1,s1=1 in
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000877def RestoreRaF16:
878 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
Reed Kotler27a72292012-10-31 05:21:10 +0000879 "restore\t$$ra, $$s0, $$s1, $frame_size", [], IILoad >, MayLoad {
880 let isCodeGenOnly = 1;
Reed Kotler3aad7622012-12-19 04:06:15 +0000881 let Defs = [S0, S1, RA, SP];
882 let Uses = [SP];
Reed Kotler27a72292012-10-31 05:21:10 +0000883}
884
885// Use Restore to increment SP since SP is not a Mip 16 register, this
886// is an easy way to do that which does not require a register.
887//
888let ra=0, s=0,s0=0,s1=0 in
889def RestoreIncSpF16:
890 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
891 "restore\t$frame_size", [], IILoad >, MayLoad {
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000892 let isCodeGenOnly = 1;
Reed Kotler3aad7622012-12-19 04:06:15 +0000893 let Defs = [SP];
894 let Uses = [SP];
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000895}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000896
897//
898// Format: SAVE {ra,}{s0/s1/s0-1,}{framesize} (All arguments are optional)
899// MIPS16e
900// Purpose: Save Registers and Set Up Stack Frame
901// To set up a stack frame on entry to a subroutine,
902// saving return address and static registers, and adjusting stack
903//
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000904let ra=1, s=1,s0=1,s1=1 in
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000905def SaveRaF16:
906 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
Reed Kotler27a72292012-10-31 05:21:10 +0000907 "save\t$$ra, $$s0, $$s1, $frame_size", [], IIStore >, MayStore {
908 let isCodeGenOnly = 1;
Reed Kotler3aad7622012-12-19 04:06:15 +0000909 let Uses = [RA, SP, S0, S1];
910 let Defs = [SP];
Reed Kotler27a72292012-10-31 05:21:10 +0000911}
912
913//
914// Use Save to decrement the SP by a constant since SP is not
915// a Mips16 register.
916//
917let ra=0, s=0,s0=0,s1=0 in
918def SaveDecSpF16:
919 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
920 "save\t$frame_size", [], IIStore >, MayStore {
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000921 let isCodeGenOnly = 1;
Reed Kotler3aad7622012-12-19 04:06:15 +0000922 let Uses = [SP];
923 let Defs = [SP];
Akira Hatanakacd04e2b2012-09-21 01:08:16 +0000924}
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +0000925//
Akira Hatanaka22bec282012-08-03 22:57:02 +0000926// Format: SB ry, offset(rx) MIPS16e
927// Purpose: Store Byte (Extended)
928// To store a byte to memory.
929//
Reed Kotler210ebe92012-09-28 02:26:24 +0000930def SbRxRyOffMemX16:
931 FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, IIStore>, MayStore;
Akira Hatanaka22bec282012-08-03 22:57:02 +0000932
933//
Reed Kotler097556d2012-10-25 21:33:30 +0000934// The Sel(T) instructions are pseudos
935// T means that they use T8 implicitly.
936//
937//
938// Format: SelBeqZ rd, rs, rt
939// Purpose: if rt==0, do nothing
940// else rs = rt
941//
Reed Kotler61b474f2013-02-16 23:39:52 +0000942def SelBeqZ: Sel<"beqz">;
Reed Kotler097556d2012-10-25 21:33:30 +0000943
944//
945// Format: SelTBteqZCmp rd, rs, rl, rr
946// Purpose: b = Cmp rl, rr.
947// If b==0 then do nothing.
948// if b!=0 then rd = rs
949//
Reed Kotler61b474f2013-02-16 23:39:52 +0000950def SelTBteqZCmp: SelT<"bteqz", "cmp">;
Reed Kotler097556d2012-10-25 21:33:30 +0000951
952//
953// Format: SelTBteqZCmpi rd, rs, rl, rr
954// Purpose: b = Cmpi rl, imm.
955// If b==0 then do nothing.
956// if b!=0 then rd = rs
957//
Reed Kotler61b474f2013-02-16 23:39:52 +0000958def SelTBteqZCmpi: SeliT<"bteqz", "cmpi">;
Reed Kotler097556d2012-10-25 21:33:30 +0000959
960//
961// Format: SelTBteqZSlt rd, rs, rl, rr
962// Purpose: b = Slt rl, rr.
963// If b==0 then do nothing.
964// if b!=0 then rd = rs
965//
Reed Kotler61b474f2013-02-16 23:39:52 +0000966def SelTBteqZSlt: SelT<"bteqz", "slt">;
Reed Kotler097556d2012-10-25 21:33:30 +0000967
968//
969// Format: SelTBteqZSlti rd, rs, rl, rr
970// Purpose: b = Slti rl, imm.
971// If b==0 then do nothing.
972// if b!=0 then rd = rs
973//
Reed Kotler61b474f2013-02-16 23:39:52 +0000974def SelTBteqZSlti: SeliT<"bteqz", "slti">;
Reed Kotler097556d2012-10-25 21:33:30 +0000975
976//
977// Format: SelTBteqZSltu rd, rs, rl, rr
978// Purpose: b = Sltu rl, rr.
979// If b==0 then do nothing.
980// if b!=0 then rd = rs
981//
Reed Kotler61b474f2013-02-16 23:39:52 +0000982def SelTBteqZSltu: SelT<"bteqz", "sltu">;
Reed Kotler097556d2012-10-25 21:33:30 +0000983
984//
985// Format: SelTBteqZSltiu rd, rs, rl, rr
986// Purpose: b = Sltiu rl, imm.
987// If b==0 then do nothing.
988// if b!=0 then rd = rs
989//
Reed Kotler61b474f2013-02-16 23:39:52 +0000990def SelTBteqZSltiu: SeliT<"bteqz", "sltiu">;
Reed Kotler097556d2012-10-25 21:33:30 +0000991
992//
993// Format: SelBnez rd, rs, rt
994// Purpose: if rt!=0, do nothing
995// else rs = rt
996//
Reed Kotler61b474f2013-02-16 23:39:52 +0000997def SelBneZ: Sel<"bnez">;
Reed Kotler097556d2012-10-25 21:33:30 +0000998
999//
1000// Format: SelTBtneZCmp rd, rs, rl, rr
1001// Purpose: b = Cmp rl, rr.
1002// If b!=0 then do nothing.
1003// if b0=0 then rd = rs
1004//
Reed Kotler61b474f2013-02-16 23:39:52 +00001005def SelTBtneZCmp: SelT<"btnez", "cmp">;
Reed Kotler097556d2012-10-25 21:33:30 +00001006
1007//
1008// Format: SelTBtnezCmpi rd, rs, rl, rr
1009// Purpose: b = Cmpi rl, imm.
1010// If b!=0 then do nothing.
1011// if b==0 then rd = rs
1012//
Reed Kotler61b474f2013-02-16 23:39:52 +00001013def SelTBtneZCmpi: SeliT<"btnez", "cmpi">;
Reed Kotler097556d2012-10-25 21:33:30 +00001014
1015//
1016// Format: SelTBtneZSlt rd, rs, rl, rr
1017// Purpose: b = Slt rl, rr.
1018// If b!=0 then do nothing.
1019// if b==0 then rd = rs
1020//
Reed Kotler61b474f2013-02-16 23:39:52 +00001021def SelTBtneZSlt: SelT<"btnez", "slt">;
Reed Kotler097556d2012-10-25 21:33:30 +00001022
1023//
1024// Format: SelTBtneZSlti rd, rs, rl, rr
1025// Purpose: b = Slti rl, imm.
1026// If b!=0 then do nothing.
1027// if b==0 then rd = rs
1028//
Reed Kotler61b474f2013-02-16 23:39:52 +00001029def SelTBtneZSlti: SeliT<"btnez", "slti">;
Reed Kotler097556d2012-10-25 21:33:30 +00001030
1031//
1032// Format: SelTBtneZSltu rd, rs, rl, rr
1033// Purpose: b = Sltu rl, rr.
1034// If b!=0 then do nothing.
1035// if b==0 then rd = rs
1036//
Reed Kotler61b474f2013-02-16 23:39:52 +00001037def SelTBtneZSltu: SelT<"btnez", "sltu">;
Reed Kotler097556d2012-10-25 21:33:30 +00001038
1039//
1040// Format: SelTBtneZSltiu rd, rs, rl, rr
1041// Purpose: b = Slti rl, imm.
1042// If b!=0 then do nothing.
1043// if b==0 then rd = rs
1044//
Reed Kotler61b474f2013-02-16 23:39:52 +00001045def SelTBtneZSltiu: SeliT<"btnez", "sltiu">;
Reed Kotler097556d2012-10-25 21:33:30 +00001046//
1047//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001048// Format: SH ry, offset(rx) MIPS16e
1049// Purpose: Store Halfword (Extended)
1050// To store a halfword to memory.
1051//
Reed Kotler210ebe92012-09-28 02:26:24 +00001052def ShRxRyOffMemX16:
1053 FEXT_RRI16_mem2_ins<0b11001, "sh", mem16, IIStore>, MayStore;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001054
1055//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001056// Format: SLL rx, ry, sa MIPS16e
1057// Purpose: Shift Word Left Logical (Extended)
1058// To execute a left-shift of a word by a fixed number of bits—0 to 31 bits.
1059//
1060def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>;
1061
1062//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001063// Format: SLLV ry, rx MIPS16e
1064// Purpose: Shift Word Left Logical Variable
1065// To execute a left-shift of a word by a variable number of bits.
1066//
1067def SllvRxRy16 : FRxRxRy16_ins<0b00100, "sllv", IIAlu>;
1068
Reed Kotler3e457f52013-02-19 03:56:57 +00001069// Format: SLTI rx, immediate MIPS16e
1070// Purpose: Set on Less Than Immediate
1071// To record the result of a less-than comparison with a constant.
1072//
1073//
Reed Kotler7b503c22013-02-20 05:45:15 +00001074def SltiRxImm16: FRI16R_ins<0b01010, "slti", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001075 let Defs = [T8];
1076}
1077
Reed Kotler164bb372012-10-23 01:35:48 +00001078//
1079// Format: SLTI rx, immediate MIPS16e
1080// Purpose: Set on Less Than Immediate (Extended)
1081// To record the result of a less-than comparison with a constant.
1082//
Reed Kotler3e457f52013-02-19 03:56:57 +00001083//
Reed Kotler7b503c22013-02-20 05:45:15 +00001084def SltiRxImmX16: FEXT_RI16R_ins<0b01010, "slti", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001085 let Defs = [T8];
1086}
1087
Reed Kotler61b474f2013-02-16 23:39:52 +00001088def SltiCCRxImmX16: FEXT_CCRXI16_ins<"slti">;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001089
Reed Kotler3e457f52013-02-19 03:56:57 +00001090// Format: SLTIU rx, immediate MIPS16e
1091// Purpose: Set on Less Than Immediate Unsigned
1092// To record the result of a less-than comparison with a constant.
1093//
1094//
Reed Kotler7b503c22013-02-20 05:45:15 +00001095def SltiuRxImm16: FRI16R_ins<0b01011, "sltiu", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001096 let Defs = [T8];
1097}
1098
1099//
1100// Format: SLTI rx, immediate MIPS16e
1101// Purpose: Set on Less Than Immediate Unsigned (Extended)
1102// To record the result of a less-than comparison with a constant.
1103//
1104//
Reed Kotler7b503c22013-02-20 05:45:15 +00001105def SltiuRxImmX16: FEXT_RI16R_ins<0b01011, "sltiu", IIAlu> {
Reed Kotler3e457f52013-02-19 03:56:57 +00001106 let Defs = [T8];
1107}
Akira Hatanaka22bec282012-08-03 22:57:02 +00001108//
Reed Kotler164bb372012-10-23 01:35:48 +00001109// Format: SLTIU rx, immediate MIPS16e
1110// Purpose: Set on Less Than Immediate Unsigned (Extended)
1111// To record the result of a less-than comparison with a constant.
1112//
Reed Kotler61b474f2013-02-16 23:39:52 +00001113def SltiuCCRxImmX16: FEXT_CCRXI16_ins<"sltiu">;
Reed Kotler164bb372012-10-23 01:35:48 +00001114
1115//
1116// Format: SLT rx, ry MIPS16e
1117// Purpose: Set on Less Than
1118// To record the result of a less-than comparison.
1119//
Reed Kotler80070bd2013-02-23 23:37:03 +00001120def SltRxRy16: FRR16R_ins<0b00010, "slt", IIAlu>{
Reed Kotler7b503c22013-02-20 05:45:15 +00001121 let Defs = [T8];
1122}
Reed Kotler164bb372012-10-23 01:35:48 +00001123
Reed Kotler61b474f2013-02-16 23:39:52 +00001124def SltCCRxRy16: FCCRR16_ins<"slt">;
Reed Kotler164bb372012-10-23 01:35:48 +00001125
1126// Format: SLTU rx, ry MIPS16e
1127// Purpose: Set on Less Than Unsigned
1128// To record the result of an unsigned less-than comparison.
1129//
Reed Kotler80070bd2013-02-23 23:37:03 +00001130def SltuRxRy16: FRR16R_ins<0b00011, "sltu", IIAlu>{
Reed Kotler7b503c22013-02-20 05:45:15 +00001131 let Defs = [T8];
1132}
Reed Kotler6879e562013-02-18 04:55:38 +00001133
Reed Kotler61b474f2013-02-16 23:39:52 +00001134def SltuRxRyRz16: FRRTR16_ins<"sltu"> {
Reed Kotler287f0442012-10-26 04:46:26 +00001135 let isCodeGenOnly=1;
Reed Kotler7b503c22013-02-20 05:45:15 +00001136 let Defs = [T8];
Reed Kotler287f0442012-10-26 04:46:26 +00001137}
Reed Kotler164bb372012-10-23 01:35:48 +00001138
1139
Reed Kotler61b474f2013-02-16 23:39:52 +00001140def SltuCCRxRy16: FCCRR16_ins<"sltu">;
Reed Kotler164bb372012-10-23 01:35:48 +00001141//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001142// Format: SRAV ry, rx MIPS16e
1143// Purpose: Shift Word Right Arithmetic Variable
1144// To execute an arithmetic right-shift of a word by a variable
1145// number of bits.
1146//
1147def SravRxRy16: FRxRxRy16_ins<0b00111, "srav", IIAlu>;
1148
1149
1150//
1151// Format: SRA rx, ry, sa MIPS16e
1152// Purpose: Shift Word Right Arithmetic (Extended)
1153// To execute an arithmetic right-shift of a word by a fixed
1154// number of bits—1 to 8 bits.
1155//
1156def SraX16: FEXT_SHIFT16_ins<0b11, "sra", IIAlu>;
1157
1158
1159//
1160// Format: SRLV ry, rx MIPS16e
1161// Purpose: Shift Word Right Logical Variable
1162// To execute a logical right-shift of a word by a variable
1163// number of bits.
1164//
1165def SrlvRxRy16: FRxRxRy16_ins<0b00110, "srlv", IIAlu>;
1166
1167
1168//
1169// Format: SRL rx, ry, sa MIPS16e
1170// Purpose: Shift Word Right Logical (Extended)
1171// To execute a logical right-shift of a word by a fixed
1172// number of bits—1 to 31 bits.
1173//
1174def SrlX16: FEXT_SHIFT16_ins<0b10, "srl", IIAlu>;
1175
1176//
1177// Format: SUBU rz, rx, ry MIPS16e
1178// Purpose: Subtract Unsigned Word
1179// To subtract 32-bit integers
1180//
1181def SubuRxRyRz16: FRRR16_ins<0b11, "subu", IIAlu>, ArithLogic16Defs<0>;
1182
1183//
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001184// Format: SW ry, offset(rx) MIPS16e
1185// Purpose: Store Word (Extended)
1186// To store a word to memory.
1187//
Reed Kotler210ebe92012-09-28 02:26:24 +00001188def SwRxRyOffMemX16:
1189 FEXT_RRI16_mem2_ins<0b11011, "sw", mem16, IIStore>, MayStore;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001190
1191//
Reed Kotler210ebe92012-09-28 02:26:24 +00001192// Format: SW rx, offset(sp) MIPS16e
1193// Purpose: Store Word rx (SP-Relative)
1194// To store an SP-relative word to memory.
1195//
1196def SwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b11010, "sw", IIStore>, MayStore;
1197
1198//
1199//
Akira Hatanaka22bec282012-08-03 22:57:02 +00001200// Format: XOR rx, ry MIPS16e
1201// Purpose: Xor
1202// To do a bitwise logical XOR.
1203//
1204def XorRxRxRy16: FRxRxRy16_ins<0b01110, "xor", IIAlu>, ArithLogic16Defs<1>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001205
Akira Hatanaka765c3122012-06-21 20:39:10 +00001206class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> {
1207 let Predicates = [InMips16Mode];
1208}
1209
Akira Hatanaka22bec282012-08-03 22:57:02 +00001210// Unary Arith/Logic
1211//
1212class ArithLogicU_pat<PatFrag OpNode, Instruction I> :
1213 Mips16Pat<(OpNode CPU16Regs:$r),
1214 (I CPU16Regs:$r)>;
Akira Hatanakabff8e312012-05-31 02:59:44 +00001215
Akira Hatanaka22bec282012-08-03 22:57:02 +00001216def: ArithLogicU_pat<not, NotRxRy16>;
1217def: ArithLogicU_pat<ineg, NegRxRy16>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001218
Akira Hatanaka22bec282012-08-03 22:57:02 +00001219class ArithLogic16_pat<SDNode OpNode, Instruction I> :
1220 Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r),
1221 (I CPU16Regs:$l, CPU16Regs:$r)>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001222
Akira Hatanaka22bec282012-08-03 22:57:02 +00001223def: ArithLogic16_pat<add, AdduRxRyRz16>;
1224def: ArithLogic16_pat<and, AndRxRxRy16>;
Reed Kotler24032212012-10-05 18:27:54 +00001225def: ArithLogic16_pat<mul, MultRxRyRz16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001226def: ArithLogic16_pat<or, OrRxRxRy16>;
1227def: ArithLogic16_pat<sub, SubuRxRyRz16>;
1228def: ArithLogic16_pat<xor, XorRxRxRy16>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001229
Akira Hatanaka22bec282012-08-03 22:57:02 +00001230// Arithmetic and logical instructions with 2 register operands.
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001231
Akira Hatanaka22bec282012-08-03 22:57:02 +00001232class ArithLogicI16_pat<SDNode OpNode, PatFrag imm_type, Instruction I> :
1233 Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm),
1234 (I CPU16Regs:$in, imm_type:$imm)>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001235
Reed Kotlerb9bf8dc2013-02-08 21:42:56 +00001236def: ArithLogicI16_pat<add, immSExt8, AddiuRxRxImm16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001237def: ArithLogicI16_pat<add, immSExt16, AddiuRxRxImmX16>;
1238def: ArithLogicI16_pat<shl, immZExt5, SllX16>;
1239def: ArithLogicI16_pat<srl, immZExt5, SrlX16>;
1240def: ArithLogicI16_pat<sra, immZExt5, SraX16>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001241
Akira Hatanaka22bec282012-08-03 22:57:02 +00001242class shift_rotate_reg16_pat<SDNode OpNode, Instruction I> :
1243 Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra),
1244 (I CPU16Regs:$r, CPU16Regs:$ra)>;
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001245
Akira Hatanaka22bec282012-08-03 22:57:02 +00001246def: shift_rotate_reg16_pat<shl, SllvRxRy16>;
1247def: shift_rotate_reg16_pat<sra, SravRxRy16>;
1248def: shift_rotate_reg16_pat<srl, SrlvRxRy16>;
1249
1250class LoadM16_pat<PatFrag OpNode, Instruction I> :
Reed Kotler3589dd72012-10-28 06:02:37 +00001251 Mips16Pat<(OpNode addr16:$addr), (I addr16:$addr)>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001252
1253def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16>;
1254def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16>;
Akira Hatanaka3e7ba762012-09-15 01:52:08 +00001255def: LoadM16_pat<sextloadi16, LhRxRyOffMemX16>;
1256def: LoadM16_pat<zextloadi16, LhuRxRyOffMemX16>;
1257def: LoadM16_pat<load, LwRxRyOffMemX16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001258
1259class StoreM16_pat<PatFrag OpNode, Instruction I> :
Reed Kotler3589dd72012-10-28 06:02:37 +00001260 Mips16Pat<(OpNode CPU16Regs:$r, addr16:$addr),
1261 (I CPU16Regs:$r, addr16:$addr)>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001262
1263def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16>;
Akira Hatanaka3e7ba762012-09-15 01:52:08 +00001264def: StoreM16_pat<truncstorei16, ShRxRyOffMemX16>;
1265def: StoreM16_pat<store, SwRxRyOffMemX16>;
Akira Hatanaka22bec282012-08-03 22:57:02 +00001266
Reed Kotler67439242012-10-17 22:29:54 +00001267// Unconditional branch
1268class UncondBranch16_pat<SDNode OpNode, Instruction I>:
1269 Mips16Pat<(OpNode bb:$imm16), (I bb:$imm16)> {
Reed Kotlerec60f7d2013-02-07 03:49:51 +00001270 let Predicates = [InMips16Mode];
Reed Kotler67439242012-10-17 22:29:54 +00001271 }
Akira Hatanakabff8e312012-05-31 02:59:44 +00001272
Reed Kotlerf8933f82013-02-02 04:07:35 +00001273def : Mips16Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1274 (Jal16 tglobaladdr:$dst)>;
1275
Reed Kotler4a230ff2013-02-07 04:34:51 +00001276def : Mips16Pat<(MipsJmpLink (i32 texternalsym:$dst)),
1277 (Jal16 texternalsym:$dst)>;
1278
Reed Kotlere6c31572012-10-28 23:08:07 +00001279// Indirect branch
1280def: Mips16Pat<
Jack Carter7ab15fa2013-01-19 02:00:40 +00001281 (brind CPU16Regs:$rs),
1282 (JrcRx16 CPU16Regs:$rs)>;
Reed Kotlere6c31572012-10-28 23:08:07 +00001283
Akira Hatanakabff8e312012-05-31 02:59:44 +00001284// Jump and Link (Call)
Reed Kotlera8117532012-10-30 00:54:49 +00001285let isCall=1, hasDelaySlot=0 in
Akira Hatanakabff8e312012-05-31 02:59:44 +00001286def JumpLinkReg16:
Akira Hatanakaf640f042012-07-17 22:55:34 +00001287 FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs),
Reed Kotlera8117532012-10-30 00:54:49 +00001288 "jalrc \t$rs", [(MipsJmpLink CPU16Regs:$rs)], IIBranch>;
Akira Hatanakaf640f042012-07-17 22:55:34 +00001289
Akira Hatanaka26e9ecb2012-07-23 23:45:54 +00001290// Mips16 pseudos
1291let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1,
1292 hasExtraSrcRegAllocReq = 1 in
1293def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>;
1294
Reed Kotler67439242012-10-17 22:29:54 +00001295
Reed Kotler164bb372012-10-23 01:35:48 +00001296// setcc patterns
1297
1298class SetCC_R16<PatFrag cond_op, Instruction I>:
1299 Mips16Pat<(cond_op CPU16Regs:$rx, CPU16Regs:$ry),
1300 (I CPU16Regs:$rx, CPU16Regs:$ry)>;
1301
1302class SetCC_I16<PatFrag cond_op, PatLeaf imm_type, Instruction I>:
1303 Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16),
Reed Kotler097556d2012-10-25 21:33:30 +00001304 (I CPU16Regs:$rx, imm_type:$imm16)>;
Reed Kotler164bb372012-10-23 01:35:48 +00001305
Reed Kotler3589dd72012-10-28 06:02:37 +00001306
1307def: Mips16Pat<(i32 addr16:$addr),
1308 (AddiuRxRyOffMemX16 addr16:$addr)>;
1309
1310
Reed Kotlere47873a2012-10-26 03:09:34 +00001311// Large (>16 bit) immediate loads
1312def : Mips16Pat<(i32 imm:$imm),
1313 (OrRxRxRy16 (SllX16 (LiRxImmX16 (HI16 imm:$imm)), 16),
1314 (LiRxImmX16 (LO16 imm:$imm)))>;
Reed Kotler164bb372012-10-23 01:35:48 +00001315
Reed Kotler287f0442012-10-26 04:46:26 +00001316// Carry MipsPatterns
1317def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs),
1318 (SubuRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
1319def : Mips16Pat<(addc CPU16Regs:$lhs, CPU16Regs:$rhs),
1320 (AdduRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>;
1321def : Mips16Pat<(addc CPU16Regs:$src, immSExt16:$imm),
1322 (AddiuRxRxImmX16 CPU16Regs:$src, imm:$imm)>;
1323
Reed Kotler67439242012-10-17 22:29:54 +00001324//
1325// Some branch conditional patterns are not generated by llvm at this time.
1326// Some are for seemingly arbitrary reasons not used: i.e. with signed number
1327// comparison they are used and for unsigned a different pattern is used.
1328// I am pushing upstream from the full mips16 port and it seemed that I needed
1329// these earlier and the mips32 port has these but now I cannot create test
1330// cases that use these patterns. While I sort this all out I will leave these
1331// extra patterns commented out and if I can be sure they are really not used,
1332// I will delete the code. I don't want to check the code in uncommented without
1333// a valid test case. In some cases, the compiler is generating patterns with
1334// setcc instead and earlier I had implemented setcc first so may have masked
1335// the problem. The setcc variants are suboptimal for mips16 so I may wantto
1336// figure out how to enable the brcond patterns or else possibly new
1337// combinations of of brcond and setcc.
1338//
1339//
1340// bcond-seteq
1341//
1342def: Mips16Pat
1343 <(brcond (i32 (seteq CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1344 (BteqzT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1345 >;
1346
1347
1348def: Mips16Pat
1349 <(brcond (i32 (seteq CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1350 (BteqzT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$targ16)
1351 >;
1352
1353def: Mips16Pat
1354 <(brcond (i32 (seteq CPU16Regs:$rx, 0)), bb:$targ16),
1355 (BeqzRxImmX16 CPU16Regs:$rx, bb:$targ16)
1356 >;
1357
1358//
1359// bcond-setgt (do we need to have this pair of setlt, setgt??)
1360//
1361def: Mips16Pat
1362 <(brcond (i32 (setgt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1363 (BtnezT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16)
1364 >;
1365
1366//
1367// bcond-setge
1368//
1369def: Mips16Pat
1370 <(brcond (i32 (setge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1371 (BteqzT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1372 >;
1373
1374//
1375// never called because compiler transforms a >= k to a > (k-1)
Reed Kotler164bb372012-10-23 01:35:48 +00001376def: Mips16Pat
1377 <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1378 (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16)
1379 >;
Reed Kotler67439242012-10-17 22:29:54 +00001380
1381//
1382// bcond-setlt
1383//
1384def: Mips16Pat
1385 <(brcond (i32 (setlt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1386 (BtnezT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1387 >;
1388
1389def: Mips16Pat
1390 <(brcond (i32 (setlt CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16),
1391 (BtnezT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16)
1392 >;
1393
1394//
1395// bcond-setle
1396//
1397def: Mips16Pat
1398 <(brcond (i32 (setle CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1399 (BteqzT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16)
1400 >;
1401
1402//
1403// bcond-setne
1404//
1405def: Mips16Pat
1406 <(brcond (i32 (setne CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1407 (BtnezT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1408 >;
1409
1410def: Mips16Pat
1411 <(brcond (i32 (setne CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16),
1412 (BtnezT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$targ16)
1413 >;
1414
1415def: Mips16Pat
1416 <(brcond (i32 (setne CPU16Regs:$rx, 0)), bb:$targ16),
1417 (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16)
1418 >;
1419
1420//
1421// This needs to be there but I forget which code will generate it
1422//
1423def: Mips16Pat
1424 <(brcond CPU16Regs:$rx, bb:$targ16),
1425 (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16)
1426 >;
1427
1428//
1429
1430//
1431// bcond-setugt
1432//
1433//def: Mips16Pat
1434// <(brcond (i32 (setugt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1435// (BtnezT8SltuX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16)
1436// >;
1437
1438//
1439// bcond-setuge
1440//
1441//def: Mips16Pat
1442// <(brcond (i32 (setuge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1443// (BteqzT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1444// >;
1445
1446
1447//
1448// bcond-setult
1449//
1450//def: Mips16Pat
1451// <(brcond (i32 (setult CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16),
1452// (BtnezT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16)
1453// >;
1454
1455def: UncondBranch16_pat<br, BimmX16>;
1456
Akira Hatanaka765c3122012-06-21 20:39:10 +00001457// Small immediates
Reed Kotler67439242012-10-17 22:29:54 +00001458def: Mips16Pat<(i32 immSExt16:$in),
1459 (AddiuRxRxImmX16 (Move32R16 ZERO), immSExt16:$in)>;
1460
Akira Hatanaka22bec282012-08-03 22:57:02 +00001461def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>;
Akira Hatanaka64626fc2012-07-26 02:24:43 +00001462
Reed Kotlercf11c592012-10-12 02:01:09 +00001463//
1464// MipsDivRem
1465//
1466def: Mips16Pat
1467 <(MipsDivRem CPU16Regs:$rx, CPU16Regs:$ry),
1468 (DivRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1469
1470//
1471// MipsDivRemU
1472//
1473def: Mips16Pat
1474 <(MipsDivRemU CPU16Regs:$rx, CPU16Regs:$ry),
1475 (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
1476
Reed Kotler097556d2012-10-25 21:33:30 +00001477// signed a,b
1478// x = (a>=b)?x:y
1479//
1480// if !(a < b) x = y
1481//
1482def : Mips16Pat<(select (i32 (setge CPU16Regs:$a, CPU16Regs:$b)),
1483 CPU16Regs:$x, CPU16Regs:$y),
1484 (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1485 CPU16Regs:$a, CPU16Regs:$b)>;
1486
1487// signed a,b
1488// x = (a>b)?x:y
1489//
1490// if (b < a) x = y
1491//
1492def : Mips16Pat<(select (i32 (setgt CPU16Regs:$a, CPU16Regs:$b)),
1493 CPU16Regs:$x, CPU16Regs:$y),
1494 (SelTBtneZSlt CPU16Regs:$x, CPU16Regs:$y,
1495 CPU16Regs:$b, CPU16Regs:$a)>;
1496
1497// unsigned a,b
1498// x = (a>=b)?x:y
1499//
1500// if !(a < b) x = y;
1501//
1502def : Mips16Pat<
1503 (select (i32 (setuge CPU16Regs:$a, CPU16Regs:$b)),
1504 CPU16Regs:$x, CPU16Regs:$y),
1505 (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1506 CPU16Regs:$a, CPU16Regs:$b)>;
1507
1508// unsigned a,b
1509// x = (a>b)?x:y
1510//
1511// if (b < a) x = y
1512//
1513def : Mips16Pat<(select (i32 (setugt CPU16Regs:$a, CPU16Regs:$b)),
1514 CPU16Regs:$x, CPU16Regs:$y),
1515 (SelTBtneZSltu CPU16Regs:$x, CPU16Regs:$y,
1516 CPU16Regs:$b, CPU16Regs:$a)>;
1517
1518// signed
1519// x = (a >= k)?x:y
1520// due to an llvm optimization, i don't think that this will ever
1521// be used. This is transformed into x = (a > k-1)?x:y
1522//
1523//
1524
1525//def : Mips16Pat<
1526// (select (i32 (setge CPU16Regs:$lhs, immSExt16:$rhs)),
1527// CPU16Regs:$T, CPU16Regs:$F),
1528// (SelTBteqZSlti CPU16Regs:$T, CPU16Regs:$F,
1529// CPU16Regs:$lhs, immSExt16:$rhs)>;
1530
1531//def : Mips16Pat<
1532// (select (i32 (setuge CPU16Regs:$lhs, immSExt16:$rhs)),
1533// CPU16Regs:$T, CPU16Regs:$F),
1534// (SelTBteqZSltiu CPU16Regs:$T, CPU16Regs:$F,
1535// CPU16Regs:$lhs, immSExt16:$rhs)>;
1536
1537// signed
1538// x = (a < k)?x:y
1539//
1540// if !(a < k) x = y;
1541//
1542def : Mips16Pat<
1543 (select (i32 (setlt CPU16Regs:$a, immSExt16:$b)),
1544 CPU16Regs:$x, CPU16Regs:$y),
1545 (SelTBtneZSlti CPU16Regs:$x, CPU16Regs:$y,
1546 CPU16Regs:$a, immSExt16:$b)>;
1547
1548
1549//
1550//
1551// signed
1552// x = (a <= b)? x : y
1553//
1554// if (b < a) x = y
1555//
1556def : Mips16Pat<(select (i32 (setle CPU16Regs:$a, CPU16Regs:$b)),
1557 CPU16Regs:$x, CPU16Regs:$y),
1558 (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y,
1559 CPU16Regs:$b, CPU16Regs:$a)>;
1560
1561//
1562// unnsigned
1563// x = (a <= b)? x : y
1564//
1565// if (b < a) x = y
1566//
1567def : Mips16Pat<(select (i32 (setule CPU16Regs:$a, CPU16Regs:$b)),
1568 CPU16Regs:$x, CPU16Regs:$y),
1569 (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y,
1570 CPU16Regs:$b, CPU16Regs:$a)>;
1571
1572//
1573// signed/unsigned
1574// x = (a == b)? x : y
1575//
1576// if (a != b) x = y
1577//
1578def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, CPU16Regs:$b)),
1579 CPU16Regs:$x, CPU16Regs:$y),
1580 (SelTBteqZCmp CPU16Regs:$x, CPU16Regs:$y,
1581 CPU16Regs:$b, CPU16Regs:$a)>;
1582
1583//
1584// signed/unsigned
1585// x = (a == 0)? x : y
1586//
1587// if (a != 0) x = y
1588//
1589def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, 0)),
1590 CPU16Regs:$x, CPU16Regs:$y),
1591 (SelBeqZ CPU16Regs:$x, CPU16Regs:$y,
1592 CPU16Regs:$a)>;
1593
1594
1595//
1596// signed/unsigned
1597// x = (a == k)? x : y
1598//
1599// if (a != k) x = y
1600//
1601def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, immZExt16:$k)),
1602 CPU16Regs:$x, CPU16Regs:$y),
1603 (SelTBteqZCmpi CPU16Regs:$x, CPU16Regs:$y,
1604 CPU16Regs:$a, immZExt16:$k)>;
1605
1606
1607//
1608// signed/unsigned
1609// x = (a != b)? x : y
1610//
1611// if (a == b) x = y
1612//
1613//
1614def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, CPU16Regs:$b)),
1615 CPU16Regs:$x, CPU16Regs:$y),
1616 (SelTBtneZCmp CPU16Regs:$x, CPU16Regs:$y,
1617 CPU16Regs:$b, CPU16Regs:$a)>;
1618
1619//
1620// signed/unsigned
1621// x = (a != 0)? x : y
1622//
1623// if (a == 0) x = y
1624//
1625def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, 0)),
1626 CPU16Regs:$x, CPU16Regs:$y),
1627 (SelBneZ CPU16Regs:$x, CPU16Regs:$y,
1628 CPU16Regs:$a)>;
1629
1630// signed/unsigned
1631// x = (a)? x : y
1632//
1633// if (!a) x = y
1634//
1635def : Mips16Pat<(select CPU16Regs:$a,
1636 CPU16Regs:$x, CPU16Regs:$y),
1637 (SelBneZ 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 (setne CPU16Regs:$a, immZExt16:$k)),
1648 CPU16Regs:$x, CPU16Regs:$y),
1649 (SelTBtneZCmpi CPU16Regs:$x, CPU16Regs:$y,
1650 CPU16Regs:$a, immZExt16:$k)>;
Reed Kotlercf11c592012-10-12 02:01:09 +00001651
Reed Kotler164bb372012-10-23 01:35:48 +00001652//
1653// When writing C code to test setxx these patterns,
1654// some will be transformed into
1655// other things. So we test using C code but using -O3 and -O0
1656//
1657// seteq
1658//
1659def : Mips16Pat
1660 <(seteq CPU16Regs:$lhs,CPU16Regs:$rhs),
1661 (SltiuCCRxImmX16 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1)>;
1662
1663def : Mips16Pat
1664 <(seteq CPU16Regs:$lhs, 0),
1665 (SltiuCCRxImmX16 CPU16Regs:$lhs, 1)>;
1666
1667
1668//
1669// setge
1670//
1671
1672def: Mips16Pat
1673 <(setge CPU16Regs:$lhs, CPU16Regs:$rhs),
1674 (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1675 (LiRxImmX16 1))>;
1676
1677//
1678// For constants, llvm transforms this to:
1679// x > (k -1) and then reverses the operands to use setlt. So this pattern
1680// is not used now by the compiler. (Presumably checking that k-1 does not
1681// overflow). The compiler never uses this at a the current time, due to
1682// other optimizations.
1683//
1684//def: Mips16Pat
1685// <(setge CPU16Regs:$lhs, immSExt16:$rhs),
1686// (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs),
1687// (LiRxImmX16 1))>;
1688
1689// This catches the x >= -32768 case by transforming it to x > -32769
1690//
1691def: Mips16Pat
1692 <(setgt CPU16Regs:$lhs, -32769),
1693 (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768),
1694 (LiRxImmX16 1))>;
1695
1696//
1697// setgt
1698//
1699//
1700
1701def: Mips16Pat
1702 <(setgt CPU16Regs:$lhs, CPU16Regs:$rhs),
1703 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1704
1705//
1706// setle
1707//
1708def: Mips16Pat
1709 <(setle CPU16Regs:$lhs, CPU16Regs:$rhs),
Reed Kotler7b503c22013-02-20 05:45:15 +00001710 (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImm16 1))>;
Reed Kotler164bb372012-10-23 01:35:48 +00001711
1712//
1713// setlt
1714//
1715def: SetCC_R16<setlt, SltCCRxRy16>;
1716
1717def: SetCC_I16<setlt, immSExt16, SltiCCRxImmX16>;
1718
1719//
1720// setne
1721//
1722def : Mips16Pat
1723 <(setne CPU16Regs:$lhs,CPU16Regs:$rhs),
1724 (SltuCCRxRy16 (LiRxImmX16 0),
1725 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs))>;
1726
1727
1728//
1729// setuge
1730//
1731def: Mips16Pat
1732 <(setuge CPU16Regs:$lhs, CPU16Regs:$rhs),
1733 (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs),
1734 (LiRxImmX16 1))>;
1735
1736// this pattern will never be used because the compiler will transform
1737// x >= k to x > (k - 1) and then use SLT
1738//
1739//def: Mips16Pat
1740// <(setuge CPU16Regs:$lhs, immZExt16:$rhs),
1741// (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs),
Reed Kotler097556d2012-10-25 21:33:30 +00001742// (LiRxImmX16 1))>;
Reed Kotler164bb372012-10-23 01:35:48 +00001743
1744//
1745// setugt
1746//
1747def: Mips16Pat
1748 <(setugt CPU16Regs:$lhs, CPU16Regs:$rhs),
1749 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>;
1750
1751//
1752// setule
1753//
1754def: Mips16Pat
1755 <(setule CPU16Regs:$lhs, CPU16Regs:$rhs),
1756 (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>;
1757
1758//
1759// setult
1760//
1761def: SetCC_R16<setult, SltuCCRxRy16>;
1762
1763def: SetCC_I16<setult, immSExt16, SltiuCCRxImmX16>;
1764
Reed Kotler7e4d9962012-10-27 00:57:14 +00001765def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)),
1766 (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>;
1767
1768// hi/lo relocs
1769
Reed Kotler7b503c22013-02-20 05:45:15 +00001770def : Mips16Pat<(MipsHi tglobaladdr:$in),
Reed Kotlerf8933f82013-02-02 04:07:35 +00001771 (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>;
Reed Kotler9cb8e7b2013-02-13 08:32:14 +00001772def : Mips16Pat<(MipsHi tjumptable:$in),
1773 (SllX16 (LiRxImmX16 tjumptable:$in), 16)>;
Jack Carter7ab15fa2013-01-19 02:00:40 +00001774def : Mips16Pat<(MipsHi tglobaltlsaddr:$in),
Reed Kotler7e4d9962012-10-27 00:57:14 +00001775 (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>;
1776
Reed Kotlerb650f6b2012-10-26 22:57:32 +00001777// wrapper_pic
1778class Wrapper16Pat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1779 Mips16Pat<(MipsWrapper RC:$gp, node:$in),
1780 (ADDiuOp RC:$gp, node:$in)>;
1781
1782
Reed Kotler3589dd72012-10-28 06:02:37 +00001783def : Wrapper16Pat<tglobaladdr, AddiuRxRxImmX16, CPU16Regs>;
Reed Kotlerb650f6b2012-10-26 22:57:32 +00001784def : Wrapper16Pat<tglobaltlsaddr, AddiuRxRxImmX16, CPU16Regs>;
1785
Reed Kotler740981e2012-10-29 19:39:04 +00001786def : Mips16Pat<(i32 (extloadi8 addr16:$src)),
1787 (LbuRxRyOffMemX16 addr16:$src)>;
1788def : Mips16Pat<(i32 (extloadi16 addr16:$src)),
Chandler Carruthf12e3a62012-11-30 11:45:22 +00001789 (LhuRxRyOffMemX16 addr16:$src)>;