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