data.isa (7146:f68d5f1f748c) data.isa (7154:1fa6d1db1f32)
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 instDecode = '''
40 case %(opcode)#x:
41 if (immShift) {
42 if (setCc) {
43 return new %(className)sRegCc(machInst, %(dest)s, %(op1)s,
44 rm, imm5, type);
45 } else {
46 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
47 rm, imm5, type);
48 }
49 } else {
50 if (setCc) {
51 return new %(className)sRegRegCc(machInst, %(dest)s,
52 %(op1)s, rm, rs, type);
53 } else {
54 return new %(className)sRegReg(machInst, %(dest)s,
55 %(op1)s, rm, rs, type);
56 }
57 }
58 break;
59 '''
60
61 def instCode(opcode, mnem, dest="rd", op1="rn"):
62 global instDecode
63 return instDecode % { "className": mnem.capitalize(),
64 "opcode": opcode,
65 "dest": dest,
66 "op1": op1 }
67
68 decode_block = '''
69 {
70 const bool immShift = (bits(machInst, 4) == 0);
71 const bool setCc = (bits(machInst, 20) == 1);
72 const uint32_t imm5 = bits(machInst, 11, 7);
73 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
74 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
75 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
76 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
77 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
78 switch (OPCODE) {
79 '''
80 decode_block += instCode(0x0, "and")
81 decode_block += instCode(0x1, "eor")
82 decode_block += instCode(0x2, "sub")
83 decode_block += instCode(0x3, "rsb")
84 decode_block += instCode(0x4, "add")
85 decode_block += instCode(0x5, "adc")
86 decode_block += instCode(0x6, "sbc")
87 decode_block += instCode(0x7, "rsc")
88 decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
89 decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
90 decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
91 decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
92 decode_block += instCode(0xc, "orr")
93 decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
94 decode_block += instCode(0xe, "bic")
95 decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
96 decode_block += '''
97 default:
98 return new Unknown(machInst);
99 }
100 }
101 '''
102}};
103
104def format ArmDataProcImm() {{
105 instDecode = '''
106 case %(opcode)#x:
107 if (setCc) {
108 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
109 imm, rotC);
110 } else {
111 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
112 imm, rotC);
113 }
114 break;
115 '''
116
117 def instCode(opcode, mnem, dest="rd", op1="rn"):
118 global instDecode
119 return instDecode % { "className": mnem.capitalize(),
120 "opcode": opcode,
121 "dest": dest,
122 "op1": op1 }
123
124 decode_block = '''
125 {
126 const bool setCc = (bits(machInst, 20) == 1);
127 const uint32_t unrotated = bits(machInst, 7, 0);
128 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
129 const bool rotC = (rotation != 0);
130 const uint32_t imm = rotate_imm(unrotated, rotation);
131 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
132 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
133 switch (OPCODE) {
134 '''
135 decode_block += instCode(0x0, "and")
136 decode_block += instCode(0x1, "eor")
137 decode_block += instCode(0x2, "sub")
138 decode_block += instCode(0x3, "rsb")
139 decode_block += instCode(0x4, "add")
140 decode_block += instCode(0x5, "adc")
141 decode_block += instCode(0x6, "sbc")
142 decode_block += instCode(0x7, "rsc")
143 decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
144 decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
145 decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
146 decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
147 decode_block += instCode(0xc, "orr")
148 decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
149 decode_block += instCode(0xe, "bic")
150 decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
151 decode_block += '''
152 default:
153 return new Unknown(machInst);
154 }
155 }
156 '''
157}};
158
159def format Thumb16ShiftAddSubMoveCmp() {{
160 decode_block = '''
161 {
162 const uint32_t imm5 = bits(machInst, 10, 6);
163 const uint32_t imm3 = bits(machInst, 8, 6);
164 const uint32_t imm8 = bits(machInst, 7, 0);
165 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
166 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
167 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
168 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
169 switch (bits(machInst, 13, 11)) {
170 case 0x0: // lsl
171 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
172 case 0x1: // lsr
173 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
174 case 0x2: // asr
175 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
176 case 0x3:
177 switch (bits(machInst, 10, 9)) {
178 case 0x0:
179 return new AddReg(machInst, rd, rn, rm, 0, LSL);
180 case 0x1:
181 return new SubReg(machInst, rd, rn, rm, 0, LSL);
182 case 0x2:
183 return new AddImm(machInst, rd, rn, imm3, true);
184 case 0x3:
185 return new SubImm(machInst, rd, rn, imm3, true);
186 }
187 case 0x4:
188 return new MovImm(machInst, rd8, INTREG_ZERO, imm8, true);
189 case 0x5:
190 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
191 case 0x6:
192 return new AddImm(machInst, rd8, rd8, imm8, true);
193 case 0x7:
194 return new SubImm(machInst, rd8, rd8, imm8, true);
195 }
196 }
197 '''
198}};
199
200def format Thumb16DataProcessing() {{
201 decode_block = '''
202 {
203 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
204 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
205 switch (bits(machInst, 9, 6)) {
206 case 0x0:
207 return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
208 case 0x1:
209 return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
210 case 0x2: //lsl
211 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
212 case 0x3: //lsr
213 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
214 case 0x4: //asr
215 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
216 case 0x5:
217 return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
218 case 0x6:
219 return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
220 case 0x7: // ror
221 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
222 case 0x8:
223 return new TstReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
224 case 0x9:
225 return new RsbImm(machInst, rdn, rm, 0, true);
226 case 0xa:
227 return new CmpReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
228 case 0xb:
229 return new CmnReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
230 case 0xc:
231 return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
232 case 0xd:
233 //XXX Implement me!
234 return new WarnUnimplemented("mul", machInst);
235 case 0xe:
236 return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
237 case 0xf:
238 return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
239 }
240 }
241 '''
242}};
243
244def format Thumb16SpecDataAndBx() {{
245 decode_block = '''
246 {
247 const IntRegIndex rdn =
248 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
249 (bits(machInst, 7) << 3));
250 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
251 switch (bits(machInst, 9, 8)) {
252 case 0x0:
253 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
254 case 0x1:
255 return new CmpReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
256 case 0x2:
257 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
258 case 0x3:
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 instDecode = '''
40 case %(opcode)#x:
41 if (immShift) {
42 if (setCc) {
43 return new %(className)sRegCc(machInst, %(dest)s, %(op1)s,
44 rm, imm5, type);
45 } else {
46 return new %(className)sReg(machInst, %(dest)s, %(op1)s,
47 rm, imm5, type);
48 }
49 } else {
50 if (setCc) {
51 return new %(className)sRegRegCc(machInst, %(dest)s,
52 %(op1)s, rm, rs, type);
53 } else {
54 return new %(className)sRegReg(machInst, %(dest)s,
55 %(op1)s, rm, rs, type);
56 }
57 }
58 break;
59 '''
60
61 def instCode(opcode, mnem, dest="rd", op1="rn"):
62 global instDecode
63 return instDecode % { "className": mnem.capitalize(),
64 "opcode": opcode,
65 "dest": dest,
66 "op1": op1 }
67
68 decode_block = '''
69 {
70 const bool immShift = (bits(machInst, 4) == 0);
71 const bool setCc = (bits(machInst, 20) == 1);
72 const uint32_t imm5 = bits(machInst, 11, 7);
73 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
74 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
75 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
76 const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
77 const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
78 switch (OPCODE) {
79 '''
80 decode_block += instCode(0x0, "and")
81 decode_block += instCode(0x1, "eor")
82 decode_block += instCode(0x2, "sub")
83 decode_block += instCode(0x3, "rsb")
84 decode_block += instCode(0x4, "add")
85 decode_block += instCode(0x5, "adc")
86 decode_block += instCode(0x6, "sbc")
87 decode_block += instCode(0x7, "rsc")
88 decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
89 decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
90 decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
91 decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
92 decode_block += instCode(0xc, "orr")
93 decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
94 decode_block += instCode(0xe, "bic")
95 decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
96 decode_block += '''
97 default:
98 return new Unknown(machInst);
99 }
100 }
101 '''
102}};
103
104def format ArmDataProcImm() {{
105 instDecode = '''
106 case %(opcode)#x:
107 if (setCc) {
108 return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
109 imm, rotC);
110 } else {
111 return new %(className)sImm(machInst, %(dest)s, %(op1)s,
112 imm, rotC);
113 }
114 break;
115 '''
116
117 def instCode(opcode, mnem, dest="rd", op1="rn"):
118 global instDecode
119 return instDecode % { "className": mnem.capitalize(),
120 "opcode": opcode,
121 "dest": dest,
122 "op1": op1 }
123
124 decode_block = '''
125 {
126 const bool setCc = (bits(machInst, 20) == 1);
127 const uint32_t unrotated = bits(machInst, 7, 0);
128 const uint32_t rotation = (bits(machInst, 11, 8) << 1);
129 const bool rotC = (rotation != 0);
130 const uint32_t imm = rotate_imm(unrotated, rotation);
131 const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
132 const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
133 switch (OPCODE) {
134 '''
135 decode_block += instCode(0x0, "and")
136 decode_block += instCode(0x1, "eor")
137 decode_block += instCode(0x2, "sub")
138 decode_block += instCode(0x3, "rsb")
139 decode_block += instCode(0x4, "add")
140 decode_block += instCode(0x5, "adc")
141 decode_block += instCode(0x6, "sbc")
142 decode_block += instCode(0x7, "rsc")
143 decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
144 decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
145 decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
146 decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
147 decode_block += instCode(0xc, "orr")
148 decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
149 decode_block += instCode(0xe, "bic")
150 decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
151 decode_block += '''
152 default:
153 return new Unknown(machInst);
154 }
155 }
156 '''
157}};
158
159def format Thumb16ShiftAddSubMoveCmp() {{
160 decode_block = '''
161 {
162 const uint32_t imm5 = bits(machInst, 10, 6);
163 const uint32_t imm3 = bits(machInst, 8, 6);
164 const uint32_t imm8 = bits(machInst, 7, 0);
165 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
166 const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
167 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
168 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
169 switch (bits(machInst, 13, 11)) {
170 case 0x0: // lsl
171 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
172 case 0x1: // lsr
173 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
174 case 0x2: // asr
175 return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
176 case 0x3:
177 switch (bits(machInst, 10, 9)) {
178 case 0x0:
179 return new AddReg(machInst, rd, rn, rm, 0, LSL);
180 case 0x1:
181 return new SubReg(machInst, rd, rn, rm, 0, LSL);
182 case 0x2:
183 return new AddImm(machInst, rd, rn, imm3, true);
184 case 0x3:
185 return new SubImm(machInst, rd, rn, imm3, true);
186 }
187 case 0x4:
188 return new MovImm(machInst, rd8, INTREG_ZERO, imm8, true);
189 case 0x5:
190 return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
191 case 0x6:
192 return new AddImm(machInst, rd8, rd8, imm8, true);
193 case 0x7:
194 return new SubImm(machInst, rd8, rd8, imm8, true);
195 }
196 }
197 '''
198}};
199
200def format Thumb16DataProcessing() {{
201 decode_block = '''
202 {
203 const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
204 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
205 switch (bits(machInst, 9, 6)) {
206 case 0x0:
207 return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
208 case 0x1:
209 return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
210 case 0x2: //lsl
211 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
212 case 0x3: //lsr
213 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
214 case 0x4: //asr
215 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
216 case 0x5:
217 return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
218 case 0x6:
219 return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
220 case 0x7: // ror
221 return new MovRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
222 case 0x8:
223 return new TstReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
224 case 0x9:
225 return new RsbImm(machInst, rdn, rm, 0, true);
226 case 0xa:
227 return new CmpReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
228 case 0xb:
229 return new CmnReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
230 case 0xc:
231 return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
232 case 0xd:
233 //XXX Implement me!
234 return new WarnUnimplemented("mul", machInst);
235 case 0xe:
236 return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
237 case 0xf:
238 return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
239 }
240 }
241 '''
242}};
243
244def format Thumb16SpecDataAndBx() {{
245 decode_block = '''
246 {
247 const IntRegIndex rdn =
248 (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
249 (bits(machInst, 7) << 3));
250 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
251 switch (bits(machInst, 9, 8)) {
252 case 0x0:
253 return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
254 case 0x1:
255 return new CmpReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
256 case 0x2:
257 return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
258 case 0x3:
259 if (bits(machInst, 7) == 0)
260 return new WarnUnimplemented("bx", machInst);
261 else
262 // The register version.
263 return new WarnUnimplemented("blx", machInst);
259 if (bits(machInst, 7) == 0) {
260 return new BxReg(machInst,
261 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
262 COND_UC);
263 } else {
264 return new BlxReg(machInst,
265 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
266 COND_UC);
267 }
264 }
265 }
266 '''
267}};
268
269def format Thumb16Adr() {{
270 decode_block = '''
271 {
272 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
273 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
274 return new AddImm(machInst, rd, INTREG_PC, imm8, true);
275 }
276 '''
277}};
278
279def format Thumb16AddSp() {{
280 decode_block = '''
281 {
282 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
283 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
284 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
285 }
286 '''
287}};
288
289def format Thumb16Misc() {{
290 decode_block = '''
291 {
292 switch (bits(machInst, 11, 8)) {
293 case 0x0:
294 if (bits(machInst, 7)) {
295 return new SubImm(machInst, INTREG_SP, INTREG_SP,
296 bits(machInst, 6, 0) << 2, true);
297 } else {
298 return new AddImm(machInst, INTREG_SP, INTREG_SP,
299 bits(machInst, 6, 0) << 2, true);
300 }
301 case 0x1:
268 }
269 }
270 '''
271}};
272
273def format Thumb16Adr() {{
274 decode_block = '''
275 {
276 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
277 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
278 return new AddImm(machInst, rd, INTREG_PC, imm8, true);
279 }
280 '''
281}};
282
283def format Thumb16AddSp() {{
284 decode_block = '''
285 {
286 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
287 const uint32_t imm8 = bits(machInst, 7, 0) << 2;
288 return new AddImm(machInst, rd, INTREG_SP, imm8, true);
289 }
290 '''
291}};
292
293def format Thumb16Misc() {{
294 decode_block = '''
295 {
296 switch (bits(machInst, 11, 8)) {
297 case 0x0:
298 if (bits(machInst, 7)) {
299 return new SubImm(machInst, INTREG_SP, INTREG_SP,
300 bits(machInst, 6, 0) << 2, true);
301 } else {
302 return new AddImm(machInst, INTREG_SP, INTREG_SP,
303 bits(machInst, 6, 0) << 2, true);
304 }
305 case 0x1:
302 return new WarnUnimplemented("cbz", machInst);
306 return new Cbz(machInst,
307 (bits(machInst, 9) << 6) |
308 (bits(machInst, 7, 3) << 1),
309 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
303 case 0x2:
304 switch (bits(machInst, 7, 6)) {
305 case 0x0:
306 return new WarnUnimplemented("sxth", machInst);
307 case 0x1:
308 return new WarnUnimplemented("sxtb", machInst);
309 case 0x2:
310 return new WarnUnimplemented("uxth", machInst);
311 case 0x3:
312 return new WarnUnimplemented("uxtb", machInst);
313 }
314 case 0x3:
310 case 0x2:
311 switch (bits(machInst, 7, 6)) {
312 case 0x0:
313 return new WarnUnimplemented("sxth", machInst);
314 case 0x1:
315 return new WarnUnimplemented("sxtb", machInst);
316 case 0x2:
317 return new WarnUnimplemented("uxth", machInst);
318 case 0x3:
319 return new WarnUnimplemented("uxtb", machInst);
320 }
321 case 0x3:
315 return new WarnUnimplemented("cbnz", machInst);
322 return new Cbz(machInst,
323 (bits(machInst, 9) << 6) |
324 (bits(machInst, 7, 3) << 1),
325 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
316 case 0x4:
317 case 0x5:
318 return new WarnUnimplemented("push", machInst);
319 case 0x6:
320 {
321 const uint32_t opBits = bits(machInst, 7, 5);
322 if (opBits == 2) {
323 return new WarnUnimplemented("setend", machInst);
324 } else if (opBits == 3) {
325 return new WarnUnimplemented("cps", machInst);
326 }
327 }
328 case 0x9:
326 case 0x4:
327 case 0x5:
328 return new WarnUnimplemented("push", machInst);
329 case 0x6:
330 {
331 const uint32_t opBits = bits(machInst, 7, 5);
332 if (opBits == 2) {
333 return new WarnUnimplemented("setend", machInst);
334 } else if (opBits == 3) {
335 return new WarnUnimplemented("cps", machInst);
336 }
337 }
338 case 0x9:
329 return new WarnUnimplemented("cbz", machInst);
339 return new Cbnz(machInst,
340 (bits(machInst, 9) << 6) |
341 (bits(machInst, 7, 3) << 1),
342 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
330 case 0xa:
331 switch (bits(machInst, 7, 5)) {
332 case 0x0:
333 return new WarnUnimplemented("rev", machInst);
334 case 0x1:
335 return new WarnUnimplemented("rev16", machInst);
336 case 0x3:
337 return new WarnUnimplemented("revsh", machInst);
338 default:
339 break;
340 }
341 break;
342 case 0xb:
343 case 0xa:
344 switch (bits(machInst, 7, 5)) {
345 case 0x0:
346 return new WarnUnimplemented("rev", machInst);
347 case 0x1:
348 return new WarnUnimplemented("rev16", machInst);
349 case 0x3:
350 return new WarnUnimplemented("revsh", machInst);
351 default:
352 break;
353 }
354 break;
355 case 0xb:
343 return new WarnUnimplemented("cbnz", machInst);
356 return new Cbnz(machInst,
357 (bits(machInst, 9) << 6) |
358 (bits(machInst, 7, 3) << 1),
359 (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
344 case 0xc:
345 case 0xd:
346 return new WarnUnimplemented("pop", machInst);
347 case 0xe:
348 return new WarnUnimplemented("bkpt", machInst);
349 case 0xf:
350 if (bits(machInst, 3, 0) != 0)
351 return new WarnUnimplemented("it", machInst);
352 switch (bits(machInst, 7, 4)) {
353 case 0x0:
354 return new WarnUnimplemented("nop", machInst);
355 case 0x1:
356 return new WarnUnimplemented("yield", machInst);
357 case 0x2:
358 return new WarnUnimplemented("wfe", machInst);
359 case 0x3:
360 return new WarnUnimplemented("wfi", machInst);
361 case 0x4:
362 return new WarnUnimplemented("sev", machInst);
363 default:
364 return new WarnUnimplemented("unallocated_hint", machInst);
365 }
366 default:
367 break;
368 }
369 return new Unknown(machInst);
370 }
371 '''
372}};
373
374def format Thumb32DataProcModImm() {{
375
376 def decInst(mnem, dest="rd", op1="rn"):
377 return '''
378 if (s) {
379 return new %(mnem)sImmCc(machInst, %(dest)s,
380 %(op1)s, imm, true);
381 } else {
382 return new %(mnem)sImm(machInst, %(dest)s,
383 %(op1)s, imm, true);
384 }
385 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
386
387 decode_block = '''
388 {
389 const uint32_t op = bits(machInst, 24, 21);
390 const bool s = (bits(machInst, 20) == 1);
391 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
392 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
393 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
394 bits(machInst, 14, 12);
395 const uint32_t dataImm = bits(machInst, 7, 0);
396 const uint32_t imm = modified_imm(ctrlImm, dataImm);
397 switch (op) {
398 case 0x0:
399 if (rd == INTREG_PC) {
400 %(tst)s
401 } else {
402 %(and)s
403 }
404 case 0x1:
405 %(bic)s
406 case 0x2:
407 if (rn == INTREG_PC) {
408 %(mov)s
409 } else {
410 %(orr)s
411 }
412 case 0x3:
413 if (rn == INTREG_PC) {
414 %(mvn)s
415 } else {
416 %(orn)s
417 }
418 case 0x4:
419 if (rd == INTREG_PC) {
420 %(teq)s
421 } else {
422 %(eor)s
423 }
424 case 0x8:
425 if (rd == INTREG_PC) {
426 %(cmn)s
427 } else {
428 %(add)s
429 }
430 case 0xa:
431 %(adc)s
432 case 0xb:
433 %(sbc)s
434 case 0xd:
435 if (rd == INTREG_PC) {
436 %(cmp)s
437 } else {
438 %(sub)s
439 }
440 case 0xe:
441 %(rsb)s
442 default:
443 return new Unknown(machInst);
444 }
445 }
446 ''' % {
447 "tst" : decInst("Tst", "INTREG_ZERO"),
448 "and" : decInst("And"),
449 "bic" : decInst("Bic"),
450 "mov" : decInst("Mov", op1="INTREG_ZERO"),
451 "orr" : decInst("Orr"),
452 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
453 "orn" : decInst("Orn"),
454 "teq" : decInst("Teq", dest="INTREG_ZERO"),
455 "eor" : decInst("Eor"),
456 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
457 "add" : decInst("Add"),
458 "adc" : decInst("Adc"),
459 "sbc" : decInst("Sbc"),
460 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
461 "sub" : decInst("Sub"),
462 "rsb" : decInst("Rsb")
463 }
464}};
465
466def format Thumb32DataProcShiftReg() {{
467
468 def decInst(mnem, dest="rd", op1="rn"):
469 return '''
470 if (s) {
471 return new %(mnem)sRegCc(machInst, %(dest)s,
472 %(op1)s, rm, amt, type);
473 } else {
474 return new %(mnem)sReg(machInst, %(dest)s,
475 %(op1)s, rm, amt, type);
476 }
477 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
478
479 decode_block = '''
480 {
481 const uint32_t op = bits(machInst, 24, 21);
482 const bool s = (bits(machInst, 20) == 1);
483 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
484 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
485 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
486 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
487 bits(machInst, 7, 6);
488 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
489 switch (op) {
490 case 0x0:
491 if (rd == INTREG_PC) {
492 %(tst)s
493 } else {
494 %(and)s
495 }
496 case 0x1:
497 %(bic)s
498 case 0x2:
499 if (rn == INTREG_PC) {
500 %(mov)s
501 } else {
502 %(orr)s
503 }
504 case 0x3:
505 if (rn == INTREG_PC) {
506 %(mvn)s
507 } else {
508 %(orn)s
509 }
510 case 0x4:
511 if (rd == INTREG_PC) {
512 %(teq)s
513 } else {
514 %(eor)s
515 }
516 case 0x6:
517 return new WarnUnimplemented("pkh", machInst);
518 case 0x8:
519 if (rd == INTREG_PC) {
520 %(cmn)s
521 } else {
522 %(add)s
523 }
524 case 0xa:
525 %(adc)s
526 case 0xb:
527 %(sbc)s
528 case 0xd:
529 if (rd == INTREG_PC) {
530 %(cmp)s
531 } else {
532 %(sub)s
533 }
534 case 0xe:
535 %(rsb)s
536 default:
537 return new Unknown(machInst);
538 }
539 }
540 ''' % {
541 "tst" : decInst("Tst", "INTREG_ZERO"),
542 "and" : decInst("And"),
543 "bic" : decInst("Bic"),
544 "mov" : decInst("Mov", op1="INTREG_ZERO"),
545 "orr" : decInst("Orr"),
546 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
547 "orn" : decInst("Orn"),
548 "teq" : decInst("Teq", "INTREG_ZERO"),
549 "eor" : decInst("Eor"),
550 "cmn" : decInst("Cmn", "INTREG_ZERO"),
551 "add" : decInst("Add"),
552 "adc" : decInst("Adc"),
553 "sbc" : decInst("Sbc"),
554 "cmp" : decInst("Cmp", "INTREG_ZERO"),
555 "sub" : decInst("Sub"),
556 "rsb" : decInst("Rsb")
557 }
558}};
360 case 0xc:
361 case 0xd:
362 return new WarnUnimplemented("pop", machInst);
363 case 0xe:
364 return new WarnUnimplemented("bkpt", machInst);
365 case 0xf:
366 if (bits(machInst, 3, 0) != 0)
367 return new WarnUnimplemented("it", machInst);
368 switch (bits(machInst, 7, 4)) {
369 case 0x0:
370 return new WarnUnimplemented("nop", machInst);
371 case 0x1:
372 return new WarnUnimplemented("yield", machInst);
373 case 0x2:
374 return new WarnUnimplemented("wfe", machInst);
375 case 0x3:
376 return new WarnUnimplemented("wfi", machInst);
377 case 0x4:
378 return new WarnUnimplemented("sev", machInst);
379 default:
380 return new WarnUnimplemented("unallocated_hint", machInst);
381 }
382 default:
383 break;
384 }
385 return new Unknown(machInst);
386 }
387 '''
388}};
389
390def format Thumb32DataProcModImm() {{
391
392 def decInst(mnem, dest="rd", op1="rn"):
393 return '''
394 if (s) {
395 return new %(mnem)sImmCc(machInst, %(dest)s,
396 %(op1)s, imm, true);
397 } else {
398 return new %(mnem)sImm(machInst, %(dest)s,
399 %(op1)s, imm, true);
400 }
401 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
402
403 decode_block = '''
404 {
405 const uint32_t op = bits(machInst, 24, 21);
406 const bool s = (bits(machInst, 20) == 1);
407 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
408 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
409 const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
410 bits(machInst, 14, 12);
411 const uint32_t dataImm = bits(machInst, 7, 0);
412 const uint32_t imm = modified_imm(ctrlImm, dataImm);
413 switch (op) {
414 case 0x0:
415 if (rd == INTREG_PC) {
416 %(tst)s
417 } else {
418 %(and)s
419 }
420 case 0x1:
421 %(bic)s
422 case 0x2:
423 if (rn == INTREG_PC) {
424 %(mov)s
425 } else {
426 %(orr)s
427 }
428 case 0x3:
429 if (rn == INTREG_PC) {
430 %(mvn)s
431 } else {
432 %(orn)s
433 }
434 case 0x4:
435 if (rd == INTREG_PC) {
436 %(teq)s
437 } else {
438 %(eor)s
439 }
440 case 0x8:
441 if (rd == INTREG_PC) {
442 %(cmn)s
443 } else {
444 %(add)s
445 }
446 case 0xa:
447 %(adc)s
448 case 0xb:
449 %(sbc)s
450 case 0xd:
451 if (rd == INTREG_PC) {
452 %(cmp)s
453 } else {
454 %(sub)s
455 }
456 case 0xe:
457 %(rsb)s
458 default:
459 return new Unknown(machInst);
460 }
461 }
462 ''' % {
463 "tst" : decInst("Tst", "INTREG_ZERO"),
464 "and" : decInst("And"),
465 "bic" : decInst("Bic"),
466 "mov" : decInst("Mov", op1="INTREG_ZERO"),
467 "orr" : decInst("Orr"),
468 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
469 "orn" : decInst("Orn"),
470 "teq" : decInst("Teq", dest="INTREG_ZERO"),
471 "eor" : decInst("Eor"),
472 "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
473 "add" : decInst("Add"),
474 "adc" : decInst("Adc"),
475 "sbc" : decInst("Sbc"),
476 "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
477 "sub" : decInst("Sub"),
478 "rsb" : decInst("Rsb")
479 }
480}};
481
482def format Thumb32DataProcShiftReg() {{
483
484 def decInst(mnem, dest="rd", op1="rn"):
485 return '''
486 if (s) {
487 return new %(mnem)sRegCc(machInst, %(dest)s,
488 %(op1)s, rm, amt, type);
489 } else {
490 return new %(mnem)sReg(machInst, %(dest)s,
491 %(op1)s, rm, amt, type);
492 }
493 ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
494
495 decode_block = '''
496 {
497 const uint32_t op = bits(machInst, 24, 21);
498 const bool s = (bits(machInst, 20) == 1);
499 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
500 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
501 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
502 const uint32_t amt = (bits(machInst, 14, 12) << 2) |
503 bits(machInst, 7, 6);
504 const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
505 switch (op) {
506 case 0x0:
507 if (rd == INTREG_PC) {
508 %(tst)s
509 } else {
510 %(and)s
511 }
512 case 0x1:
513 %(bic)s
514 case 0x2:
515 if (rn == INTREG_PC) {
516 %(mov)s
517 } else {
518 %(orr)s
519 }
520 case 0x3:
521 if (rn == INTREG_PC) {
522 %(mvn)s
523 } else {
524 %(orn)s
525 }
526 case 0x4:
527 if (rd == INTREG_PC) {
528 %(teq)s
529 } else {
530 %(eor)s
531 }
532 case 0x6:
533 return new WarnUnimplemented("pkh", machInst);
534 case 0x8:
535 if (rd == INTREG_PC) {
536 %(cmn)s
537 } else {
538 %(add)s
539 }
540 case 0xa:
541 %(adc)s
542 case 0xb:
543 %(sbc)s
544 case 0xd:
545 if (rd == INTREG_PC) {
546 %(cmp)s
547 } else {
548 %(sub)s
549 }
550 case 0xe:
551 %(rsb)s
552 default:
553 return new Unknown(machInst);
554 }
555 }
556 ''' % {
557 "tst" : decInst("Tst", "INTREG_ZERO"),
558 "and" : decInst("And"),
559 "bic" : decInst("Bic"),
560 "mov" : decInst("Mov", op1="INTREG_ZERO"),
561 "orr" : decInst("Orr"),
562 "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
563 "orn" : decInst("Orn"),
564 "teq" : decInst("Teq", "INTREG_ZERO"),
565 "eor" : decInst("Eor"),
566 "cmn" : decInst("Cmn", "INTREG_ZERO"),
567 "add" : decInst("Add"),
568 "adc" : decInst("Adc"),
569 "sbc" : decInst("Sbc"),
570 "cmp" : decInst("Cmp", "INTREG_ZERO"),
571 "sub" : decInst("Sub"),
572 "rsb" : decInst("Rsb")
573 }
574}};