data.isa (7237:4c1445a9e72b) data.isa (7240:40a17fb6a9c5)
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 const IntRegIndex rn =
135 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
136 const IntRegIndex rd =
137 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
138 const uint32_t satImm = bits(machInst, 20, 16);
139 const uint32_t imm = bits(machInst, 11, 7);
140 const ArmShiftType type =
141 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
142 if (op1 == 0) {
143 if (type) {
144 return new PkhtbReg(machInst, rd, (IntRegIndex)a,
145 rn, imm, type);
146 } else {
147 return new PkhbtReg(machInst, rd, (IntRegIndex)a,
148 rn, imm, type);
149 }
150 } else if (bits(op1, 2, 1) == 1) {
151 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
152 } else if (bits(op1, 2, 1) == 3) {
153 return new Usat(machInst, rd, satImm, rn, imm, type);
154 }
155 return new Unknown(machInst);
156 }
157 switch (op1) {
158 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 const IntRegIndex rn =
135 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
136 const IntRegIndex rd =
137 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
138 const uint32_t satImm = bits(machInst, 20, 16);
139 const uint32_t imm = bits(machInst, 11, 7);
140 const ArmShiftType type =
141 (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
142 if (op1 == 0) {
143 if (type) {
144 return new PkhtbReg(machInst, rd, (IntRegIndex)a,
145 rn, imm, type);
146 } else {
147 return new PkhbtReg(machInst, rd, (IntRegIndex)a,
148 rn, imm, type);
149 }
150 } else if (bits(op1, 2, 1) == 1) {
151 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
152 } else if (bits(op1, 2, 1) == 3) {
153 return new Usat(machInst, rd, satImm, rn, imm, type);
154 }
155 return new Unknown(machInst);
156 }
157 switch (op1) {
158 case 0x0:
159 if (op2 == 0x3) {
159 {
160 const IntRegIndex rn =
161 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
162 const IntRegIndex rd =
163 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
164 const IntRegIndex rm =
165 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
160 const IntRegIndex rn =
161 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
162 const IntRegIndex rd =
163 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
164 const IntRegIndex rm =
165 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
166 const uint32_t rotation =
167 (uint32_t)bits(machInst, 11, 10) << 3;
168 if (a == 0xf) {
169 return new Sxtb16(machInst, rd, rotation, rm);
170 } else {
171 return new Sxtab16(machInst, rd, rn, rm, rotation);
166 if (op2 == 0x3) {
167 const uint32_t rotation =
168 (uint32_t)bits(machInst, 11, 10) << 3;
169 if (a == 0xf) {
170 return new Sxtb16(machInst, rd, rotation, rm);
171 } else {
172 return new Sxtab16(machInst, rd, rn, rm, rotation);
173 }
174 } else if (op2 == 0x5) {
175 return new Sel(machInst, rd, rn, rm);
172 }
176 }
173 } else if (op2 == 0x5) {
174 return new WarnUnimplemented("sel", machInst);
175 }
176 break;
177 case 0x2:
178 if (op2 == 0x1) {
179 const IntRegIndex rn =
180 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
181 const IntRegIndex rd =
182 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
183 const uint32_t satImm = bits(machInst, 20, 16);
184 return new Ssat16(machInst, rd, satImm + 1, rn);
185 } else if (op2 == 0x3) {
186 const IntRegIndex rn =
187 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
188 const IntRegIndex rd =
189 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
190 const IntRegIndex rm =
191 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
192 const uint32_t rotation =
193 (uint32_t)bits(machInst, 11, 10) << 3;
194 if (a == 0xf) {
195 return new Sxtb(machInst, rd, rotation, rm);
196 } else {
197 return new Sxtab(machInst, rd, rn, rm, rotation);
198 }
199 }
200 break;
201 case 0x3:
202 if (op2 == 0x1) {
203 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
204 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
205 return new Rev(machInst, rd, rm);
206 } else if (op2 == 0x3) {
207 const IntRegIndex rn =
208 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
209 const IntRegIndex rd =
210 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
211 const IntRegIndex rm =
212 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
213 const uint32_t rotation =
214 (uint32_t)bits(machInst, 11, 10) << 3;
215 if (a == 0xf) {
216 return new Sxth(machInst, rd, rotation, rm);
217 } else {
218 return new Sxtah(machInst, rd, rn, rm, rotation);
219 }
220 } else if (op2 == 0x5) {
221 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
222 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
223 return new Rev16(machInst, rd, rm);
224 }
225 break;
226 case 0x4:
227 if (op2 == 0x3) {
228 const IntRegIndex rn =
229 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
230 const IntRegIndex rd =
231 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
232 const IntRegIndex rm =
233 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
234 const uint32_t rotation =
235 (uint32_t)bits(machInst, 11, 10) << 3;
236 if (a == 0xf) {
237 return new Uxtb16(machInst, rd, rotation, rm);
238 } else {
239 return new Uxtab16(machInst, rd, rn, rm, rotation);
240 }
241 }
242 break;
243 case 0x6:
244 if (op2 == 0x1) {
245 const IntRegIndex rn =
246 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
247 const IntRegIndex rd =
248 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
249 const uint32_t satImm = bits(machInst, 20, 16);
250 return new Usat16(machInst, rd, satImm, rn);
251 } else if (op2 == 0x3) {
252 const IntRegIndex rn =
253 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
254 const IntRegIndex rd =
255 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
256 const IntRegIndex rm =
257 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
258 const uint32_t rotation =
259 (uint32_t)bits(machInst, 11, 10) << 3;
260 if (a == 0xf) {
261 return new Uxtb(machInst, rd, rotation, rm);
262 } else {
263 return new Uxtab(machInst, rd, rn, rm, rotation);
264 }
265 }
266 break;
267 case 0x7:
268 if (op2 == 0x1) {
269 return new WarnUnimplemented("rbit", machInst);
270 } else if (op2 == 0x3) {
271 const IntRegIndex rn =
272 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
273 const IntRegIndex rd =
274 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
275 const IntRegIndex rm =
276 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
277 const uint32_t rotation =
278 (uint32_t)bits(machInst, 11, 10) << 3;
279 if (a == 0xf) {
280 return new Uxth(machInst, rd, rotation, rm);
281 } else {
282 return new Uxtah(machInst, rd, rn, rm, rotation);
283 }
284 } else if (op2 == 0x5) {
285 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
286 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
287 return new Revsh(machInst, rd, rm);
288 }
289 break;
290 }
291 return new Unknown(machInst);
292 }
293 '''
294}};
295
296def format ArmParallelAddSubtract() {{
297 decode_block='''
298 {
299 const uint32_t op1 = bits(machInst, 21, 20);
300 const uint32_t op2 = bits(machInst, 7, 5);
301 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
302 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
303 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
304 if (bits(machInst, 22) == 0) {
305 switch (op1) {
306 case 0x1:
307 switch (op2) {
308 case 0x0:
309 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
310 case 0x1:
311 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
312 case 0x2:
313 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
314 case 0x3:
315 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
316 case 0x4:
317 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
318 case 0x7:
319 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
320 }
321 break;
322 case 0x2:
323 switch (op2) {
324 case 0x0:
325 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
326 case 0x1:
327 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
328 case 0x2:
329 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
330 case 0x3:
331 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
332 case 0x4:
333 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
334 case 0x7:
335 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
336 }
337 break;
338 case 0x3:
339 switch (op2) {
340 case 0x0:
341 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
342 case 0x1:
343 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
344 case 0x2:
345 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
346 case 0x3:
347 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
348 case 0x4:
349 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
350 case 0x7:
351 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
352 }
353 break;
354 }
355 } else {
356 switch (op1) {
357 case 0x1:
358 switch (op2) {
359 case 0x0:
360 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
361 case 0x1:
362 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
363 case 0x2:
364 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
365 case 0x3:
366 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
367 case 0x4:
368 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
369 case 0x7:
370 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
371 }
372 break;
373 case 0x2:
374 switch (op2) {
375 case 0x0:
376 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
377 case 0x1:
378 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
379 case 0x2:
380 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
381 case 0x3:
382 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
383 case 0x4:
384 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
385 case 0x7:
386 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
387 }
388 break;
389 case 0x3:
390 switch (op2) {
391 case 0x0:
392 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
393 case 0x1:
394 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
395 case 0x2:
396 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
397 case 0x3:
398 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
399 case 0x4:
400 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
401 case 0x7:
402 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
403 }
404 break;
405 }
406 }
407 return new Unknown(machInst);
408 }
409 '''
410}};
411
412def format ArmDataProcImm() {{
413 pclr = '''
414 return new %(className)ssImmPclr(machInst, %(dest)s,
415 %(op1)s, imm, false);
416 '''
417 adr = '''
418 return new AdrImm(machInst, %(dest)s, %(add)s,
419 imm, false);
420 '''
421 instDecode = '''
422 case %(opcode)#x:
423 if (setCc) {
424 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
425 %(pclr)s
426 } else {
427 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
428 imm, rotC);
429 }
430 } else {
431 if (%(adrInst)s && %(op1)s == INTREG_PC) {
432 %(adr)s
433 } else {
434 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
435 imm, rotC);
436 }
437 }
438 break;
439 '''
440
441 def instCode(opcode, mnem, useDest = True, useOp1 = True):
442 global instDecode, pclr, adr
443 if useDest:
444 dest = "rd"
445 else:
446 dest = "INTREG_ZERO"
447 if useOp1:
448 op1 = "rn"
449 else:
450 op1 = "INTREG_ZERO"
451 substDict = { "className": mnem.capitalize(),
452 "opcode": opcode,
453 "dest": dest,
454 "op1": op1,
455 "adr": "",
456 "adrInst": "false" }
457 if useDest:
458 substDict["pclrInst"] = "true"
459 substDict["pclr"] = pclr % substDict
460 else:
461 substDict["pclrInst"] = "false"
462 substDict["pclr"] = ""
463 return instDecode % substDict
464
465 def adrCode(opcode, mnem, add="1"):
466 global instDecode, pclr, adr
467 substDict = { "className": mnem.capitalize(),
468 "opcode": opcode,
469 "dest": "rd",
470 "op1": "rn",
471 "add": add,
472 "pclrInst": "true",
473 "adrInst": "true" }
474 substDict["pclr"] = pclr % substDict
475 substDict["adr"] = adr % substDict
476 return instDecode % substDict
477
478 decode_block = '''
479 {
480 const bool setCc = (bits(machInst, 20) == 1);
481 const uint32_t unrotated = bits(machInst, 7, 0);
482 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
483 const bool rotC = (rotation != 0);
484 const uint32_t imm = rotate_imm(unrotated, rotation);
485 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
486 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
487 switch (OPCODE) {
488 '''
489 decode_block += instCode(0x0, "and")
490 decode_block += instCode(0x1, "eor")
491 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
492 decode_block += instCode(0x3, "rsb")
493 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
494 decode_block += instCode(0x5, "adc")
495 decode_block += instCode(0x6, "sbc")
496 decode_block += instCode(0x7, "rsc")
497 decode_block += instCode(0x8, "tst", useDest = False)
498 decode_block += instCode(0x9, "teq", useDest = False)
499 decode_block += instCode(0xa, "cmp", useDest = False)
500 decode_block += instCode(0xb, "cmn", useDest = False)
501 decode_block += instCode(0xc, "orr")
502 decode_block += instCode(0xd, "mov", useOp1 = False)
503 decode_block += instCode(0xe, "bic")
504 decode_block += instCode(0xf, "mvn", useOp1 = False)
505 decode_block += '''
506 default:
507 return new Unknown(machInst);
508 }
509 }
510 '''
511}};
512
513def format ArmSatAddSub() {{
514 decode_block = '''
515 {
516 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
517 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
518 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
519 switch (OPCODE) {
520 case 0x8:
521 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
522 case 0x9:
523 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
524 case 0xa:
525 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
526 case 0xb:
527 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
528 default:
529 return new Unknown(machInst);
530 }
531 }
532 '''
533}};
534
535def format Thumb32DataProcReg() {{
536 decode_block = '''
537 {
538 const uint32_t op1 = bits(machInst, 23, 20);
539 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
540 const uint32_t op2 = bits(machInst, 7, 4);
541 if (bits(op1, 3) != 1) {
542 if (op2 == 0) {
543 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
544 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
545 switch (bits(op1, 2, 0)) {
546 case 0x0:
547 return new MovRegReg(machInst, rd,
548 INTREG_ZERO, rn, rm, LSL);
549 case 0x1:
550 return new MovRegRegCc(machInst, rd,
551 INTREG_ZERO, rn, rm, LSL);
552 case 0x2:
553 return new MovRegReg(machInst, rd,
554 INTREG_ZERO, rn, rm, LSR);
555 case 0x3:
556 return new MovRegRegCc(machInst, rd,
557 INTREG_ZERO, rn, rm, LSR);
558 case 0x4:
559 return new MovRegReg(machInst, rd,
560 INTREG_ZERO, rn, rm, ASR);
561 case 0x5:
562 return new MovRegRegCc(machInst, rd,
563 INTREG_ZERO, rn, rm, ASR);
564 case 0x6:
565 return new MovRegReg(machInst, rd,
566 INTREG_ZERO, rn, rm, ROR);
567 case 0x7:
568 return new MovRegRegCc(machInst, rd,
569 INTREG_ZERO, rn, rm, ROR);
570 }
571 }
572 {
573 const IntRegIndex rd =
574 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
575 const IntRegIndex rm =
576 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
577 const uint32_t rotation =
578 (uint32_t)bits(machInst, 5, 4) << 3;
579 switch (bits(op1, 2, 0)) {
580 case 0x0:
581 if (rn == 0xf) {
582 return new Sxth(machInst, rd, rotation, rm);
583 } else {
584 return new Sxtah(machInst, rd, rn, rm, rotation);
585 }
586 case 0x1:
587 if (rn == 0xf) {
588 return new Uxth(machInst, rd, rotation, rm);
589 } else {
590 return new Uxtah(machInst, rd, rn, rm, rotation);
591 }
592 case 0x2:
593 if (rn == 0xf) {
594 return new Sxtb16(machInst, rd, rotation, rm);
595 } else {
596 return new Sxtab16(machInst, rd, rn, rm, rotation);
597 }
598 case 0x3:
599 if (rn == 0xf) {
600 return new Uxtb16(machInst, rd, rotation, rm);
601 } else {
602 return new Uxtab16(machInst, rd, rn, rm, rotation);
603 }
604 case 0x4:
605 if (rn == 0xf) {
606 return new Sxtb(machInst, rd, rotation, rm);
607 } else {
608 return new Sxtab(machInst, rd, rn, rm, rotation);
609 }
610 case 0x5:
611 if (rn == 0xf) {
612 return new Uxtb(machInst, rd, rotation, rm);
613 } else {
614 return new Uxtab(machInst, rd, rn, rm, rotation);
615 }
616 default:
617 return new Unknown(machInst);
618 }
619 }
620 } else {
621 if (bits(op2, 3) == 0) {
622 const IntRegIndex rd =
623 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
624 const IntRegIndex rm =
625 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
626 if (bits(op2, 2) == 0x0) {
627 const uint32_t op1 = bits(machInst, 22, 20);
628 const uint32_t op2 = bits(machInst, 5, 4);
629 switch (op2) {
630 case 0x0:
631 switch (op1) {
632 case 0x1:
633 return new Sadd16RegCc(machInst, rd,
634 rn, rm, 0, LSL);
635 case 0x2:
636 return new SasxRegCc(machInst, rd,
637 rn, rm, 0, LSL);
638 case 0x6:
639 return new SsaxRegCc(machInst, rd,
640 rn, rm, 0, LSL);
641 case 0x5:
642 return new Ssub16RegCc(machInst, rd,
643 rn, rm, 0, LSL);
644 case 0x0:
645 return new Sadd8RegCc(machInst, rd,
646 rn, rm, 0, LSL);
647 case 0x4:
648 return new Ssub8RegCc(machInst, rd,
649 rn, rm, 0, LSL);
650 }
651 break;
652 case 0x1:
653 switch (op1) {
654 case 0x1:
655 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
656 case 0x2:
657 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
658 case 0x6:
659 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
660 case 0x5:
661 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
662 case 0x0:
663 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
664 case 0x4:
665 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
666 }
667 break;
668 case 0x2:
669 switch (op1) {
670 case 0x1:
671 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
672 case 0x2:
673 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
674 case 0x6:
675 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
676 case 0x5:
677 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
678 case 0x0:
679 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
680 case 0x4:
681 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
682 }
683 break;
684 }
685 } else {
686 const uint32_t op1 = bits(machInst, 22, 20);
687 const uint32_t op2 = bits(machInst, 5, 4);
688 switch (op2) {
689 case 0x0:
690 switch (op1) {
691 case 0x1:
692 return new Uadd16RegCc(machInst, rd,
693 rn, rm, 0, LSL);
694 case 0x2:
695 return new UasxRegCc(machInst, rd,
696 rn, rm, 0, LSL);
697 case 0x6:
698 return new UsaxRegCc(machInst, rd,
699 rn, rm, 0, LSL);
700 case 0x5:
701 return new Usub16RegCc(machInst, rd,
702 rn, rm, 0, LSL);
703 case 0x0:
704 return new Uadd8RegCc(machInst, rd,
705 rn, rm, 0, LSL);
706 case 0x4:
707 return new Usub8RegCc(machInst, rd,
708 rn, rm, 0, LSL);
709 }
710 break;
711 case 0x1:
712 switch (op1) {
713 case 0x1:
714 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
715 case 0x2:
716 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
717 case 0x6:
718 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
719 case 0x5:
720 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
721 case 0x0:
722 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
723 case 0x4:
724 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
725 }
726 break;
727 case 0x2:
728 switch (op1) {
729 case 0x1:
730 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
731 case 0x2:
732 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
733 case 0x6:
734 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
735 case 0x5:
736 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
737 case 0x0:
738 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
739 case 0x4:
740 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
741 }
742 break;
743 }
744 }
745 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
746 const uint32_t op1 = bits(machInst, 21, 20);
747 const uint32_t op2 = bits(machInst, 5, 4);
177 }
178 break;
179 case 0x2:
180 if (op2 == 0x1) {
181 const IntRegIndex rn =
182 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
183 const IntRegIndex rd =
184 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
185 const uint32_t satImm = bits(machInst, 20, 16);
186 return new Ssat16(machInst, rd, satImm + 1, rn);
187 } else if (op2 == 0x3) {
188 const IntRegIndex rn =
189 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
190 const IntRegIndex rd =
191 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
192 const IntRegIndex rm =
193 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
194 const uint32_t rotation =
195 (uint32_t)bits(machInst, 11, 10) << 3;
196 if (a == 0xf) {
197 return new Sxtb(machInst, rd, rotation, rm);
198 } else {
199 return new Sxtab(machInst, rd, rn, rm, rotation);
200 }
201 }
202 break;
203 case 0x3:
204 if (op2 == 0x1) {
205 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
206 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
207 return new Rev(machInst, rd, rm);
208 } else if (op2 == 0x3) {
209 const IntRegIndex rn =
210 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
211 const IntRegIndex rd =
212 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
213 const IntRegIndex rm =
214 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
215 const uint32_t rotation =
216 (uint32_t)bits(machInst, 11, 10) << 3;
217 if (a == 0xf) {
218 return new Sxth(machInst, rd, rotation, rm);
219 } else {
220 return new Sxtah(machInst, rd, rn, rm, rotation);
221 }
222 } else if (op2 == 0x5) {
223 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
224 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
225 return new Rev16(machInst, rd, rm);
226 }
227 break;
228 case 0x4:
229 if (op2 == 0x3) {
230 const IntRegIndex rn =
231 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
232 const IntRegIndex rd =
233 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
234 const IntRegIndex rm =
235 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
236 const uint32_t rotation =
237 (uint32_t)bits(machInst, 11, 10) << 3;
238 if (a == 0xf) {
239 return new Uxtb16(machInst, rd, rotation, rm);
240 } else {
241 return new Uxtab16(machInst, rd, rn, rm, rotation);
242 }
243 }
244 break;
245 case 0x6:
246 if (op2 == 0x1) {
247 const IntRegIndex rn =
248 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
249 const IntRegIndex rd =
250 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
251 const uint32_t satImm = bits(machInst, 20, 16);
252 return new Usat16(machInst, rd, satImm, rn);
253 } else if (op2 == 0x3) {
254 const IntRegIndex rn =
255 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
256 const IntRegIndex rd =
257 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
258 const IntRegIndex rm =
259 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
260 const uint32_t rotation =
261 (uint32_t)bits(machInst, 11, 10) << 3;
262 if (a == 0xf) {
263 return new Uxtb(machInst, rd, rotation, rm);
264 } else {
265 return new Uxtab(machInst, rd, rn, rm, rotation);
266 }
267 }
268 break;
269 case 0x7:
270 if (op2 == 0x1) {
271 return new WarnUnimplemented("rbit", machInst);
272 } else if (op2 == 0x3) {
273 const IntRegIndex rn =
274 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
275 const IntRegIndex rd =
276 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
277 const IntRegIndex rm =
278 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
279 const uint32_t rotation =
280 (uint32_t)bits(machInst, 11, 10) << 3;
281 if (a == 0xf) {
282 return new Uxth(machInst, rd, rotation, rm);
283 } else {
284 return new Uxtah(machInst, rd, rn, rm, rotation);
285 }
286 } else if (op2 == 0x5) {
287 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
288 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
289 return new Revsh(machInst, rd, rm);
290 }
291 break;
292 }
293 return new Unknown(machInst);
294 }
295 '''
296}};
297
298def format ArmParallelAddSubtract() {{
299 decode_block='''
300 {
301 const uint32_t op1 = bits(machInst, 21, 20);
302 const uint32_t op2 = bits(machInst, 7, 5);
303 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
304 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
305 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
306 if (bits(machInst, 22) == 0) {
307 switch (op1) {
308 case 0x1:
309 switch (op2) {
310 case 0x0:
311 return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
312 case 0x1:
313 return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
314 case 0x2:
315 return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
316 case 0x3:
317 return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
318 case 0x4:
319 return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
320 case 0x7:
321 return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
322 }
323 break;
324 case 0x2:
325 switch (op2) {
326 case 0x0:
327 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
328 case 0x1:
329 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
330 case 0x2:
331 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
332 case 0x3:
333 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
334 case 0x4:
335 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
336 case 0x7:
337 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
338 }
339 break;
340 case 0x3:
341 switch (op2) {
342 case 0x0:
343 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
344 case 0x1:
345 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
346 case 0x2:
347 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
348 case 0x3:
349 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
350 case 0x4:
351 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
352 case 0x7:
353 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
354 }
355 break;
356 }
357 } else {
358 switch (op1) {
359 case 0x1:
360 switch (op2) {
361 case 0x0:
362 return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
363 case 0x1:
364 return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
365 case 0x2:
366 return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
367 case 0x3:
368 return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
369 case 0x4:
370 return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
371 case 0x7:
372 return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
373 }
374 break;
375 case 0x2:
376 switch (op2) {
377 case 0x0:
378 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
379 case 0x1:
380 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
381 case 0x2:
382 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
383 case 0x3:
384 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
385 case 0x4:
386 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
387 case 0x7:
388 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
389 }
390 break;
391 case 0x3:
392 switch (op2) {
393 case 0x0:
394 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
395 case 0x1:
396 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
397 case 0x2:
398 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
399 case 0x3:
400 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
401 case 0x4:
402 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
403 case 0x7:
404 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
405 }
406 break;
407 }
408 }
409 return new Unknown(machInst);
410 }
411 '''
412}};
413
414def format ArmDataProcImm() {{
415 pclr = '''
416 return new %(className)ssImmPclr(machInst, %(dest)s,
417 %(op1)s, imm, false);
418 '''
419 adr = '''
420 return new AdrImm(machInst, %(dest)s, %(add)s,
421 imm, false);
422 '''
423 instDecode = '''
424 case %(opcode)#x:
425 if (setCc) {
426 if (%(pclrInst)s && %(dest)s == INTREG_PC) {
427 %(pclr)s
428 } else {
429 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
430 imm, rotC);
431 }
432 } else {
433 if (%(adrInst)s && %(op1)s == INTREG_PC) {
434 %(adr)s
435 } else {
436 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
437 imm, rotC);
438 }
439 }
440 break;
441 '''
442
443 def instCode(opcode, mnem, useDest = True, useOp1 = True):
444 global instDecode, pclr, adr
445 if useDest:
446 dest = "rd"
447 else:
448 dest = "INTREG_ZERO"
449 if useOp1:
450 op1 = "rn"
451 else:
452 op1 = "INTREG_ZERO"
453 substDict = { "className": mnem.capitalize(),
454 "opcode": opcode,
455 "dest": dest,
456 "op1": op1,
457 "adr": "",
458 "adrInst": "false" }
459 if useDest:
460 substDict["pclrInst"] = "true"
461 substDict["pclr"] = pclr % substDict
462 else:
463 substDict["pclrInst"] = "false"
464 substDict["pclr"] = ""
465 return instDecode % substDict
466
467 def adrCode(opcode, mnem, add="1"):
468 global instDecode, pclr, adr
469 substDict = { "className": mnem.capitalize(),
470 "opcode": opcode,
471 "dest": "rd",
472 "op1": "rn",
473 "add": add,
474 "pclrInst": "true",
475 "adrInst": "true" }
476 substDict["pclr"] = pclr % substDict
477 substDict["adr"] = adr % substDict
478 return instDecode % substDict
479
480 decode_block = '''
481 {
482 const bool setCc = (bits(machInst, 20) == 1);
483 const uint32_t unrotated = bits(machInst, 7, 0);
484 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
485 const bool rotC = (rotation != 0);
486 const uint32_t imm = rotate_imm(unrotated, rotation);
487 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
488 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
489 switch (OPCODE) {
490 '''
491 decode_block += instCode(0x0, "and")
492 decode_block += instCode(0x1, "eor")
493 decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
494 decode_block += instCode(0x3, "rsb")
495 decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
496 decode_block += instCode(0x5, "adc")
497 decode_block += instCode(0x6, "sbc")
498 decode_block += instCode(0x7, "rsc")
499 decode_block += instCode(0x8, "tst", useDest = False)
500 decode_block += instCode(0x9, "teq", useDest = False)
501 decode_block += instCode(0xa, "cmp", useDest = False)
502 decode_block += instCode(0xb, "cmn", useDest = False)
503 decode_block += instCode(0xc, "orr")
504 decode_block += instCode(0xd, "mov", useOp1 = False)
505 decode_block += instCode(0xe, "bic")
506 decode_block += instCode(0xf, "mvn", useOp1 = False)
507 decode_block += '''
508 default:
509 return new Unknown(machInst);
510 }
511 }
512 '''
513}};
514
515def format ArmSatAddSub() {{
516 decode_block = '''
517 {
518 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
519 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
520 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
521 switch (OPCODE) {
522 case 0x8:
523 return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
524 case 0x9:
525 return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
526 case 0xa:
527 return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
528 case 0xb:
529 return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
530 default:
531 return new Unknown(machInst);
532 }
533 }
534 '''
535}};
536
537def format Thumb32DataProcReg() {{
538 decode_block = '''
539 {
540 const uint32_t op1 = bits(machInst, 23, 20);
541 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
542 const uint32_t op2 = bits(machInst, 7, 4);
543 if (bits(op1, 3) != 1) {
544 if (op2 == 0) {
545 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
546 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
547 switch (bits(op1, 2, 0)) {
548 case 0x0:
549 return new MovRegReg(machInst, rd,
550 INTREG_ZERO, rn, rm, LSL);
551 case 0x1:
552 return new MovRegRegCc(machInst, rd,
553 INTREG_ZERO, rn, rm, LSL);
554 case 0x2:
555 return new MovRegReg(machInst, rd,
556 INTREG_ZERO, rn, rm, LSR);
557 case 0x3:
558 return new MovRegRegCc(machInst, rd,
559 INTREG_ZERO, rn, rm, LSR);
560 case 0x4:
561 return new MovRegReg(machInst, rd,
562 INTREG_ZERO, rn, rm, ASR);
563 case 0x5:
564 return new MovRegRegCc(machInst, rd,
565 INTREG_ZERO, rn, rm, ASR);
566 case 0x6:
567 return new MovRegReg(machInst, rd,
568 INTREG_ZERO, rn, rm, ROR);
569 case 0x7:
570 return new MovRegRegCc(machInst, rd,
571 INTREG_ZERO, rn, rm, ROR);
572 }
573 }
574 {
575 const IntRegIndex rd =
576 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
577 const IntRegIndex rm =
578 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
579 const uint32_t rotation =
580 (uint32_t)bits(machInst, 5, 4) << 3;
581 switch (bits(op1, 2, 0)) {
582 case 0x0:
583 if (rn == 0xf) {
584 return new Sxth(machInst, rd, rotation, rm);
585 } else {
586 return new Sxtah(machInst, rd, rn, rm, rotation);
587 }
588 case 0x1:
589 if (rn == 0xf) {
590 return new Uxth(machInst, rd, rotation, rm);
591 } else {
592 return new Uxtah(machInst, rd, rn, rm, rotation);
593 }
594 case 0x2:
595 if (rn == 0xf) {
596 return new Sxtb16(machInst, rd, rotation, rm);
597 } else {
598 return new Sxtab16(machInst, rd, rn, rm, rotation);
599 }
600 case 0x3:
601 if (rn == 0xf) {
602 return new Uxtb16(machInst, rd, rotation, rm);
603 } else {
604 return new Uxtab16(machInst, rd, rn, rm, rotation);
605 }
606 case 0x4:
607 if (rn == 0xf) {
608 return new Sxtb(machInst, rd, rotation, rm);
609 } else {
610 return new Sxtab(machInst, rd, rn, rm, rotation);
611 }
612 case 0x5:
613 if (rn == 0xf) {
614 return new Uxtb(machInst, rd, rotation, rm);
615 } else {
616 return new Uxtab(machInst, rd, rn, rm, rotation);
617 }
618 default:
619 return new Unknown(machInst);
620 }
621 }
622 } else {
623 if (bits(op2, 3) == 0) {
624 const IntRegIndex rd =
625 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
626 const IntRegIndex rm =
627 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
628 if (bits(op2, 2) == 0x0) {
629 const uint32_t op1 = bits(machInst, 22, 20);
630 const uint32_t op2 = bits(machInst, 5, 4);
631 switch (op2) {
632 case 0x0:
633 switch (op1) {
634 case 0x1:
635 return new Sadd16RegCc(machInst, rd,
636 rn, rm, 0, LSL);
637 case 0x2:
638 return new SasxRegCc(machInst, rd,
639 rn, rm, 0, LSL);
640 case 0x6:
641 return new SsaxRegCc(machInst, rd,
642 rn, rm, 0, LSL);
643 case 0x5:
644 return new Ssub16RegCc(machInst, rd,
645 rn, rm, 0, LSL);
646 case 0x0:
647 return new Sadd8RegCc(machInst, rd,
648 rn, rm, 0, LSL);
649 case 0x4:
650 return new Ssub8RegCc(machInst, rd,
651 rn, rm, 0, LSL);
652 }
653 break;
654 case 0x1:
655 switch (op1) {
656 case 0x1:
657 return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
658 case 0x2:
659 return new QasxReg(machInst, rd, rn, rm, 0, LSL);
660 case 0x6:
661 return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
662 case 0x5:
663 return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
664 case 0x0:
665 return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
666 case 0x4:
667 return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
668 }
669 break;
670 case 0x2:
671 switch (op1) {
672 case 0x1:
673 return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
674 case 0x2:
675 return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
676 case 0x6:
677 return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
678 case 0x5:
679 return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
680 case 0x0:
681 return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
682 case 0x4:
683 return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
684 }
685 break;
686 }
687 } else {
688 const uint32_t op1 = bits(machInst, 22, 20);
689 const uint32_t op2 = bits(machInst, 5, 4);
690 switch (op2) {
691 case 0x0:
692 switch (op1) {
693 case 0x1:
694 return new Uadd16RegCc(machInst, rd,
695 rn, rm, 0, LSL);
696 case 0x2:
697 return new UasxRegCc(machInst, rd,
698 rn, rm, 0, LSL);
699 case 0x6:
700 return new UsaxRegCc(machInst, rd,
701 rn, rm, 0, LSL);
702 case 0x5:
703 return new Usub16RegCc(machInst, rd,
704 rn, rm, 0, LSL);
705 case 0x0:
706 return new Uadd8RegCc(machInst, rd,
707 rn, rm, 0, LSL);
708 case 0x4:
709 return new Usub8RegCc(machInst, rd,
710 rn, rm, 0, LSL);
711 }
712 break;
713 case 0x1:
714 switch (op1) {
715 case 0x1:
716 return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
717 case 0x2:
718 return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
719 case 0x6:
720 return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
721 case 0x5:
722 return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
723 case 0x0:
724 return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
725 case 0x4:
726 return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
727 }
728 break;
729 case 0x2:
730 switch (op1) {
731 case 0x1:
732 return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
733 case 0x2:
734 return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
735 case 0x6:
736 return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
737 case 0x5:
738 return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
739 case 0x0:
740 return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
741 case 0x4:
742 return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
743 }
744 break;
745 }
746 }
747 } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
748 const uint32_t op1 = bits(machInst, 21, 20);
749 const uint32_t op2 = bits(machInst, 5, 4);
750 const IntRegIndex rd =
751 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
752 const IntRegIndex rm =
753 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
748 switch (op1) {
749 case 0x0:
754 switch (op1) {
755 case 0x0:
750 {
751 IntRegIndex rd =
752 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
753 IntRegIndex rm =
754 (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
755 switch (op2) {
756 case 0x0:
757 return new QaddRegCc(machInst, rd,
758 rm, rn, 0, LSL);
759 case 0x1:
760 return new QdaddRegCc(machInst, rd,
761 rm, rn, 0, LSL);
762 case 0x2:
763 return new QsubRegCc(machInst, rd,
764 rm, rn, 0, LSL);
765 case 0x3:
766 return new QdsubRegCc(machInst, rd,
767 rm, rn, 0, LSL);
768 }
756 switch (op2) {
757 case 0x0:
758 return new QaddRegCc(machInst, rd,
759 rm, rn, 0, LSL);
760 case 0x1:
761 return new QdaddRegCc(machInst, rd,
762 rm, rn, 0, LSL);
763 case 0x2:
764 return new QsubRegCc(machInst, rd,
765 rm, rn, 0, LSL);
766 case 0x3:
767 return new QdsubRegCc(machInst, rd,
768 rm, rn, 0, LSL);
769 }
770 break;
771 case 0x1:
769 }
770 break;
771 case 0x1:
772 {
773 IntRegIndex rd =
774 (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
775 IntRegIndex rm = rn;
776 switch (op2) {
777 case 0x0:
778 return new Rev(machInst, rd, rm);
779 case 0x1:
780 return new Rev16(machInst, rd, rm);
781 case 0x2:
782 return new WarnUnimplemented("rbit", machInst);
783 case 0x3:
784 return new Revsh(machInst, rd, rm);
785 }
772 switch (op2) {
773 case 0x0:
774 return new Rev(machInst, rd, rn);
775 case 0x1:
776 return new Rev16(machInst, rd, rn);
777 case 0x2:
778 return new WarnUnimplemented("rbit", machInst);
779 case 0x3:
780 return new Revsh(machInst, rd, rn);
786 }
787 break;
788 case 0x2:
789 if (op2 == 0) {
781 }
782 break;
783 case 0x2:
784 if (op2 == 0) {
790 return new WarnUnimplemented("sel", machInst);
785 return new Sel(machInst, rd, rn, rm);
791 }
792 break;
793 case 0x3:
794 if (op2 == 0) {
795 return new WarnUnimplemented("clz", machInst);
796 }
797 }
798 }
799 return new Unknown(machInst);
800 }
801 }
802 '''
803}};
804
805def format Thumb16ShiftAddSubMoveCmp() {{
806 decode_block = '''
807 {
808 const uint32_t imm5 = bits(machInst, 10, 6);
809 const uint32_t imm3 = bits(machInst, 8, 6);
810 const uint32_t imm8 = bits(machInst, 7, 0);
811 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
812 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
813 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
814 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
815 switch (bits(machInst, 13, 11)) {
816 case 0x0: // lsl
817 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
818 case 0x1: // lsr
819 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
820 case 0x2: // asr
821 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
822 case 0x3:
823 switch (bits(machInst, 10, 9)) {
824 case 0x0:
825 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
826 case 0x1:
827 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
828 case 0x2:
829 return new AddImmCc(machInst, rd, rn, imm3, true);
830 case 0x3:
831 return new SubImmCc(machInst, rd, rn, imm3, true);
832 }
833 case 0x4:
834 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
835 case 0x5:
836 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
837 case 0x6:
838 return new AddImmCc(machInst, rd8, rd8, imm8, true);
839 case 0x7:
840 return new SubImmCc(machInst, rd8, rd8, imm8, true);
841 }
842 }
843 '''
844}};
845
846def format Thumb16DataProcessing() {{
847 decode_block = '''
848 {
849 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
850 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
851 switch (bits(machInst, 9, 6)) {
852 case 0x0:
853 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
854 case 0x1:
855 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
856 case 0x2: //lsl
857 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
858 case 0x3: //lsr
859 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
860 case 0x4: //asr
861 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
862 case 0x5:
863 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
864 case 0x6:
865 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
866 case 0x7: // ror
867 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
868 case 0x8:
869 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
870 case 0x9:
871 return new RsbImmCc(machInst, rdn, rm, 0, true);
872 case 0xa:
873 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
874 case 0xb:
875 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
876 case 0xc:
877 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
878 case 0xd:
879 return new MulCc(machInst, rdn, rm, rdn);
880 case 0xe:
881 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
882 case 0xf:
883 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
884 }
885 }
886 '''
887}};
888
889def format Thumb16SpecDataAndBx() {{
890 decode_block = '''
891 {
892 const IntRegIndex rdn =
893 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
894 (bits(machInst, 7) << 3));
895 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
896 switch (bits(machInst, 9, 8)) {
897 case 0x0:
898 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
899 case 0x1:
900 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
901 case 0x2:
902 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
903 case 0x3:
904 if (bits(machInst, 7) == 0) {
905 return new BxReg(machInst,
906 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
907 COND_UC);
908 } else {
909 return new BlxReg(machInst,
910 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
911 COND_UC);
912 }
913 }
914 }
915 '''
916}};
917
918def format Thumb16Adr() {{
919 decode_block = '''
920 {
921 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
922 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
923 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
924 }
925 '''
926}};
927
928def format Thumb16AddSp() {{
929 decode_block = '''
930 {
931 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
932 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
933 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
934 }
935 '''
936}};
937
938def format Thumb16Misc() {{
939 decode_block = '''
940 {
941 switch (bits(machInst, 11, 8)) {
942 case 0x0:
943 if (bits(machInst, 7)) {
944 return new SubImm(machInst, INTREG_SP, INTREG_SP,
945 bits(machInst, 6, 0) << 2, true);
946 } else {
947 return new AddImm(machInst, INTREG_SP, INTREG_SP,
948 bits(machInst, 6, 0) << 2, true);
949 }
950 case 0x1:
951 return new Cbz(machInst,
952 (bits(machInst, 9) << 6) |
953 (bits(machInst, 7, 3) << 1),
954 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
955 case 0x2:
956 {
957 const IntRegIndex rd =
958 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
959 const IntRegIndex rm =
960 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
961 switch (bits(machInst, 7, 6)) {
962 case 0x0:
963 return new Sxth(machInst, rd, 0, rm);
964 case 0x1:
965 return new Sxtb(machInst, rd, 0, rm);
966 case 0x2:
967 return new Uxth(machInst, rd, 0, rm);
968 case 0x3:
969 return new Uxtb(machInst, rd, 0, rm);
970 }
971 }
972 case 0x3:
973 return new Cbz(machInst,
974 (bits(machInst, 9) << 6) |
975 (bits(machInst, 7, 3) << 1),
976 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
977 case 0x4:
978 case 0x5:
979 {
980 const uint32_t m = bits(machInst, 8);
981 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
982 return new LdmStm(machInst, INTREG_SP, false, false, false,
983 true, false, regList);
984 }
985 case 0x6:
986 {
987 const uint32_t opBits = bits(machInst, 7, 5);
988 if (opBits == 2) {
989 return new WarnUnimplemented("setend", machInst);
990 } else if (opBits == 3) {
991 return new WarnUnimplemented("cps", machInst);
992 }
993 }
994 case 0x9:
995 return new Cbnz(machInst,
996 (bits(machInst, 9) << 6) |
997 (bits(machInst, 7, 3) << 1),
998 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
999 case 0xa:
1000 {
1001 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1002 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1003 switch (bits(machInst, 7, 6)) {
1004 case 0x0:
1005 return new Rev(machInst, rd, rm);
1006 case 0x1:
1007 return new Rev16(machInst, rd, rm);
1008 case 0x3:
1009 return new Revsh(machInst, rd, rm);
1010 default:
1011 break;
1012 }
1013 }
1014 break;
1015 case 0xb:
1016 return new Cbnz(machInst,
1017 (bits(machInst, 9) << 6) |
1018 (bits(machInst, 7, 3) << 1),
1019 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1020 case 0xc:
1021 case 0xd:
1022 {
1023 const uint32_t p = bits(machInst, 8);
1024 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1025 return new LdmStm(machInst, INTREG_SP, true, true, false,
1026 true, true, regList);
1027 }
1028 case 0xe:
1029 return new WarnUnimplemented("bkpt", machInst);
1030 case 0xf:
1031 if (bits(machInst, 3, 0) != 0)
1032 return new WarnUnimplemented("it", machInst);
1033 switch (bits(machInst, 7, 4)) {
1034 case 0x0:
1035 return new WarnUnimplemented("nop", machInst);
1036 case 0x1:
1037 return new WarnUnimplemented("yield", machInst);
1038 case 0x2:
1039 return new WarnUnimplemented("wfe", machInst);
1040 case 0x3:
1041 return new WarnUnimplemented("wfi", machInst);
1042 case 0x4:
1043 return new WarnUnimplemented("sev", machInst);
1044 default:
1045 return new WarnUnimplemented("unallocated_hint", machInst);
1046 }
1047 default:
1048 break;
1049 }
1050 return new Unknown(machInst);
1051 }
1052 '''
1053}};
1054
1055def format Thumb32DataProcModImm() {{
1056
1057 def decInst(mnem, dest="rd", op1="rn"):
1058 return '''
1059 if (s) {
1060 return new %(mnem)sImmCc(machInst, %(dest)s,
1061 %(op1)s, imm, rotC);
1062 } else {
1063 return new %(mnem)sImm(machInst, %(dest)s,
1064 %(op1)s, imm, rotC);
1065 }
1066 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1067
1068 decode_block = '''
1069 {
1070 const uint32_t op = bits(machInst, 24, 21);
1071 const bool s = (bits(machInst, 20) == 1);
1072 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1073 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1074 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1075 bits(machInst, 14, 12);
1076 const bool rotC = ctrlImm > 3;
1077 const uint32_t dataImm = bits(machInst, 7, 0);
1078 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1079 switch (op) {
1080 case 0x0:
1081 if (rd == INTREG_PC) {
1082 %(tst)s
1083 } else {
1084 %(and)s
1085 }
1086 case 0x1:
1087 %(bic)s
1088 case 0x2:
1089 if (rn == INTREG_PC) {
1090 %(mov)s
1091 } else {
1092 %(orr)s
1093 }
1094 case 0x3:
1095 if (rn == INTREG_PC) {
1096 %(mvn)s
1097 } else {
1098 %(orn)s
1099 }
1100 case 0x4:
1101 if (rd == INTREG_PC) {
1102 %(teq)s
1103 } else {
1104 %(eor)s
1105 }
1106 case 0x8:
1107 if (rd == INTREG_PC) {
1108 %(cmn)s
1109 } else {
1110 %(add)s
1111 }
1112 case 0xa:
1113 %(adc)s
1114 case 0xb:
1115 %(sbc)s
1116 case 0xd:
1117 if (rd == INTREG_PC) {
1118 %(cmp)s
1119 } else {
1120 %(sub)s
1121 }
1122 case 0xe:
1123 %(rsb)s
1124 default:
1125 return new Unknown(machInst);
1126 }
1127 }
1128 ''' % {
1129 "tst" : decInst("Tst", "INTREG_ZERO"),
1130 "and" : decInst("And"),
1131 "bic" : decInst("Bic"),
1132 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1133 "orr" : decInst("Orr"),
1134 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1135 "orn" : decInst("Orn"),
1136 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1137 "eor" : decInst("Eor"),
1138 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1139 "add" : decInst("Add"),
1140 "adc" : decInst("Adc"),
1141 "sbc" : decInst("Sbc"),
1142 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1143 "sub" : decInst("Sub"),
1144 "rsb" : decInst("Rsb")
1145 }
1146}};
1147
1148def format Thumb32DataProcPlainBin() {{
1149 decode_block = '''
1150 {
1151 const uint32_t op = bits(machInst, 24, 20);
1152 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1153 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1154 switch (op) {
1155 case 0x0:
1156 {
1157 const uint32_t imm = bits(machInst, 7, 0) |
1158 (bits(machInst, 14, 12) << 8) |
1159 (bits(machInst, 26) << 11);
1160 if (rn == 0xf) {
1161 return new AdrImm(machInst, rd, (IntRegIndex)1,
1162 imm, false);
1163 } else {
1164 return new AddImm(machInst, rd, rn, imm, true);
1165 }
1166 }
1167 case 0x4:
1168 {
1169 const uint32_t imm = bits(machInst, 7, 0) |
1170 (bits(machInst, 14, 12) << 8) |
1171 (bits(machInst, 26) << 11) |
1172 (bits(machInst, 19, 16) << 12);
1173 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1174 }
1175 case 0xa:
1176 {
1177 const uint32_t imm = bits(machInst, 7, 0) |
1178 (bits(machInst, 14, 12) << 8) |
1179 (bits(machInst, 26) << 11);
1180 if (rn == 0xf) {
1181 return new AdrImm(machInst, rd, (IntRegIndex)0,
1182 imm, false);
1183 } else {
1184 return new SubImm(machInst, rd, rn, imm, true);
1185 }
1186 }
1187 case 0xc:
1188 {
1189 const uint32_t imm = bits(machInst, 7, 0) |
1190 (bits(machInst, 14, 12) << 8) |
1191 (bits(machInst, 26) << 11) |
1192 (bits(machInst, 19, 16) << 12);
1193 return new MovtImm(machInst, rd, rd, imm, true);
1194 }
1195 case 0x12:
1196 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1197 const uint32_t satImm = bits(machInst, 4, 0);
1198 return new Ssat16(machInst, rd, satImm + 1, rn);
1199 }
1200 // Fall through on purpose...
1201 case 0x10:
1202 {
1203 const uint32_t satImm = bits(machInst, 4, 0);
1204 const uint32_t imm = bits(machInst, 7, 6) |
1205 (bits(machInst, 14, 12) << 2);
1206 const ArmShiftType type =
1207 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1208 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1209 }
1210 case 0x14:
1211 return new WarnUnimplemented("sbfx", machInst);
1212 case 0x16:
1213 if (rn == 0xf) {
1214 return new WarnUnimplemented("bfc", machInst);
1215 } else {
1216 return new WarnUnimplemented("bfi", machInst);
1217 }
1218 case 0x1a:
1219 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1220 const uint32_t satImm = bits(machInst, 4, 0);
1221 return new Usat16(machInst, rd, satImm, rn);
1222 }
1223 // Fall through on purpose...
1224 case 0x18:
1225 {
1226 const uint32_t satImm = bits(machInst, 4, 0);
1227 const uint32_t imm = bits(machInst, 7, 6) |
1228 (bits(machInst, 14, 12) << 2);
1229 const ArmShiftType type =
1230 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1231 return new Usat(machInst, rd, satImm, rn, imm, type);
1232 }
1233 case 0x1c:
1234 return new WarnUnimplemented("ubfx", machInst);
1235 default:
1236 return new Unknown(machInst);
1237 }
1238 }
1239 '''
1240}};
1241
1242def format Thumb32DataProcShiftReg() {{
1243
1244 def decInst(mnem, dest="rd", op1="rn"):
1245 return '''
1246 if (s) {
1247 return new %(mnem)sRegCc(machInst, %(dest)s,
1248 %(op1)s, rm, amt, type);
1249 } else {
1250 return new %(mnem)sReg(machInst, %(dest)s,
1251 %(op1)s, rm, amt, type);
1252 }
1253 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1254
1255 decode_block = '''
1256 {
1257 const uint32_t op = bits(machInst, 24, 21);
1258 const bool s = (bits(machInst, 20) == 1);
1259 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1260 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1261 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1262 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1263 bits(machInst, 7, 6);
1264 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1265 switch (op) {
1266 case 0x0:
1267 if (rd == INTREG_PC) {
1268 %(tst)s
1269 } else {
1270 %(and)s
1271 }
1272 case 0x1:
1273 %(bic)s
1274 case 0x2:
1275 if (rn == INTREG_PC) {
1276 %(mov)s
1277 } else {
1278 %(orr)s
1279 }
1280 case 0x3:
1281 if (rn == INTREG_PC) {
1282 %(mvn)s
1283 } else {
1284 %(orn)s
1285 }
1286 case 0x4:
1287 if (rd == INTREG_PC) {
1288 %(teq)s
1289 } else {
1290 %(eor)s
1291 }
1292 case 0x6:
1293 if (type) {
1294 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1295 } else {
1296 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1297 }
1298 case 0x8:
1299 if (rd == INTREG_PC) {
1300 %(cmn)s
1301 } else {
1302 %(add)s
1303 }
1304 case 0xa:
1305 %(adc)s
1306 case 0xb:
1307 %(sbc)s
1308 case 0xd:
1309 if (rd == INTREG_PC) {
1310 %(cmp)s
1311 } else {
1312 %(sub)s
1313 }
1314 case 0xe:
1315 %(rsb)s
1316 default:
1317 return new Unknown(machInst);
1318 }
1319 }
1320 ''' % {
1321 "tst" : decInst("Tst", "INTREG_ZERO"),
1322 "and" : decInst("And"),
1323 "bic" : decInst("Bic"),
1324 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1325 "orr" : decInst("Orr"),
1326 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1327 "orn" : decInst("Orn"),
1328 "teq" : decInst("Teq", "INTREG_ZERO"),
1329 "eor" : decInst("Eor"),
1330 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1331 "add" : decInst("Add"),
1332 "adc" : decInst("Adc"),
1333 "sbc" : decInst("Sbc"),
1334 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1335 "sub" : decInst("Sub"),
1336 "rsb" : decInst("Rsb")
1337 }
1338}};
786 }
787 break;
788 case 0x3:
789 if (op2 == 0) {
790 return new WarnUnimplemented("clz", machInst);
791 }
792 }
793 }
794 return new Unknown(machInst);
795 }
796 }
797 '''
798}};
799
800def format Thumb16ShiftAddSubMoveCmp() {{
801 decode_block = '''
802 {
803 const uint32_t imm5 = bits(machInst, 10, 6);
804 const uint32_t imm3 = bits(machInst, 8, 6);
805 const uint32_t imm8 = bits(machInst, 7, 0);
806 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
807 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
808 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
809 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
810 switch (bits(machInst, 13, 11)) {
811 case 0x0: // lsl
812 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
813 case 0x1: // lsr
814 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
815 case 0x2: // asr
816 return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
817 case 0x3:
818 switch (bits(machInst, 10, 9)) {
819 case 0x0:
820 return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
821 case 0x1:
822 return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
823 case 0x2:
824 return new AddImmCc(machInst, rd, rn, imm3, true);
825 case 0x3:
826 return new SubImmCc(machInst, rd, rn, imm3, true);
827 }
828 case 0x4:
829 return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
830 case 0x5:
831 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
832 case 0x6:
833 return new AddImmCc(machInst, rd8, rd8, imm8, true);
834 case 0x7:
835 return new SubImmCc(machInst, rd8, rd8, imm8, true);
836 }
837 }
838 '''
839}};
840
841def format Thumb16DataProcessing() {{
842 decode_block = '''
843 {
844 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
845 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
846 switch (bits(machInst, 9, 6)) {
847 case 0x0:
848 return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
849 case 0x1:
850 return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
851 case 0x2: //lsl
852 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
853 case 0x3: //lsr
854 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
855 case 0x4: //asr
856 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
857 case 0x5:
858 return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
859 case 0x6:
860 return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
861 case 0x7: // ror
862 return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
863 case 0x8:
864 return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
865 case 0x9:
866 return new RsbImmCc(machInst, rdn, rm, 0, true);
867 case 0xa:
868 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
869 case 0xb:
870 return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
871 case 0xc:
872 return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
873 case 0xd:
874 return new MulCc(machInst, rdn, rm, rdn);
875 case 0xe:
876 return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
877 case 0xf:
878 return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
879 }
880 }
881 '''
882}};
883
884def format Thumb16SpecDataAndBx() {{
885 decode_block = '''
886 {
887 const IntRegIndex rdn =
888 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
889 (bits(machInst, 7) << 3));
890 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
891 switch (bits(machInst, 9, 8)) {
892 case 0x0:
893 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
894 case 0x1:
895 return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
896 case 0x2:
897 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
898 case 0x3:
899 if (bits(machInst, 7) == 0) {
900 return new BxReg(machInst,
901 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
902 COND_UC);
903 } else {
904 return new BlxReg(machInst,
905 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
906 COND_UC);
907 }
908 }
909 }
910 '''
911}};
912
913def format Thumb16Adr() {{
914 decode_block = '''
915 {
916 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
917 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
918 return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
919 }
920 '''
921}};
922
923def format Thumb16AddSp() {{
924 decode_block = '''
925 {
926 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
927 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
928 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
929 }
930 '''
931}};
932
933def format Thumb16Misc() {{
934 decode_block = '''
935 {
936 switch (bits(machInst, 11, 8)) {
937 case 0x0:
938 if (bits(machInst, 7)) {
939 return new SubImm(machInst, INTREG_SP, INTREG_SP,
940 bits(machInst, 6, 0) << 2, true);
941 } else {
942 return new AddImm(machInst, INTREG_SP, INTREG_SP,
943 bits(machInst, 6, 0) << 2, true);
944 }
945 case 0x1:
946 return new Cbz(machInst,
947 (bits(machInst, 9) << 6) |
948 (bits(machInst, 7, 3) << 1),
949 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
950 case 0x2:
951 {
952 const IntRegIndex rd =
953 (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
954 const IntRegIndex rm =
955 (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
956 switch (bits(machInst, 7, 6)) {
957 case 0x0:
958 return new Sxth(machInst, rd, 0, rm);
959 case 0x1:
960 return new Sxtb(machInst, rd, 0, rm);
961 case 0x2:
962 return new Uxth(machInst, rd, 0, rm);
963 case 0x3:
964 return new Uxtb(machInst, rd, 0, rm);
965 }
966 }
967 case 0x3:
968 return new Cbz(machInst,
969 (bits(machInst, 9) << 6) |
970 (bits(machInst, 7, 3) << 1),
971 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
972 case 0x4:
973 case 0x5:
974 {
975 const uint32_t m = bits(machInst, 8);
976 const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
977 return new LdmStm(machInst, INTREG_SP, false, false, false,
978 true, false, regList);
979 }
980 case 0x6:
981 {
982 const uint32_t opBits = bits(machInst, 7, 5);
983 if (opBits == 2) {
984 return new WarnUnimplemented("setend", machInst);
985 } else if (opBits == 3) {
986 return new WarnUnimplemented("cps", machInst);
987 }
988 }
989 case 0x9:
990 return new Cbnz(machInst,
991 (bits(machInst, 9) << 6) |
992 (bits(machInst, 7, 3) << 1),
993 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
994 case 0xa:
995 {
996 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
997 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
998 switch (bits(machInst, 7, 6)) {
999 case 0x0:
1000 return new Rev(machInst, rd, rm);
1001 case 0x1:
1002 return new Rev16(machInst, rd, rm);
1003 case 0x3:
1004 return new Revsh(machInst, rd, rm);
1005 default:
1006 break;
1007 }
1008 }
1009 break;
1010 case 0xb:
1011 return new Cbnz(machInst,
1012 (bits(machInst, 9) << 6) |
1013 (bits(machInst, 7, 3) << 1),
1014 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1015 case 0xc:
1016 case 0xd:
1017 {
1018 const uint32_t p = bits(machInst, 8);
1019 const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1020 return new LdmStm(machInst, INTREG_SP, true, true, false,
1021 true, true, regList);
1022 }
1023 case 0xe:
1024 return new WarnUnimplemented("bkpt", machInst);
1025 case 0xf:
1026 if (bits(machInst, 3, 0) != 0)
1027 return new WarnUnimplemented("it", machInst);
1028 switch (bits(machInst, 7, 4)) {
1029 case 0x0:
1030 return new WarnUnimplemented("nop", machInst);
1031 case 0x1:
1032 return new WarnUnimplemented("yield", machInst);
1033 case 0x2:
1034 return new WarnUnimplemented("wfe", machInst);
1035 case 0x3:
1036 return new WarnUnimplemented("wfi", machInst);
1037 case 0x4:
1038 return new WarnUnimplemented("sev", machInst);
1039 default:
1040 return new WarnUnimplemented("unallocated_hint", machInst);
1041 }
1042 default:
1043 break;
1044 }
1045 return new Unknown(machInst);
1046 }
1047 '''
1048}};
1049
1050def format Thumb32DataProcModImm() {{
1051
1052 def decInst(mnem, dest="rd", op1="rn"):
1053 return '''
1054 if (s) {
1055 return new %(mnem)sImmCc(machInst, %(dest)s,
1056 %(op1)s, imm, rotC);
1057 } else {
1058 return new %(mnem)sImm(machInst, %(dest)s,
1059 %(op1)s, imm, rotC);
1060 }
1061 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1062
1063 decode_block = '''
1064 {
1065 const uint32_t op = bits(machInst, 24, 21);
1066 const bool s = (bits(machInst, 20) == 1);
1067 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1068 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1069 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1070 bits(machInst, 14, 12);
1071 const bool rotC = ctrlImm > 3;
1072 const uint32_t dataImm = bits(machInst, 7, 0);
1073 const uint32_t imm = modified_imm(ctrlImm, dataImm);
1074 switch (op) {
1075 case 0x0:
1076 if (rd == INTREG_PC) {
1077 %(tst)s
1078 } else {
1079 %(and)s
1080 }
1081 case 0x1:
1082 %(bic)s
1083 case 0x2:
1084 if (rn == INTREG_PC) {
1085 %(mov)s
1086 } else {
1087 %(orr)s
1088 }
1089 case 0x3:
1090 if (rn == INTREG_PC) {
1091 %(mvn)s
1092 } else {
1093 %(orn)s
1094 }
1095 case 0x4:
1096 if (rd == INTREG_PC) {
1097 %(teq)s
1098 } else {
1099 %(eor)s
1100 }
1101 case 0x8:
1102 if (rd == INTREG_PC) {
1103 %(cmn)s
1104 } else {
1105 %(add)s
1106 }
1107 case 0xa:
1108 %(adc)s
1109 case 0xb:
1110 %(sbc)s
1111 case 0xd:
1112 if (rd == INTREG_PC) {
1113 %(cmp)s
1114 } else {
1115 %(sub)s
1116 }
1117 case 0xe:
1118 %(rsb)s
1119 default:
1120 return new Unknown(machInst);
1121 }
1122 }
1123 ''' % {
1124 "tst" : decInst("Tst", "INTREG_ZERO"),
1125 "and" : decInst("And"),
1126 "bic" : decInst("Bic"),
1127 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1128 "orr" : decInst("Orr"),
1129 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1130 "orn" : decInst("Orn"),
1131 "teq" : decInst("Teq", dest="INTREG_ZERO"),
1132 "eor" : decInst("Eor"),
1133 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1134 "add" : decInst("Add"),
1135 "adc" : decInst("Adc"),
1136 "sbc" : decInst("Sbc"),
1137 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1138 "sub" : decInst("Sub"),
1139 "rsb" : decInst("Rsb")
1140 }
1141}};
1142
1143def format Thumb32DataProcPlainBin() {{
1144 decode_block = '''
1145 {
1146 const uint32_t op = bits(machInst, 24, 20);
1147 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1148 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1149 switch (op) {
1150 case 0x0:
1151 {
1152 const uint32_t imm = bits(machInst, 7, 0) |
1153 (bits(machInst, 14, 12) << 8) |
1154 (bits(machInst, 26) << 11);
1155 if (rn == 0xf) {
1156 return new AdrImm(machInst, rd, (IntRegIndex)1,
1157 imm, false);
1158 } else {
1159 return new AddImm(machInst, rd, rn, imm, true);
1160 }
1161 }
1162 case 0x4:
1163 {
1164 const uint32_t imm = bits(machInst, 7, 0) |
1165 (bits(machInst, 14, 12) << 8) |
1166 (bits(machInst, 26) << 11) |
1167 (bits(machInst, 19, 16) << 12);
1168 return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1169 }
1170 case 0xa:
1171 {
1172 const uint32_t imm = bits(machInst, 7, 0) |
1173 (bits(machInst, 14, 12) << 8) |
1174 (bits(machInst, 26) << 11);
1175 if (rn == 0xf) {
1176 return new AdrImm(machInst, rd, (IntRegIndex)0,
1177 imm, false);
1178 } else {
1179 return new SubImm(machInst, rd, rn, imm, true);
1180 }
1181 }
1182 case 0xc:
1183 {
1184 const uint32_t imm = bits(machInst, 7, 0) |
1185 (bits(machInst, 14, 12) << 8) |
1186 (bits(machInst, 26) << 11) |
1187 (bits(machInst, 19, 16) << 12);
1188 return new MovtImm(machInst, rd, rd, imm, true);
1189 }
1190 case 0x12:
1191 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1192 const uint32_t satImm = bits(machInst, 4, 0);
1193 return new Ssat16(machInst, rd, satImm + 1, rn);
1194 }
1195 // Fall through on purpose...
1196 case 0x10:
1197 {
1198 const uint32_t satImm = bits(machInst, 4, 0);
1199 const uint32_t imm = bits(machInst, 7, 6) |
1200 (bits(machInst, 14, 12) << 2);
1201 const ArmShiftType type =
1202 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1203 return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1204 }
1205 case 0x14:
1206 return new WarnUnimplemented("sbfx", machInst);
1207 case 0x16:
1208 if (rn == 0xf) {
1209 return new WarnUnimplemented("bfc", machInst);
1210 } else {
1211 return new WarnUnimplemented("bfi", machInst);
1212 }
1213 case 0x1a:
1214 if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1215 const uint32_t satImm = bits(machInst, 4, 0);
1216 return new Usat16(machInst, rd, satImm, rn);
1217 }
1218 // Fall through on purpose...
1219 case 0x18:
1220 {
1221 const uint32_t satImm = bits(machInst, 4, 0);
1222 const uint32_t imm = bits(machInst, 7, 6) |
1223 (bits(machInst, 14, 12) << 2);
1224 const ArmShiftType type =
1225 (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1226 return new Usat(machInst, rd, satImm, rn, imm, type);
1227 }
1228 case 0x1c:
1229 return new WarnUnimplemented("ubfx", machInst);
1230 default:
1231 return new Unknown(machInst);
1232 }
1233 }
1234 '''
1235}};
1236
1237def format Thumb32DataProcShiftReg() {{
1238
1239 def decInst(mnem, dest="rd", op1="rn"):
1240 return '''
1241 if (s) {
1242 return new %(mnem)sRegCc(machInst, %(dest)s,
1243 %(op1)s, rm, amt, type);
1244 } else {
1245 return new %(mnem)sReg(machInst, %(dest)s,
1246 %(op1)s, rm, amt, type);
1247 }
1248 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1249
1250 decode_block = '''
1251 {
1252 const uint32_t op = bits(machInst, 24, 21);
1253 const bool s = (bits(machInst, 20) == 1);
1254 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1255 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1256 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1257 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1258 bits(machInst, 7, 6);
1259 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1260 switch (op) {
1261 case 0x0:
1262 if (rd == INTREG_PC) {
1263 %(tst)s
1264 } else {
1265 %(and)s
1266 }
1267 case 0x1:
1268 %(bic)s
1269 case 0x2:
1270 if (rn == INTREG_PC) {
1271 %(mov)s
1272 } else {
1273 %(orr)s
1274 }
1275 case 0x3:
1276 if (rn == INTREG_PC) {
1277 %(mvn)s
1278 } else {
1279 %(orn)s
1280 }
1281 case 0x4:
1282 if (rd == INTREG_PC) {
1283 %(teq)s
1284 } else {
1285 %(eor)s
1286 }
1287 case 0x6:
1288 if (type) {
1289 return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1290 } else {
1291 return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1292 }
1293 case 0x8:
1294 if (rd == INTREG_PC) {
1295 %(cmn)s
1296 } else {
1297 %(add)s
1298 }
1299 case 0xa:
1300 %(adc)s
1301 case 0xb:
1302 %(sbc)s
1303 case 0xd:
1304 if (rd == INTREG_PC) {
1305 %(cmp)s
1306 } else {
1307 %(sub)s
1308 }
1309 case 0xe:
1310 %(rsb)s
1311 default:
1312 return new Unknown(machInst);
1313 }
1314 }
1315 ''' % {
1316 "tst" : decInst("Tst", "INTREG_ZERO"),
1317 "and" : decInst("And"),
1318 "bic" : decInst("Bic"),
1319 "mov" : decInst("Mov", op1="INTREG_ZERO"),
1320 "orr" : decInst("Orr"),
1321 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1322 "orn" : decInst("Orn"),
1323 "teq" : decInst("Teq", "INTREG_ZERO"),
1324 "eor" : decInst("Eor"),
1325 "cmn" : decInst("Cmn", "INTREG_ZERO"),
1326 "add" : decInst("Add"),
1327 "adc" : decInst("Adc"),
1328 "sbc" : decInst("Sbc"),
1329 "cmp" : decInst("Cmp", "INTREG_ZERO"),
1330 "sub" : decInst("Sub"),
1331 "rsb" : decInst("Rsb")
1332 }
1333}};