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