data.isa (7220:31a36c59a937) data.isa (7222:c6c7740edaf3)
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39 pclr = '''
40 return new %(className)ssRegPclr(machInst, %(dest)s,
41 %(op1)s, rm, imm5,
42 type);
43 '''
44 instDecode = '''
45 case %(opcode)#x:
46 if (immShift) {
47 if (setCc) {
48 if (%(dest)s == INTREG_PC) {
49 %(pclr)s
50 } else {
51 return new %(className)sRegCc(machInst, %(dest)s,
52 %(op1)s, rm, imm5, type);
53 }
54 } else {
55 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
56 rm, imm5, type);
57 }
58 } else {
59 if (setCc) {
60 return new %(className)sRegRegCc(machInst, %(dest)s,
61 %(op1)s, rm, rs, type);
62 } else {
63 return new %(className)sRegReg(machInst, %(dest)s,
64 %(op1)s, rm, rs, type);
65 }
66 }
67 break;
68 '''
69
70 def instCode(opcode, mnem, useDest = True, useOp1 = True):
71 global pclr
72 if useDest:
73 dest = "rd"
74 else:
75 dest = "INTREG_ZERO"
76 if useOp1:
77 op1 = "rn"
78 else:
79 op1 = "INTREG_ZERO"
80 global instDecode, pclrCode
81 substDict = { "className": mnem.capitalize(),
82 "opcode": opcode,
83 "dest": dest,
84 "op1": op1 }
85 if useDest:
86 substDict["pclr"] = pclr % substDict
87 else:
88 substDict["pclr"] = ""
89 return instDecode % substDict
90
91 decode_block = '''
92 {
93 const bool immShift = (bits(machInst, 4) == 0);
94 const bool setCc = (bits(machInst, 20) == 1);
95 const uint32_t imm5 = bits(machInst, 11, 7);
96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
101 switch (OPCODE) {
102 '''
103 decode_block += instCode(0x0, "and")
104 decode_block += instCode(0x1, "eor")
105 decode_block += instCode(0x2, "sub")
106 decode_block += instCode(0x3, "rsb")
107 decode_block += instCode(0x4, "add")
108 decode_block += instCode(0x5, "adc")
109 decode_block += instCode(0x6, "sbc")
110 decode_block += instCode(0x7, "rsc")
111 decode_block += instCode(0x8, "tst", useDest = False)
112 decode_block += instCode(0x9, "teq", useDest = False)
113 decode_block += instCode(0xa, "cmp", useDest = False)
114 decode_block += instCode(0xb, "cmn", useDest = False)
115 decode_block += instCode(0xc, "orr")
116 decode_block += instCode(0xd, "mov", useOp1 = False)
117 decode_block += instCode(0xe, "bic")
118 decode_block += instCode(0xf, "mvn", useOp1 = False)
119 decode_block += '''
120 default:
121 return new Unknown(machInst);
122 }
123 }
124 '''
125}};
126
127def format ArmPackUnpackSatReverse() {{
128 decode_block = '''
129 {
130 const uint32_t op1 = bits(machInst, 22, 20);
131 const uint32_t a = bits(machInst, 19, 16);
132 const uint32_t op2 = bits(machInst, 7, 5);
133 if (bits(op2, 0) == 0) {
134 if (op1 == 0) {
135 return new WarnUnimplemented("pkh", machInst);
136 } else if (bits(op1, 2, 1) == 1) {
137 return new WarnUnimplemented("ssat", machInst);
138 } else if (bits(op1, 2, 1) == 3) {
139 return new WarnUnimplemented("usat", machInst);
140 }
141 return new Unknown(machInst);
142 }
143 switch (op1) {
144 case 0x0:
145 if (op2 == 0x3) {
146 if (a == 0xf) {
147 return new WarnUnimplemented("sxtb16", machInst);
148 } else {
149 return new WarnUnimplemented("sxtab16", machInst);
150 }
151 } else if (op2 == 0x5) {
152 return new WarnUnimplemented("sel", machInst);
153 }
154 break;
155 case 0x2:
156 if (op2 == 0x1) {
157 return new WarnUnimplemented("ssat16", machInst);
158 } else if (op2 == 0x3) {
159 if (a == 0xf) {
160 return new WarnUnimplemented("sxtb", machInst);
161 } else {
162 return new WarnUnimplemented("sxtab", machInst);
163 }
164 }
165 break;
166 case 0x3:
167 if (op2 == 0x1) {
168 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
169 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
170 return new Rev(machInst, rd, rm);
171 } else if (op2 == 0x3) {
172 if (a == 0xf) {
173 return new WarnUnimplemented("sxth", machInst);
174 } else {
175 return new WarnUnimplemented("sxtah", machInst);
176 }
177 } else if (op2 == 0x5) {
178 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
179 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
180 return new Rev16(machInst, rd, rm);
181 }
182 break;
183 case 0x4:
184 if (op2 == 0x3) {
185 if (a == 0xf) {
186 return new WarnUnimplemented("uxtb16", machInst);
187 } else {
188 return new WarnUnimplemented("uxtab16", machInst);
189 }
190 }
191 break;
192 case 0x6:
193 if (op2 == 0x1) {
194 return new WarnUnimplemented("usat16", machInst);
195 } else if (op2 == 0x3) {
196 if (a == 0xf) {
197 return new WarnUnimplemented("uxtb", machInst);
198 } else {
199 return new WarnUnimplemented("uxtab", machInst);
200 }
201 }
202 break;
203 case 0x7:
204 if (op2 == 0x1) {
205 return new WarnUnimplemented("rbit", machInst);
206 } else if (op2 == 0x3) {
207 if (a == 0xf) {
208 return new WarnUnimplemented("uxth", machInst);
209 } else {
210 return new WarnUnimplemented("uxtah", machInst);
211 }
212 } else if (op2 == 0x5) {
213 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
214 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
215 return new Revsh(machInst, rd, rm);
216 }
217 break;
218 }
219 return new Unknown(machInst);
220 }
221 '''
222}};
223
224def format ArmParallelAddSubtract() {{
225 decode_block='''
226 {
227 const uint32_t op1 = bits(machInst, 21, 20);
228 const uint32_t op2 = bits(machInst, 7, 5);
229 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
230 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
231 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
232 if (bits(machInst, 22) == 0) {
233 switch (op1) {
234 case 0x1:
235 switch (op2) {
236 case 0x0:
237 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
238 case 0x1:
239 return new WarnUnimplemented("sasx", machInst);
240 case 0x2:
241 return new WarnUnimplemented("ssax", machInst);
242 case 0x3:
243 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
244 case 0x4:
245 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
246 case 0x7:
247 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
248 }
249 break;
250 case 0x2:
251 switch (op2) {
252 case 0x0:
253 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
254 case 0x1:
255 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
256 case 0x2:
257 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
258 case 0x3:
259 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
260 case 0x4:
261 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
262 case 0x7:
263 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
264 }
265 break;
266 case 0x3:
267 switch (op2) {
268 case 0x0:
269 return new WarnUnimplemented("shadd16", machInst);
270 case 0x1:
271 return new WarnUnimplemented("shasx", machInst);
272 case 0x2:
273 return new WarnUnimplemented("shsax", machInst);
274 case 0x3:
275 return new WarnUnimplemented("shsub16", machInst);
276 case 0x4:
277 return new WarnUnimplemented("shadd8", machInst);
278 case 0x7:
279 return new WarnUnimplemented("shsub8", machInst);
280 }
281 break;
282 }
283 } else {
284 switch (op1) {
285 case 0x1:
286 switch (op2) {
287 case 0x0:
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39 pclr = '''
40 return new %(className)ssRegPclr(machInst, %(dest)s,
41 %(op1)s, rm, imm5,
42 type);
43 '''
44 instDecode = '''
45 case %(opcode)#x:
46 if (immShift) {
47 if (setCc) {
48 if (%(dest)s == INTREG_PC) {
49 %(pclr)s
50 } else {
51 return new %(className)sRegCc(machInst, %(dest)s,
52 %(op1)s, rm, imm5, type);
53 }
54 } else {
55 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
56 rm, imm5, type);
57 }
58 } else {
59 if (setCc) {
60 return new %(className)sRegRegCc(machInst, %(dest)s,
61 %(op1)s, rm, rs, type);
62 } else {
63 return new %(className)sRegReg(machInst, %(dest)s,
64 %(op1)s, rm, rs, type);
65 }
66 }
67 break;
68 '''
69
70 def instCode(opcode, mnem, useDest = True, useOp1 = True):
71 global pclr
72 if useDest:
73 dest = "rd"
74 else:
75 dest = "INTREG_ZERO"
76 if useOp1:
77 op1 = "rn"
78 else:
79 op1 = "INTREG_ZERO"
80 global instDecode, pclrCode
81 substDict = { "className": mnem.capitalize(),
82 "opcode": opcode,
83 "dest": dest,
84 "op1": op1 }
85 if useDest:
86 substDict["pclr"] = pclr % substDict
87 else:
88 substDict["pclr"] = ""
89 return instDecode % substDict
90
91 decode_block = '''
92 {
93 const bool immShift = (bits(machInst, 4) == 0);
94 const bool setCc = (bits(machInst, 20) == 1);
95 const uint32_t imm5 = bits(machInst, 11, 7);
96 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
97 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
98 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
99 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
100 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
101 switch (OPCODE) {
102 '''
103 decode_block += instCode(0x0, "and")
104 decode_block += instCode(0x1, "eor")
105 decode_block += instCode(0x2, "sub")
106 decode_block += instCode(0x3, "rsb")
107 decode_block += instCode(0x4, "add")
108 decode_block += instCode(0x5, "adc")
109 decode_block += instCode(0x6, "sbc")
110 decode_block += instCode(0x7, "rsc")
111 decode_block += instCode(0x8, "tst", useDest = False)
112 decode_block += instCode(0x9, "teq", useDest = False)
113 decode_block += instCode(0xa, "cmp", useDest = False)
114 decode_block += instCode(0xb, "cmn", useDest = False)
115 decode_block += instCode(0xc, "orr")
116 decode_block += instCode(0xd, "mov", useOp1 = False)
117 decode_block += instCode(0xe, "bic")
118 decode_block += instCode(0xf, "mvn", useOp1 = False)
119 decode_block += '''
120 default:
121 return new Unknown(machInst);
122 }
123 }
124 '''
125}};
126
127def format ArmPackUnpackSatReverse() {{
128 decode_block = '''
129 {
130 const uint32_t op1 = bits(machInst, 22, 20);
131 const uint32_t a = bits(machInst, 19, 16);
132 const uint32_t op2 = bits(machInst, 7, 5);
133 if (bits(op2, 0) == 0) {
134 if (op1 == 0) {
135 return new WarnUnimplemented("pkh", machInst);
136 } else if (bits(op1, 2, 1) == 1) {
137 return new WarnUnimplemented("ssat", machInst);
138 } else if (bits(op1, 2, 1) == 3) {
139 return new WarnUnimplemented("usat", machInst);
140 }
141 return new Unknown(machInst);
142 }
143 switch (op1) {
144 case 0x0:
145 if (op2 == 0x3) {
146 if (a == 0xf) {
147 return new WarnUnimplemented("sxtb16", machInst);
148 } else {
149 return new WarnUnimplemented("sxtab16", machInst);
150 }
151 } else if (op2 == 0x5) {
152 return new WarnUnimplemented("sel", machInst);
153 }
154 break;
155 case 0x2:
156 if (op2 == 0x1) {
157 return new WarnUnimplemented("ssat16", machInst);
158 } else if (op2 == 0x3) {
159 if (a == 0xf) {
160 return new WarnUnimplemented("sxtb", machInst);
161 } else {
162 return new WarnUnimplemented("sxtab", machInst);
163 }
164 }
165 break;
166 case 0x3:
167 if (op2 == 0x1) {
168 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
169 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
170 return new Rev(machInst, rd, rm);
171 } else if (op2 == 0x3) {
172 if (a == 0xf) {
173 return new WarnUnimplemented("sxth", machInst);
174 } else {
175 return new WarnUnimplemented("sxtah", machInst);
176 }
177 } else if (op2 == 0x5) {
178 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
179 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
180 return new Rev16(machInst, rd, rm);
181 }
182 break;
183 case 0x4:
184 if (op2 == 0x3) {
185 if (a == 0xf) {
186 return new WarnUnimplemented("uxtb16", machInst);
187 } else {
188 return new WarnUnimplemented("uxtab16", machInst);
189 }
190 }
191 break;
192 case 0x6:
193 if (op2 == 0x1) {
194 return new WarnUnimplemented("usat16", machInst);
195 } else if (op2 == 0x3) {
196 if (a == 0xf) {
197 return new WarnUnimplemented("uxtb", machInst);
198 } else {
199 return new WarnUnimplemented("uxtab", machInst);
200 }
201 }
202 break;
203 case 0x7:
204 if (op2 == 0x1) {
205 return new WarnUnimplemented("rbit", machInst);
206 } else if (op2 == 0x3) {
207 if (a == 0xf) {
208 return new WarnUnimplemented("uxth", machInst);
209 } else {
210 return new WarnUnimplemented("uxtah", machInst);
211 }
212 } else if (op2 == 0x5) {
213 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
214 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
215 return new Revsh(machInst, rd, rm);
216 }
217 break;
218 }
219 return new Unknown(machInst);
220 }
221 '''
222}};
223
224def format ArmParallelAddSubtract() {{
225 decode_block='''
226 {
227 const uint32_t op1 = bits(machInst, 21, 20);
228 const uint32_t op2 = bits(machInst, 7, 5);
229 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
230 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
231 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
232 if (bits(machInst, 22) == 0) {
233 switch (op1) {
234 case 0x1:
235 switch (op2) {
236 case 0x0:
237 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
238 case 0x1:
239 return new WarnUnimplemented("sasx", machInst);
240 case 0x2:
241 return new WarnUnimplemented("ssax", machInst);
242 case 0x3:
243 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
244 case 0x4:
245 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
246 case 0x7:
247 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
248 }
249 break;
250 case 0x2:
251 switch (op2) {
252 case 0x0:
253 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
254 case 0x1:
255 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
256 case 0x2:
257 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
258 case 0x3:
259 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
260 case 0x4:
261 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
262 case 0x7:
263 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
264 }
265 break;
266 case 0x3:
267 switch (op2) {
268 case 0x0:
269 return new WarnUnimplemented("shadd16", machInst);
270 case 0x1:
271 return new WarnUnimplemented("shasx", machInst);
272 case 0x2:
273 return new WarnUnimplemented("shsax", machInst);
274 case 0x3:
275 return new WarnUnimplemented("shsub16", machInst);
276 case 0x4:
277 return new WarnUnimplemented("shadd8", machInst);
278 case 0x7:
279 return new WarnUnimplemented("shsub8", machInst);
280 }
281 break;
282 }
283 } else {
284 switch (op1) {
285 case 0x1:
286 switch (op2) {
287 case 0x0:
288 return new WarnUnimplemented("uadd16", machInst);
288 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
289 case 0x1:
289 case 0x1:
290 return new WarnUnimplemented("uasx", machInst);
290 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
291 case 0x2:
291 case 0x2:
292 return new WarnUnimplemented("usax", machInst);
292 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
293 case 0x3:
293 case 0x3:
294 return new WarnUnimplemented("usub16", machInst);
294 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
295 case 0x4:
295 case 0x4:
296 return new WarnUnimplemented("uadd8", machInst);
296 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
297 case 0x7:
297 case 0x7:
298 return new WarnUnimplemented("usub8", machInst);
298 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
299 }
300 break;
301 case 0x2:
302 switch (op2) {
303 case 0x0:
304 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
305 case 0x1:
306 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
307 case 0x2:
308 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
309 case 0x3:
310 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
311 case 0x4:
312 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
313 case 0x7:
314 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
315 }
316 break;
317 case 0x3:
318 switch (op2) {
319 case 0x0:
320 return new WarnUnimplemented("uhadd16", machInst);
321 case 0x1:
322 return new WarnUnimplemented("uhasx", machInst);
323 case 0x2:
324 return new WarnUnimplemented("uhsax", machInst);
325 case 0x3:
326 return new WarnUnimplemented("uhsub16", machInst);
327 case 0x4:
328 return new WarnUnimplemented("uhadd8", machInst);
329 case 0x7:
330 return new WarnUnimplemented("uhsub8", machInst);
331 }
332 break;
333 }
334 }
335 return new Unknown(machInst);
336 }
337 '''
338}};
339
340def format ArmDataProcImm() {{
341 pclr = '''
342 return new %(className)ssImmPclr(machInst, %(dest)s,
343 %(op1)s, imm, false);
344 '''
345 adr = '''
346 return new AdrImm(machInst, %(dest)s, %(add)s,
347 imm, false);
348 '''
349 instDecode = '''
350 case %(opcode)#x:
351 if (setCc) {
352 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
353 %(pclr)s
354 } else {
355 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
356 imm, rotC);
357 }
358 } else {
359 if (%(adrInst)s && %(op1)s == INTREG_PC) {
360 %(adr)s
361 } else {
362 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
363 imm, rotC);
364 }
365 }
366 break;
367 '''
368
369 def instCode(opcode, mnem, useDest = True, useOp1 = True):
370 global instDecode, pclr, adr
371 if useDest:
372 dest = "rd"
373 else:
374 dest = "INTREG_ZERO"
375 if useOp1:
376 op1 = "rn"
377 else:
378 op1 = "INTREG_ZERO"
379 substDict = { "className": mnem.capitalize(),
380 "opcode": opcode,
381 "dest": dest,
382 "op1": op1,
383 "adr": "",
384 "adrInst": "false" }
385 if useDest:
386 substDict["pclrInst"] = "true"
387 substDict["pclr"] = pclr % substDict
388 else:
389 substDict["pclrInst"] = "false"
390 substDict["pclr"] = ""
391 return instDecode % substDict
392
393 def adrCode(opcode, mnem, add="1"):
394 global instDecode, pclr, adr
395 substDict = { "className": mnem.capitalize(),
396 "opcode": opcode,
397 "dest": "rd",
398 "op1": "rn",
399 "add": add,
400 "pclrInst": "true",
401 "adrInst": "true" }
402 substDict["pclr"] = pclr % substDict
403 substDict["adr"] = adr % substDict
404 return instDecode % substDict
405
406 decode_block = '''
407 {
408 const bool setCc = (bits(machInst, 20) == 1);
409 const uint32_t unrotated = bits(machInst, 7, 0);
410 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
411 const bool rotC = (rotation != 0);
412 const uint32_t imm = rotate_imm(unrotated, rotation);
413 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
414 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
415 switch (OPCODE) {
416 '''
417 decode_block += instCode(0x0, "and")
418 decode_block += instCode(0x1, "eor")
419 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
420 decode_block += instCode(0x3, "rsb")
421 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
422 decode_block += instCode(0x5, "adc")
423 decode_block += instCode(0x6, "sbc")
424 decode_block += instCode(0x7, "rsc")
425 decode_block += instCode(0x8, "tst", useDest = False)
426 decode_block += instCode(0x9, "teq", useDest = False)
427 decode_block += instCode(0xa, "cmp", useDest = False)
428 decode_block += instCode(0xb, "cmn", useDest = False)
429 decode_block += instCode(0xc, "orr")
430 decode_block += instCode(0xd, "mov", useOp1 = False)
431 decode_block += instCode(0xe, "bic")
432 decode_block += instCode(0xf, "mvn", useOp1 = False)
433 decode_block += '''
434 default:
435 return new Unknown(machInst);
436 }
437 }
438 '''
439}};
440
441def format ArmSatAddSub() {{
442 decode_block = '''
443 {
444 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
445 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
446 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
447 switch (OPCODE) {
448 case 0x8:
449 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
450 case 0x9:
451 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
452 case 0xa:
453 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
454 case 0xb:
455 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
456 default:
457 return new Unknown(machInst);
458 }
459 }
460 '''
461}};
462
463def format Thumb32DataProcReg() {{
464 decode_block = '''
465 {
466 const uint32_t op1 = bits(machInst, 23, 20);
467 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
468 const uint32_t op2 = bits(machInst, 7, 4);
469 if (bits(op1, 3) != 1) {
470 if (op2 == 0) {
471 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
472 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
473 switch (bits(op1, 2, 0)) {
474 case 0x0:
475 return new MovRegReg(machInst, rd,
476 INTREG_ZERO, rn, rm, LSL);
477 case 0x1:
478 return new MovRegRegCc(machInst, rd,
479 INTREG_ZERO, rn, rm, LSL);
480 case 0x2:
481 return new MovRegReg(machInst, rd,
482 INTREG_ZERO, rn, rm, LSR);
483 case 0x3:
484 return new MovRegRegCc(machInst, rd,
485 INTREG_ZERO, rn, rm, LSR);
486 case 0x4:
487 return new MovRegReg(machInst, rd,
488 INTREG_ZERO, rn, rm, ASR);
489 case 0x5:
490 return new MovRegRegCc(machInst, rd,
491 INTREG_ZERO, rn, rm, ASR);
492 case 0x6:
493 return new MovRegReg(machInst, rd,
494 INTREG_ZERO, rn, rm, ROR);
495 case 0x7:
496 return new MovRegRegCc(machInst, rd,
497 INTREG_ZERO, rn, rm, ROR);
498 }
499 }
500 switch (bits(op1, 2, 0)) {
501 case 0x0:
502 if (rn == 0xf) {
503 return new WarnUnimplemented("sxth", machInst);
504 } else {
505 return new WarnUnimplemented("sxtah", machInst);
506 }
507 case 0x1:
508 if (rn == 0xf) {
509 return new WarnUnimplemented("uxth", machInst);
510 } else {
511 return new WarnUnimplemented("uxtah", machInst);
512 }
513 case 0x2:
514 if (rn == 0xf) {
515 return new WarnUnimplemented("sxtb16", machInst);
516 } else {
517 return new WarnUnimplemented("sxtab16", machInst);
518 }
519 case 0x3:
520 if (rn == 0xf) {
521 return new WarnUnimplemented("uxtb16", machInst);
522 } else {
523 return new WarnUnimplemented("uxtab16", machInst);
524 }
525 case 0x4:
526 if (rn == 0xf) {
527 return new WarnUnimplemented("sxtb", machInst);
528 } else {
529 return new WarnUnimplemented("sxtab", machInst);
530 }
531 case 0x5:
532 if (rn == 0xf) {
533 return new WarnUnimplemented("uxtb", machInst);
534 } else {
535 return new WarnUnimplemented("uxtab", machInst);
536 }
537 default:
538 return new Unknown(machInst);
539 }
540 } else {
541 if (bits(op2, 3) == 0) {
542 const IntRegIndex rd =
543 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
544 const IntRegIndex rm =
545 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
546 if (bits(op2, 2) == 0x0) {
547 const uint32_t op1 = bits(machInst, 22, 20);
548 const uint32_t op2 = bits(machInst, 5, 4);
549 switch (op2) {
550 case 0x0:
551 switch (op1) {
552 case 0x1:
553 return new Sadd16RegCc(machInst, rd,
554 rn, rm, 0, LSL);
555 case 0x2:
556 return new WarnUnimplemented("sasx", machInst);
557 case 0x6:
558 return new WarnUnimplemented("ssax", machInst);
559 case 0x5:
560 return new Ssub16RegCc(machInst, rd,
561 rn, rm, 0, LSL);
562 case 0x0:
563 return new Sadd8RegCc(machInst, rd,
564 rn, rm, 0, LSL);
565 case 0x4:
566 return new Ssub8RegCc(machInst, rd,
567 rn, rm, 0, LSL);
568 }
569 break;
570 case 0x1:
571 switch (op1) {
572 case 0x1:
573 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
574 case 0x2:
575 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
576 case 0x6:
577 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
578 case 0x5:
579 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
580 case 0x0:
581 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
582 case 0x4:
583 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
584 }
585 break;
586 case 0x2:
587 switch (op1) {
588 case 0x1:
589 return new WarnUnimplemented("shadd16", machInst);
590 case 0x2:
591 return new WarnUnimplemented("shasx", machInst);
592 case 0x6:
593 return new WarnUnimplemented("shsax", machInst);
594 case 0x5:
595 return new WarnUnimplemented("shsub16", machInst);
596 case 0x0:
597 return new WarnUnimplemented("shadd8", machInst);
598 case 0x4:
599 return new WarnUnimplemented("shsub8", machInst);
600 }
601 break;
602 }
603 } else {
604 const uint32_t op1 = bits(machInst, 22, 20);
605 const uint32_t op2 = bits(machInst, 5, 4);
606 switch (op2) {
607 case 0x0:
608 switch (op1) {
609 case 0x1:
299 }
300 break;
301 case 0x2:
302 switch (op2) {
303 case 0x0:
304 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
305 case 0x1:
306 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
307 case 0x2:
308 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
309 case 0x3:
310 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
311 case 0x4:
312 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
313 case 0x7:
314 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
315 }
316 break;
317 case 0x3:
318 switch (op2) {
319 case 0x0:
320 return new WarnUnimplemented("uhadd16", machInst);
321 case 0x1:
322 return new WarnUnimplemented("uhasx", machInst);
323 case 0x2:
324 return new WarnUnimplemented("uhsax", machInst);
325 case 0x3:
326 return new WarnUnimplemented("uhsub16", machInst);
327 case 0x4:
328 return new WarnUnimplemented("uhadd8", machInst);
329 case 0x7:
330 return new WarnUnimplemented("uhsub8", machInst);
331 }
332 break;
333 }
334 }
335 return new Unknown(machInst);
336 }
337 '''
338}};
339
340def format ArmDataProcImm() {{
341 pclr = '''
342 return new %(className)ssImmPclr(machInst, %(dest)s,
343 %(op1)s, imm, false);
344 '''
345 adr = '''
346 return new AdrImm(machInst, %(dest)s, %(add)s,
347 imm, false);
348 '''
349 instDecode = '''
350 case %(opcode)#x:
351 if (setCc) {
352 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
353 %(pclr)s
354 } else {
355 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
356 imm, rotC);
357 }
358 } else {
359 if (%(adrInst)s && %(op1)s == INTREG_PC) {
360 %(adr)s
361 } else {
362 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
363 imm, rotC);
364 }
365 }
366 break;
367 '''
368
369 def instCode(opcode, mnem, useDest = True, useOp1 = True):
370 global instDecode, pclr, adr
371 if useDest:
372 dest = "rd"
373 else:
374 dest = "INTREG_ZERO"
375 if useOp1:
376 op1 = "rn"
377 else:
378 op1 = "INTREG_ZERO"
379 substDict = { "className": mnem.capitalize(),
380 "opcode": opcode,
381 "dest": dest,
382 "op1": op1,
383 "adr": "",
384 "adrInst": "false" }
385 if useDest:
386 substDict["pclrInst"] = "true"
387 substDict["pclr"] = pclr % substDict
388 else:
389 substDict["pclrInst"] = "false"
390 substDict["pclr"] = ""
391 return instDecode % substDict
392
393 def adrCode(opcode, mnem, add="1"):
394 global instDecode, pclr, adr
395 substDict = { "className": mnem.capitalize(),
396 "opcode": opcode,
397 "dest": "rd",
398 "op1": "rn",
399 "add": add,
400 "pclrInst": "true",
401 "adrInst": "true" }
402 substDict["pclr"] = pclr % substDict
403 substDict["adr"] = adr % substDict
404 return instDecode % substDict
405
406 decode_block = '''
407 {
408 const bool setCc = (bits(machInst, 20) == 1);
409 const uint32_t unrotated = bits(machInst, 7, 0);
410 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
411 const bool rotC = (rotation != 0);
412 const uint32_t imm = rotate_imm(unrotated, rotation);
413 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
414 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
415 switch (OPCODE) {
416 '''
417 decode_block += instCode(0x0, "and")
418 decode_block += instCode(0x1, "eor")
419 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
420 decode_block += instCode(0x3, "rsb")
421 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
422 decode_block += instCode(0x5, "adc")
423 decode_block += instCode(0x6, "sbc")
424 decode_block += instCode(0x7, "rsc")
425 decode_block += instCode(0x8, "tst", useDest = False)
426 decode_block += instCode(0x9, "teq", useDest = False)
427 decode_block += instCode(0xa, "cmp", useDest = False)
428 decode_block += instCode(0xb, "cmn", useDest = False)
429 decode_block += instCode(0xc, "orr")
430 decode_block += instCode(0xd, "mov", useOp1 = False)
431 decode_block += instCode(0xe, "bic")
432 decode_block += instCode(0xf, "mvn", useOp1 = False)
433 decode_block += '''
434 default:
435 return new Unknown(machInst);
436 }
437 }
438 '''
439}};
440
441def format ArmSatAddSub() {{
442 decode_block = '''
443 {
444 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
445 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
446 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
447 switch (OPCODE) {
448 case 0x8:
449 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
450 case 0x9:
451 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
452 case 0xa:
453 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
454 case 0xb:
455 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
456 default:
457 return new Unknown(machInst);
458 }
459 }
460 '''
461}};
462
463def format Thumb32DataProcReg() {{
464 decode_block = '''
465 {
466 const uint32_t op1 = bits(machInst, 23, 20);
467 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
468 const uint32_t op2 = bits(machInst, 7, 4);
469 if (bits(op1, 3) != 1) {
470 if (op2 == 0) {
471 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
472 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
473 switch (bits(op1, 2, 0)) {
474 case 0x0:
475 return new MovRegReg(machInst, rd,
476 INTREG_ZERO, rn, rm, LSL);
477 case 0x1:
478 return new MovRegRegCc(machInst, rd,
479 INTREG_ZERO, rn, rm, LSL);
480 case 0x2:
481 return new MovRegReg(machInst, rd,
482 INTREG_ZERO, rn, rm, LSR);
483 case 0x3:
484 return new MovRegRegCc(machInst, rd,
485 INTREG_ZERO, rn, rm, LSR);
486 case 0x4:
487 return new MovRegReg(machInst, rd,
488 INTREG_ZERO, rn, rm, ASR);
489 case 0x5:
490 return new MovRegRegCc(machInst, rd,
491 INTREG_ZERO, rn, rm, ASR);
492 case 0x6:
493 return new MovRegReg(machInst, rd,
494 INTREG_ZERO, rn, rm, ROR);
495 case 0x7:
496 return new MovRegRegCc(machInst, rd,
497 INTREG_ZERO, rn, rm, ROR);
498 }
499 }
500 switch (bits(op1, 2, 0)) {
501 case 0x0:
502 if (rn == 0xf) {
503 return new WarnUnimplemented("sxth", machInst);
504 } else {
505 return new WarnUnimplemented("sxtah", machInst);
506 }
507 case 0x1:
508 if (rn == 0xf) {
509 return new WarnUnimplemented("uxth", machInst);
510 } else {
511 return new WarnUnimplemented("uxtah", machInst);
512 }
513 case 0x2:
514 if (rn == 0xf) {
515 return new WarnUnimplemented("sxtb16", machInst);
516 } else {
517 return new WarnUnimplemented("sxtab16", machInst);
518 }
519 case 0x3:
520 if (rn == 0xf) {
521 return new WarnUnimplemented("uxtb16", machInst);
522 } else {
523 return new WarnUnimplemented("uxtab16", machInst);
524 }
525 case 0x4:
526 if (rn == 0xf) {
527 return new WarnUnimplemented("sxtb", machInst);
528 } else {
529 return new WarnUnimplemented("sxtab", machInst);
530 }
531 case 0x5:
532 if (rn == 0xf) {
533 return new WarnUnimplemented("uxtb", machInst);
534 } else {
535 return new WarnUnimplemented("uxtab", machInst);
536 }
537 default:
538 return new Unknown(machInst);
539 }
540 } else {
541 if (bits(op2, 3) == 0) {
542 const IntRegIndex rd =
543 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
544 const IntRegIndex rm =
545 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
546 if (bits(op2, 2) == 0x0) {
547 const uint32_t op1 = bits(machInst, 22, 20);
548 const uint32_t op2 = bits(machInst, 5, 4);
549 switch (op2) {
550 case 0x0:
551 switch (op1) {
552 case 0x1:
553 return new Sadd16RegCc(machInst, rd,
554 rn, rm, 0, LSL);
555 case 0x2:
556 return new WarnUnimplemented("sasx", machInst);
557 case 0x6:
558 return new WarnUnimplemented("ssax", machInst);
559 case 0x5:
560 return new Ssub16RegCc(machInst, rd,
561 rn, rm, 0, LSL);
562 case 0x0:
563 return new Sadd8RegCc(machInst, rd,
564 rn, rm, 0, LSL);
565 case 0x4:
566 return new Ssub8RegCc(machInst, rd,
567 rn, rm, 0, LSL);
568 }
569 break;
570 case 0x1:
571 switch (op1) {
572 case 0x1:
573 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
574 case 0x2:
575 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
576 case 0x6:
577 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
578 case 0x5:
579 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
580 case 0x0:
581 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
582 case 0x4:
583 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
584 }
585 break;
586 case 0x2:
587 switch (op1) {
588 case 0x1:
589 return new WarnUnimplemented("shadd16", machInst);
590 case 0x2:
591 return new WarnUnimplemented("shasx", machInst);
592 case 0x6:
593 return new WarnUnimplemented("shsax", machInst);
594 case 0x5:
595 return new WarnUnimplemented("shsub16", machInst);
596 case 0x0:
597 return new WarnUnimplemented("shadd8", machInst);
598 case 0x4:
599 return new WarnUnimplemented("shsub8", machInst);
600 }
601 break;
602 }
603 } else {
604 const uint32_t op1 = bits(machInst, 22, 20);
605 const uint32_t op2 = bits(machInst, 5, 4);
606 switch (op2) {
607 case 0x0:
608 switch (op1) {
609 case 0x1:
610 return new WarnUnimplemented("uadd16", machInst);
610 return new Uadd16RegCc(machInst, rd,
611 rn, rm, 0, LSL);
611 case 0x2:
612 case 0x2:
612 return new WarnUnimplemented("uasx", machInst);
613 return new UasxRegCc(machInst, rd,
614 rn, rm, 0, LSL);
613 case 0x6:
615 case 0x6:
614 return new WarnUnimplemented("usax", machInst);
616 return new UsaxRegCc(machInst, rd,
617 rn, rm, 0, LSL);
615 case 0x5:
618 case 0x5:
616 return new WarnUnimplemented("usub16", machInst);
619 return new Usub16RegCc(machInst, rd,
620 rn, rm, 0, LSL);
617 case 0x0:
621 case 0x0:
618 return new WarnUnimplemented("uadd8", machInst);
622 return new Uadd8RegCc(machInst, rd,
623 rn, rm, 0, LSL);
619 case 0x4:
624 case 0x4:
620 return new WarnUnimplemented("usub8", machInst);
625 return new Usub8RegCc(machInst, rd,
626 rn, rm, 0, LSL);
621 }
622 break;
623 case 0x1:
624 switch (op1) {
625 case 0x1:
626 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
627 case 0x2:
628 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
629 case 0x6:
630 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
631 case 0x5:
632 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
633 case 0x0:
634 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
635 case 0x4:
636 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
637 }
638 break;
639 case 0x2:
640 switch (op1) {
641 case 0x1:
642 return new WarnUnimplemented("uhadd16", machInst);
643 case 0x2:
644 return new WarnUnimplemented("uhasx", machInst);
645 case 0x6:
646 return new WarnUnimplemented("uhsax", machInst);
647 case 0x5:
648 return new WarnUnimplemented("uhsub16", machInst);
649 case 0x0:
650 return new WarnUnimplemented("uhadd8", machInst);
651 case 0x4:
652 return new WarnUnimplemented("uhsub8", machInst);
653 }
654 break;
655 }
656 }
657 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
658 const uint32_t op1 = bits(machInst, 21, 20);
659 const uint32_t op2 = bits(machInst, 5, 4);
660 switch (op1) {
661 case 0x0:
662 {
663 IntRegIndex rd =
664 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
665 IntRegIndex rm =
666 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
667 switch (op2) {
668 case 0x0:
669 return new QaddRegCc(machInst, rd,
670 rm, rn, 0, LSL);
671 case 0x1:
672 return new QdaddRegCc(machInst, rd,
673 rm, rn, 0, LSL);
674 case 0x2:
675 return new QsubRegCc(machInst, rd,
676 rm, rn, 0, LSL);
677 case 0x3:
678 return new QdsubRegCc(machInst, rd,
679 rm, rn, 0, LSL);
680 }
681 }
682 break;
683 case 0x1:
684 {
685 IntRegIndex rd =
686 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
687 IntRegIndex rm = rn;
688 switch (op2) {
689 case 0x0:
690 return new Rev(machInst, rd, rm);
691 case 0x1:
692 return new Rev16(machInst, rd, rm);
693 case 0x2:
694 return new WarnUnimplemented("rbit", machInst);
695 case 0x3:
696 return new Revsh(machInst, rd, rm);
697 }
698 }
699 break;
700 case 0x2:
701 if (op2 == 0) {
702 return new WarnUnimplemented("sel", machInst);
703 }
704 break;
705 case 0x3:
706 if (op2 == 0) {
707 return new WarnUnimplemented("clz", machInst);
708 }
709 }
710 }
711 return new Unknown(machInst);
712 }
713 }
714 '''
715}};
716
717def format Thumb16ShiftAddSubMoveCmp() {{
718 decode_block = '''
719 {
720 const uint32_t imm5 = bits(machInst, 10, 6);
721 const uint32_t imm3 = bits(machInst, 8, 6);
722 const uint32_t imm8 = bits(machInst, 7, 0);
723 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
724 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
725 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
726 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
727 switch (bits(machInst, 13, 11)) {
728 case 0x0: // lsl
729 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
730 case 0x1: // lsr
731 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
732 case 0x2: // asr
733 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
734 case 0x3:
735 switch (bits(machInst, 10, 9)) {
736 case 0x0:
737 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
738 case 0x1:
739 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
740 case 0x2:
741 return new AddImmCc(machInst, rd, rn, imm3, true);
742 case 0x3:
743 return new SubImmCc(machInst, rd, rn, imm3, true);
744 }
745 case 0x4:
746 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
747 case 0x5:
748 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
749 case 0x6:
750 return new AddImmCc(machInst, rd8, rd8, imm8, true);
751 case 0x7:
752 return new SubImmCc(machInst, rd8, rd8, imm8, true);
753 }
754 }
755 '''
756}};
757
758def format Thumb16DataProcessing() {{
759 decode_block = '''
760 {
761 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
762 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
763 switch (bits(machInst, 9, 6)) {
764 case 0x0:
765 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
766 case 0x1:
767 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
768 case 0x2: //lsl
769 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
770 case 0x3: //lsr
771 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
772 case 0x4: //asr
773 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
774 case 0x5:
775 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
776 case 0x6:
777 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
778 case 0x7: // ror
779 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
780 case 0x8:
781 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
782 case 0x9:
783 return new RsbImmCc(machInst, rdn, rm, 0, true);
784 case 0xa:
785 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
786 case 0xb:
787 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
788 case 0xc:
789 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
790 case 0xd:
791 return new MulCc(machInst, rdn, rm, rdn);
792 case 0xe:
793 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
794 case 0xf:
795 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
796 }
797 }
798 '''
799}};
800
801def format Thumb16SpecDataAndBx() {{
802 decode_block = '''
803 {
804 const IntRegIndex rdn =
805 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
806 (bits(machInst, 7) << 3));
807 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
808 switch (bits(machInst, 9, 8)) {
809 case 0x0:
810 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
811 case 0x1:
812 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
813 case 0x2:
814 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
815 case 0x3:
816 if (bits(machInst, 7) == 0) {
817 return new BxReg(machInst,
818 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
819 COND_UC);
820 } else {
821 return new BlxReg(machInst,
822 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
823 COND_UC);
824 }
825 }
826 }
827 '''
828}};
829
830def format Thumb16Adr() {{
831 decode_block = '''
832 {
833 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
834 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
835 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
836 }
837 '''
838}};
839
840def format Thumb16AddSp() {{
841 decode_block = '''
842 {
843 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
844 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
845 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
846 }
847 '''
848}};
849
850def format Thumb16Misc() {{
851 decode_block = '''
852 {
853 switch (bits(machInst, 11, 8)) {
854 case 0x0:
855 if (bits(machInst, 7)) {
856 return new SubImm(machInst, INTREG_SP, INTREG_SP,
857 bits(machInst, 6, 0) << 2, true);
858 } else {
859 return new AddImm(machInst, INTREG_SP, INTREG_SP,
860 bits(machInst, 6, 0) << 2, true);
861 }
862 case 0x1:
863 return new Cbz(machInst,
864 (bits(machInst, 9) << 6) |
865 (bits(machInst, 7, 3) << 1),
866 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
867 case 0x2:
868 switch (bits(machInst, 7, 6)) {
869 case 0x0:
870 return new WarnUnimplemented("sxth", machInst);
871 case 0x1:
872 return new WarnUnimplemented("sxtb", machInst);
873 case 0x2:
874 return new WarnUnimplemented("uxth", machInst);
875 case 0x3:
876 return new WarnUnimplemented("uxtb", machInst);
877 }
878 case 0x3:
879 return new Cbz(machInst,
880 (bits(machInst, 9) << 6) |
881 (bits(machInst, 7, 3) << 1),
882 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
883 case 0x4:
884 case 0x5:
885 {
886 const uint32_t m = bits(machInst, 8);
887 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
888 return new LdmStm(machInst, INTREG_SP, false, false, false,
889 true, false, regList);
890 }
891 case 0x6:
892 {
893 const uint32_t opBits = bits(machInst, 7, 5);
894 if (opBits == 2) {
895 return new WarnUnimplemented("setend", machInst);
896 } else if (opBits == 3) {
897 return new WarnUnimplemented("cps", machInst);
898 }
899 }
900 case 0x9:
901 return new Cbnz(machInst,
902 (bits(machInst, 9) << 6) |
903 (bits(machInst, 7, 3) << 1),
904 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
905 case 0xa:
906 {
907 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
908 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
909 switch (bits(machInst, 7, 6)) {
910 case 0x0:
911 return new Rev(machInst, rd, rm);
912 case 0x1:
913 return new Rev16(machInst, rd, rm);
914 case 0x3:
915 return new Revsh(machInst, rd, rm);
916 default:
917 break;
918 }
919 }
920 break;
921 case 0xb:
922 return new Cbnz(machInst,
923 (bits(machInst, 9) << 6) |
924 (bits(machInst, 7, 3) << 1),
925 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
926 case 0xc:
927 case 0xd:
928 {
929 const uint32_t p = bits(machInst, 8);
930 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
931 return new LdmStm(machInst, INTREG_SP, true, true, false,
932 true, true, regList);
933 }
934 case 0xe:
935 return new WarnUnimplemented("bkpt", machInst);
936 case 0xf:
937 if (bits(machInst, 3, 0) != 0)
938 return new WarnUnimplemented("it", machInst);
939 switch (bits(machInst, 7, 4)) {
940 case 0x0:
941 return new WarnUnimplemented("nop", machInst);
942 case 0x1:
943 return new WarnUnimplemented("yield", machInst);
944 case 0x2:
945 return new WarnUnimplemented("wfe", machInst);
946 case 0x3:
947 return new WarnUnimplemented("wfi", machInst);
948 case 0x4:
949 return new WarnUnimplemented("sev", machInst);
950 default:
951 return new WarnUnimplemented("unallocated_hint", machInst);
952 }
953 default:
954 break;
955 }
956 return new Unknown(machInst);
957 }
958 '''
959}};
960
961def format Thumb32DataProcModImm() {{
962
963 def decInst(mnem, dest="rd", op1="rn"):
964 return '''
965 if (s) {
966 return new %(mnem)sImmCc(machInst, %(dest)s,
967 %(op1)s, imm, rotC);
968 } else {
969 return new %(mnem)sImm(machInst, %(dest)s,
970 %(op1)s, imm, rotC);
971 }
972 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
973
974 decode_block = '''
975 {
976 const uint32_t op = bits(machInst, 24, 21);
977 const bool s = (bits(machInst, 20) == 1);
978 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
979 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
980 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
981 bits(machInst, 14, 12);
982 const bool rotC = ctrlImm > 3;
983 const uint32_t dataImm = bits(machInst, 7, 0);
984 const uint32_t imm = modified_imm(ctrlImm, dataImm);
985 switch (op) {
986 case 0x0:
987 if (rd == INTREG_PC) {
988 %(tst)s
989 } else {
990 %(and)s
991 }
992 case 0x1:
993 %(bic)s
994 case 0x2:
995 if (rn == INTREG_PC) {
996 %(mov)s
997 } else {
998 %(orr)s
999 }
1000 case 0x3:
1001 if (rn == INTREG_PC) {
1002 %(mvn)s
1003 } else {
1004 %(orn)s
1005 }
1006 case 0x4:
1007 if (rd == INTREG_PC) {
1008 %(teq)s
1009 } else {
1010 %(eor)s
1011 }
1012 case 0x8:
1013 if (rd == INTREG_PC) {
1014 %(cmn)s
1015 } else {
1016 %(add)s
1017 }
1018 case 0xa:
1019 %(adc)s
1020 case 0xb:
1021 %(sbc)s
1022 case 0xd:
1023 if (rd == INTREG_PC) {
1024 %(cmp)s
1025 } else {
1026 %(sub)s
1027 }
1028 case 0xe:
1029 %(rsb)s
1030 default:
1031 return new Unknown(machInst);
1032 }
1033 }
1034 ''' % {
1035 "tst" : decInst("Tst", "INTREG_ZERO"),
1036 "and" : decInst("And"),
1037 "bic" : decInst("Bic"),
1038 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1039 "orr" : decInst("Orr"),
1040 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1041 "orn" : decInst("Orn"),
1042 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1043 "eor" : decInst("Eor"),
1044 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1045 "add" : decInst("Add"),
1046 "adc" : decInst("Adc"),
1047 "sbc" : decInst("Sbc"),
1048 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1049 "sub" : decInst("Sub"),
1050 "rsb" : decInst("Rsb")
1051 }
1052}};
1053
1054def format Thumb32DataProcPlainBin() {{
1055 decode_block = '''
1056 {
1057 const uint32_t op = bits(machInst, 24, 20);
1058 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1059 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1060 switch (op) {
1061 case 0x0:
1062 {
1063 const uint32_t imm = bits(machInst, 7, 0) |
1064 (bits(machInst, 14, 12) << 8) |
1065 (bits(machInst, 26) << 11);
1066 if (rn == 0xf) {
1067 return new AdrImm(machInst, rd, (IntRegIndex)1,
1068 imm, false);
1069 } else {
1070 return new AddImm(machInst, rd, rn, imm, true);
1071 }
1072 }
1073 case 0x4:
1074 {
1075 const uint32_t imm = bits(machInst, 7, 0) |
1076 (bits(machInst, 14, 12) << 8) |
1077 (bits(machInst, 26) << 11) |
1078 (bits(machInst, 19, 16) << 12);
1079 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1080 }
1081 case 0xa:
1082 {
1083 const uint32_t imm = bits(machInst, 7, 0) |
1084 (bits(machInst, 14, 12) << 8) |
1085 (bits(machInst, 26) << 11);
1086 if (rn == 0xf) {
1087 return new AdrImm(machInst, rd, (IntRegIndex)0,
1088 imm, false);
1089 } else {
1090 return new SubImm(machInst, rd, rn, imm, true);
1091 }
1092 }
1093 case 0xc:
1094 {
1095 const uint32_t imm = bits(machInst, 7, 0) |
1096 (bits(machInst, 14, 12) << 8) |
1097 (bits(machInst, 26) << 11) |
1098 (bits(machInst, 19, 16) << 12);
1099 return new MovtImm(machInst, rd, rd, imm, true);
1100 }
1101 case 0x12:
1102 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1103 return new WarnUnimplemented("ssat16", machInst);
1104 }
1105 // Fall through on purpose...
1106 case 0x10:
1107 return new WarnUnimplemented("ssat", machInst);
1108 case 0x14:
1109 return new WarnUnimplemented("sbfx", machInst);
1110 case 0x16:
1111 if (rn == 0xf) {
1112 return new WarnUnimplemented("bfc", machInst);
1113 } else {
1114 return new WarnUnimplemented("bfi", machInst);
1115 }
1116 case 0x1a:
1117 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1118 return new WarnUnimplemented("usat16", machInst);
1119 }
1120 // Fall through on purpose...
1121 case 0x18:
1122 return new WarnUnimplemented("usat", machInst);
1123 case 0x1c:
1124 return new WarnUnimplemented("ubfx", machInst);
1125 default:
1126 return new Unknown(machInst);
1127 }
1128 }
1129 '''
1130}};
1131
1132def format Thumb32DataProcShiftReg() {{
1133
1134 def decInst(mnem, dest="rd", op1="rn"):
1135 return '''
1136 if (s) {
1137 return new %(mnem)sRegCc(machInst, %(dest)s,
1138 %(op1)s, rm, amt, type);
1139 } else {
1140 return new %(mnem)sReg(machInst, %(dest)s,
1141 %(op1)s, rm, amt, type);
1142 }
1143 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1144
1145 decode_block = '''
1146 {
1147 const uint32_t op = bits(machInst, 24, 21);
1148 const bool s = (bits(machInst, 20) == 1);
1149 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1150 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1151 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1152 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1153 bits(machInst, 7, 6);
1154 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1155 switch (op) {
1156 case 0x0:
1157 if (rd == INTREG_PC) {
1158 %(tst)s
1159 } else {
1160 %(and)s
1161 }
1162 case 0x1:
1163 %(bic)s
1164 case 0x2:
1165 if (rn == INTREG_PC) {
1166 %(mov)s
1167 } else {
1168 %(orr)s
1169 }
1170 case 0x3:
1171 if (rn == INTREG_PC) {
1172 %(mvn)s
1173 } else {
1174 %(orn)s
1175 }
1176 case 0x4:
1177 if (rd == INTREG_PC) {
1178 %(teq)s
1179 } else {
1180 %(eor)s
1181 }
1182 case 0x6:
1183 return new WarnUnimplemented("pkh", machInst);
1184 case 0x8:
1185 if (rd == INTREG_PC) {
1186 %(cmn)s
1187 } else {
1188 %(add)s
1189 }
1190 case 0xa:
1191 %(adc)s
1192 case 0xb:
1193 %(sbc)s
1194 case 0xd:
1195 if (rd == INTREG_PC) {
1196 %(cmp)s
1197 } else {
1198 %(sub)s
1199 }
1200 case 0xe:
1201 %(rsb)s
1202 default:
1203 return new Unknown(machInst);
1204 }
1205 }
1206 ''' % {
1207 "tst" : decInst("Tst", "INTREG_ZERO"),
1208 "and" : decInst("And"),
1209 "bic" : decInst("Bic"),
1210 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1211 "orr" : decInst("Orr"),
1212 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1213 "orn" : decInst("Orn"),
1214 "teq" : decInst("Teq", "INTREG_ZERO"),
1215 "eor" : decInst("Eor"),
1216 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1217 "add" : decInst("Add"),
1218 "adc" : decInst("Adc"),
1219 "sbc" : decInst("Sbc"),
1220 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1221 "sub" : decInst("Sub"),
1222 "rsb" : decInst("Rsb")
1223 }
1224}};
627 }
628 break;
629 case 0x1:
630 switch (op1) {
631 case 0x1:
632 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
633 case 0x2:
634 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
635 case 0x6:
636 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
637 case 0x5:
638 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
639 case 0x0:
640 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
641 case 0x4:
642 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
643 }
644 break;
645 case 0x2:
646 switch (op1) {
647 case 0x1:
648 return new WarnUnimplemented("uhadd16", machInst);
649 case 0x2:
650 return new WarnUnimplemented("uhasx", machInst);
651 case 0x6:
652 return new WarnUnimplemented("uhsax", machInst);
653 case 0x5:
654 return new WarnUnimplemented("uhsub16", machInst);
655 case 0x0:
656 return new WarnUnimplemented("uhadd8", machInst);
657 case 0x4:
658 return new WarnUnimplemented("uhsub8", machInst);
659 }
660 break;
661 }
662 }
663 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
664 const uint32_t op1 = bits(machInst, 21, 20);
665 const uint32_t op2 = bits(machInst, 5, 4);
666 switch (op1) {
667 case 0x0:
668 {
669 IntRegIndex rd =
670 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
671 IntRegIndex rm =
672 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
673 switch (op2) {
674 case 0x0:
675 return new QaddRegCc(machInst, rd,
676 rm, rn, 0, LSL);
677 case 0x1:
678 return new QdaddRegCc(machInst, rd,
679 rm, rn, 0, LSL);
680 case 0x2:
681 return new QsubRegCc(machInst, rd,
682 rm, rn, 0, LSL);
683 case 0x3:
684 return new QdsubRegCc(machInst, rd,
685 rm, rn, 0, LSL);
686 }
687 }
688 break;
689 case 0x1:
690 {
691 IntRegIndex rd =
692 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
693 IntRegIndex rm = rn;
694 switch (op2) {
695 case 0x0:
696 return new Rev(machInst, rd, rm);
697 case 0x1:
698 return new Rev16(machInst, rd, rm);
699 case 0x2:
700 return new WarnUnimplemented("rbit", machInst);
701 case 0x3:
702 return new Revsh(machInst, rd, rm);
703 }
704 }
705 break;
706 case 0x2:
707 if (op2 == 0) {
708 return new WarnUnimplemented("sel", machInst);
709 }
710 break;
711 case 0x3:
712 if (op2 == 0) {
713 return new WarnUnimplemented("clz", machInst);
714 }
715 }
716 }
717 return new Unknown(machInst);
718 }
719 }
720 '''
721}};
722
723def format Thumb16ShiftAddSubMoveCmp() {{
724 decode_block = '''
725 {
726 const uint32_t imm5 = bits(machInst, 10, 6);
727 const uint32_t imm3 = bits(machInst, 8, 6);
728 const uint32_t imm8 = bits(machInst, 7, 0);
729 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
730 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
731 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
732 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
733 switch (bits(machInst, 13, 11)) {
734 case 0x0: // lsl
735 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
736 case 0x1: // lsr
737 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
738 case 0x2: // asr
739 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
740 case 0x3:
741 switch (bits(machInst, 10, 9)) {
742 case 0x0:
743 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
744 case 0x1:
745 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
746 case 0x2:
747 return new AddImmCc(machInst, rd, rn, imm3, true);
748 case 0x3:
749 return new SubImmCc(machInst, rd, rn, imm3, true);
750 }
751 case 0x4:
752 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
753 case 0x5:
754 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
755 case 0x6:
756 return new AddImmCc(machInst, rd8, rd8, imm8, true);
757 case 0x7:
758 return new SubImmCc(machInst, rd8, rd8, imm8, true);
759 }
760 }
761 '''
762}};
763
764def format Thumb16DataProcessing() {{
765 decode_block = '''
766 {
767 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
768 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
769 switch (bits(machInst, 9, 6)) {
770 case 0x0:
771 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
772 case 0x1:
773 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
774 case 0x2: //lsl
775 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
776 case 0x3: //lsr
777 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
778 case 0x4: //asr
779 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
780 case 0x5:
781 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
782 case 0x6:
783 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
784 case 0x7: // ror
785 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
786 case 0x8:
787 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
788 case 0x9:
789 return new RsbImmCc(machInst, rdn, rm, 0, true);
790 case 0xa:
791 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
792 case 0xb:
793 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
794 case 0xc:
795 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
796 case 0xd:
797 return new MulCc(machInst, rdn, rm, rdn);
798 case 0xe:
799 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
800 case 0xf:
801 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
802 }
803 }
804 '''
805}};
806
807def format Thumb16SpecDataAndBx() {{
808 decode_block = '''
809 {
810 const IntRegIndex rdn =
811 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
812 (bits(machInst, 7) << 3));
813 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
814 switch (bits(machInst, 9, 8)) {
815 case 0x0:
816 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
817 case 0x1:
818 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
819 case 0x2:
820 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
821 case 0x3:
822 if (bits(machInst, 7) == 0) {
823 return new BxReg(machInst,
824 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
825 COND_UC);
826 } else {
827 return new BlxReg(machInst,
828 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
829 COND_UC);
830 }
831 }
832 }
833 '''
834}};
835
836def format Thumb16Adr() {{
837 decode_block = '''
838 {
839 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
840 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
841 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
842 }
843 '''
844}};
845
846def format Thumb16AddSp() {{
847 decode_block = '''
848 {
849 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
850 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
851 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
852 }
853 '''
854}};
855
856def format Thumb16Misc() {{
857 decode_block = '''
858 {
859 switch (bits(machInst, 11, 8)) {
860 case 0x0:
861 if (bits(machInst, 7)) {
862 return new SubImm(machInst, INTREG_SP, INTREG_SP,
863 bits(machInst, 6, 0) << 2, true);
864 } else {
865 return new AddImm(machInst, INTREG_SP, INTREG_SP,
866 bits(machInst, 6, 0) << 2, true);
867 }
868 case 0x1:
869 return new Cbz(machInst,
870 (bits(machInst, 9) << 6) |
871 (bits(machInst, 7, 3) << 1),
872 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
873 case 0x2:
874 switch (bits(machInst, 7, 6)) {
875 case 0x0:
876 return new WarnUnimplemented("sxth", machInst);
877 case 0x1:
878 return new WarnUnimplemented("sxtb", machInst);
879 case 0x2:
880 return new WarnUnimplemented("uxth", machInst);
881 case 0x3:
882 return new WarnUnimplemented("uxtb", machInst);
883 }
884 case 0x3:
885 return new Cbz(machInst,
886 (bits(machInst, 9) << 6) |
887 (bits(machInst, 7, 3) << 1),
888 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
889 case 0x4:
890 case 0x5:
891 {
892 const uint32_t m = bits(machInst, 8);
893 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
894 return new LdmStm(machInst, INTREG_SP, false, false, false,
895 true, false, regList);
896 }
897 case 0x6:
898 {
899 const uint32_t opBits = bits(machInst, 7, 5);
900 if (opBits == 2) {
901 return new WarnUnimplemented("setend", machInst);
902 } else if (opBits == 3) {
903 return new WarnUnimplemented("cps", machInst);
904 }
905 }
906 case 0x9:
907 return new Cbnz(machInst,
908 (bits(machInst, 9) << 6) |
909 (bits(machInst, 7, 3) << 1),
910 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
911 case 0xa:
912 {
913 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
914 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
915 switch (bits(machInst, 7, 6)) {
916 case 0x0:
917 return new Rev(machInst, rd, rm);
918 case 0x1:
919 return new Rev16(machInst, rd, rm);
920 case 0x3:
921 return new Revsh(machInst, rd, rm);
922 default:
923 break;
924 }
925 }
926 break;
927 case 0xb:
928 return new Cbnz(machInst,
929 (bits(machInst, 9) << 6) |
930 (bits(machInst, 7, 3) << 1),
931 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
932 case 0xc:
933 case 0xd:
934 {
935 const uint32_t p = bits(machInst, 8);
936 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
937 return new LdmStm(machInst, INTREG_SP, true, true, false,
938 true, true, regList);
939 }
940 case 0xe:
941 return new WarnUnimplemented("bkpt", machInst);
942 case 0xf:
943 if (bits(machInst, 3, 0) != 0)
944 return new WarnUnimplemented("it", machInst);
945 switch (bits(machInst, 7, 4)) {
946 case 0x0:
947 return new WarnUnimplemented("nop", machInst);
948 case 0x1:
949 return new WarnUnimplemented("yield", machInst);
950 case 0x2:
951 return new WarnUnimplemented("wfe", machInst);
952 case 0x3:
953 return new WarnUnimplemented("wfi", machInst);
954 case 0x4:
955 return new WarnUnimplemented("sev", machInst);
956 default:
957 return new WarnUnimplemented("unallocated_hint", machInst);
958 }
959 default:
960 break;
961 }
962 return new Unknown(machInst);
963 }
964 '''
965}};
966
967def format Thumb32DataProcModImm() {{
968
969 def decInst(mnem, dest="rd", op1="rn"):
970 return '''
971 if (s) {
972 return new %(mnem)sImmCc(machInst, %(dest)s,
973 %(op1)s, imm, rotC);
974 } else {
975 return new %(mnem)sImm(machInst, %(dest)s,
976 %(op1)s, imm, rotC);
977 }
978 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
979
980 decode_block = '''
981 {
982 const uint32_t op = bits(machInst, 24, 21);
983 const bool s = (bits(machInst, 20) == 1);
984 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
985 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
986 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
987 bits(machInst, 14, 12);
988 const bool rotC = ctrlImm > 3;
989 const uint32_t dataImm = bits(machInst, 7, 0);
990 const uint32_t imm = modified_imm(ctrlImm, dataImm);
991 switch (op) {
992 case 0x0:
993 if (rd == INTREG_PC) {
994 %(tst)s
995 } else {
996 %(and)s
997 }
998 case 0x1:
999 %(bic)s
1000 case 0x2:
1001 if (rn == INTREG_PC) {
1002 %(mov)s
1003 } else {
1004 %(orr)s
1005 }
1006 case 0x3:
1007 if (rn == INTREG_PC) {
1008 %(mvn)s
1009 } else {
1010 %(orn)s
1011 }
1012 case 0x4:
1013 if (rd == INTREG_PC) {
1014 %(teq)s
1015 } else {
1016 %(eor)s
1017 }
1018 case 0x8:
1019 if (rd == INTREG_PC) {
1020 %(cmn)s
1021 } else {
1022 %(add)s
1023 }
1024 case 0xa:
1025 %(adc)s
1026 case 0xb:
1027 %(sbc)s
1028 case 0xd:
1029 if (rd == INTREG_PC) {
1030 %(cmp)s
1031 } else {
1032 %(sub)s
1033 }
1034 case 0xe:
1035 %(rsb)s
1036 default:
1037 return new Unknown(machInst);
1038 }
1039 }
1040 ''' % {
1041 "tst" : decInst("Tst", "INTREG_ZERO"),
1042 "and" : decInst("And"),
1043 "bic" : decInst("Bic"),
1044 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1045 "orr" : decInst("Orr"),
1046 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1047 "orn" : decInst("Orn"),
1048 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1049 "eor" : decInst("Eor"),
1050 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1051 "add" : decInst("Add"),
1052 "adc" : decInst("Adc"),
1053 "sbc" : decInst("Sbc"),
1054 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1055 "sub" : decInst("Sub"),
1056 "rsb" : decInst("Rsb")
1057 }
1058}};
1059
1060def format Thumb32DataProcPlainBin() {{
1061 decode_block = '''
1062 {
1063 const uint32_t op = bits(machInst, 24, 20);
1064 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1065 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1066 switch (op) {
1067 case 0x0:
1068 {
1069 const uint32_t imm = bits(machInst, 7, 0) |
1070 (bits(machInst, 14, 12) << 8) |
1071 (bits(machInst, 26) << 11);
1072 if (rn == 0xf) {
1073 return new AdrImm(machInst, rd, (IntRegIndex)1,
1074 imm, false);
1075 } else {
1076 return new AddImm(machInst, rd, rn, imm, true);
1077 }
1078 }
1079 case 0x4:
1080 {
1081 const uint32_t imm = bits(machInst, 7, 0) |
1082 (bits(machInst, 14, 12) << 8) |
1083 (bits(machInst, 26) << 11) |
1084 (bits(machInst, 19, 16) << 12);
1085 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1086 }
1087 case 0xa:
1088 {
1089 const uint32_t imm = bits(machInst, 7, 0) |
1090 (bits(machInst, 14, 12) << 8) |
1091 (bits(machInst, 26) << 11);
1092 if (rn == 0xf) {
1093 return new AdrImm(machInst, rd, (IntRegIndex)0,
1094 imm, false);
1095 } else {
1096 return new SubImm(machInst, rd, rn, imm, true);
1097 }
1098 }
1099 case 0xc:
1100 {
1101 const uint32_t imm = bits(machInst, 7, 0) |
1102 (bits(machInst, 14, 12) << 8) |
1103 (bits(machInst, 26) << 11) |
1104 (bits(machInst, 19, 16) << 12);
1105 return new MovtImm(machInst, rd, rd, imm, true);
1106 }
1107 case 0x12:
1108 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1109 return new WarnUnimplemented("ssat16", machInst);
1110 }
1111 // Fall through on purpose...
1112 case 0x10:
1113 return new WarnUnimplemented("ssat", machInst);
1114 case 0x14:
1115 return new WarnUnimplemented("sbfx", machInst);
1116 case 0x16:
1117 if (rn == 0xf) {
1118 return new WarnUnimplemented("bfc", machInst);
1119 } else {
1120 return new WarnUnimplemented("bfi", machInst);
1121 }
1122 case 0x1a:
1123 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1124 return new WarnUnimplemented("usat16", machInst);
1125 }
1126 // Fall through on purpose...
1127 case 0x18:
1128 return new WarnUnimplemented("usat", machInst);
1129 case 0x1c:
1130 return new WarnUnimplemented("ubfx", machInst);
1131 default:
1132 return new Unknown(machInst);
1133 }
1134 }
1135 '''
1136}};
1137
1138def format Thumb32DataProcShiftReg() {{
1139
1140 def decInst(mnem, dest="rd", op1="rn"):
1141 return '''
1142 if (s) {
1143 return new %(mnem)sRegCc(machInst, %(dest)s,
1144 %(op1)s, rm, amt, type);
1145 } else {
1146 return new %(mnem)sReg(machInst, %(dest)s,
1147 %(op1)s, rm, amt, type);
1148 }
1149 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1150
1151 decode_block = '''
1152 {
1153 const uint32_t op = bits(machInst, 24, 21);
1154 const bool s = (bits(machInst, 20) == 1);
1155 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1156 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1157 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1158 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1159 bits(machInst, 7, 6);
1160 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1161 switch (op) {
1162 case 0x0:
1163 if (rd == INTREG_PC) {
1164 %(tst)s
1165 } else {
1166 %(and)s
1167 }
1168 case 0x1:
1169 %(bic)s
1170 case 0x2:
1171 if (rn == INTREG_PC) {
1172 %(mov)s
1173 } else {
1174 %(orr)s
1175 }
1176 case 0x3:
1177 if (rn == INTREG_PC) {
1178 %(mvn)s
1179 } else {
1180 %(orn)s
1181 }
1182 case 0x4:
1183 if (rd == INTREG_PC) {
1184 %(teq)s
1185 } else {
1186 %(eor)s
1187 }
1188 case 0x6:
1189 return new WarnUnimplemented("pkh", machInst);
1190 case 0x8:
1191 if (rd == INTREG_PC) {
1192 %(cmn)s
1193 } else {
1194 %(add)s
1195 }
1196 case 0xa:
1197 %(adc)s
1198 case 0xb:
1199 %(sbc)s
1200 case 0xd:
1201 if (rd == INTREG_PC) {
1202 %(cmp)s
1203 } else {
1204 %(sub)s
1205 }
1206 case 0xe:
1207 %(rsb)s
1208 default:
1209 return new Unknown(machInst);
1210 }
1211 }
1212 ''' % {
1213 "tst" : decInst("Tst", "INTREG_ZERO"),
1214 "and" : decInst("And"),
1215 "bic" : decInst("Bic"),
1216 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1217 "orr" : decInst("Orr"),
1218 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1219 "orn" : decInst("Orn"),
1220 "teq" : decInst("Teq", "INTREG_ZERO"),
1221 "eor" : decInst("Eor"),
1222 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1223 "add" : decInst("Add"),
1224 "adc" : decInst("Adc"),
1225 "sbc" : decInst("Sbc"),
1226 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1227 "sub" : decInst("Sub"),
1228 "rsb" : decInst("Rsb")
1229 }
1230}};