aarch64.isa (14127:65faf17eea53) aarch64.isa (14128:6ed23d07d0d1)
1// Copyright (c) 2011-2019 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// Thomas Grocutt
38// Mbou Eyole
39// Giacomo Gabrielli
40
41output header {{
42namespace Aarch64
43{
44 StaticInstPtr decodeDataProcImm(ExtMachInst machInst);
45 StaticInstPtr decodeBranchExcSys(ExtMachInst machInst);
46 StaticInstPtr decodeLoadsStores(ExtMachInst machInst);
47 StaticInstPtr decodeDataProcReg(ExtMachInst machInst);
48
49 template <typename DecoderFeatures>
50 StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst);
51 StaticInstPtr decodeFp(ExtMachInst machInst);
52 template <typename DecoderFeatures>
53 StaticInstPtr decodeAdvSIMD(ExtMachInst machInst);
54 StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst);
55
56 StaticInstPtr decodeSveInt(ExtMachInst machInst);
57 StaticInstPtr decodeSveFp(ExtMachInst machInst);
58 StaticInstPtr decodeSveMem(ExtMachInst machInst);
59
60 StaticInstPtr decodeGem5Ops(ExtMachInst machInst);
61}
62}};
63
64output decoder {{
65namespace Aarch64
66{
67 StaticInstPtr
68 decodeDataProcImm(ExtMachInst machInst)
69 {
70 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
71 IntRegIndex rdsp = makeSP(rd);
72 IntRegIndex rdzr = makeZero(rd);
73 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
74 IntRegIndex rnsp = makeSP(rn);
75
76 uint8_t opc = bits(machInst, 30, 29);
77 bool sf = bits(machInst, 31);
78 bool n = bits(machInst, 22);
79 uint8_t immr = bits(machInst, 21, 16);
80 uint8_t imms = bits(machInst, 15, 10);
81 switch (bits(machInst, 25, 23)) {
82 case 0x0:
83 case 0x1:
84 {
85 uint64_t immlo = bits(machInst, 30, 29);
86 uint64_t immhi = bits(machInst, 23, 5);
87 uint64_t imm = (immlo << 0) | (immhi << 2);
88 if (bits(machInst, 31) == 0)
89 return new AdrXImm(machInst, rdzr, INTREG_ZERO, sext<21>(imm));
90 else
91 return new AdrpXImm(machInst, rdzr, INTREG_ZERO,
92 sext<33>(imm << 12));
93 }
94 case 0x2:
95 case 0x3:
96 {
97 uint32_t imm12 = bits(machInst, 21, 10);
98 uint8_t shift = bits(machInst, 23, 22);
99 uint32_t imm;
100 if (shift == 0x0)
101 imm = imm12 << 0;
102 else if (shift == 0x1)
103 imm = imm12 << 12;
104 else
105 return new Unknown64(machInst);
106 switch (opc) {
107 case 0x0:
108 return new AddXImm(machInst, rdsp, rnsp, imm);
109 case 0x1:
110 return new AddXImmCc(machInst, rdzr, rnsp, imm);
111 case 0x2:
112 return new SubXImm(machInst, rdsp, rnsp, imm);
113 case 0x3:
114 return new SubXImmCc(machInst, rdzr, rnsp, imm);
115 default:
116 M5_UNREACHABLE;
117 }
118 }
119 case 0x4:
120 {
121 if (!sf && n)
122 return new Unknown64(machInst);
123 // len = MSB(n:NOT(imms)), len < 1 is undefined.
124 uint8_t len = 0;
125 if (n) {
126 len = 6;
127 } else if (imms == 0x3f || imms == 0x3e) {
128 return new Unknown64(machInst);
129 } else {
130 len = findMsbSet(imms ^ 0x3f);
131 }
132 // Generate r, s, and size.
133 uint64_t r = bits(immr, len - 1, 0);
134 uint64_t s = bits(imms, len - 1, 0);
135 uint8_t size = 1 << len;
136 if (s == size - 1)
137 return new Unknown64(machInst);
138 // Generate the pattern with s 1s, rotated by r, with size bits.
139 uint64_t pattern = mask(s + 1);
140 if (r) {
141 pattern = (pattern >> r) | (pattern << (size - r));
142 pattern &= mask(size);
143 }
144 uint8_t width = sf ? 64 : 32;
145 // Replicate that to fill up the immediate.
146 for (unsigned i = 1; i < (width / size); i *= 2)
147 pattern |= (pattern << (i * size));
148 uint64_t imm = pattern;
149
150 switch (opc) {
151 case 0x0:
152 return new AndXImm(machInst, rdsp, rn, imm);
153 case 0x1:
154 return new OrrXImm(machInst, rdsp, rn, imm);
155 case 0x2:
156 return new EorXImm(machInst, rdsp, rn, imm);
157 case 0x3:
158 return new AndXImmCc(machInst, rdzr, rn, imm);
159 default:
160 M5_UNREACHABLE;
161 }
162 }
163 case 0x5:
164 {
165 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
166 IntRegIndex rdzr = makeZero(rd);
167 uint32_t imm16 = bits(machInst, 20, 5);
168 uint32_t hw = bits(machInst, 22, 21);
169 switch (opc) {
170 case 0x0:
171 return new Movn(machInst, rdzr, imm16, hw * 16);
172 case 0x1:
173 return new Unknown64(machInst);
174 case 0x2:
175 return new Movz(machInst, rdzr, imm16, hw * 16);
176 case 0x3:
177 return new Movk(machInst, rdzr, imm16, hw * 16);
178 default:
179 M5_UNREACHABLE;
180 }
181 }
182 case 0x6:
183 if ((sf != n) || (!sf && (bits(immr, 5) || bits(imms, 5))))
184 return new Unknown64(machInst);
185 switch (opc) {
186 case 0x0:
187 return new Sbfm64(machInst, rdzr, rn, immr, imms);
188 case 0x1:
189 return new Bfm64(machInst, rdzr, rn, immr, imms);
190 case 0x2:
191 return new Ubfm64(machInst, rdzr, rn, immr, imms);
192 case 0x3:
193 return new Unknown64(machInst);
194 default:
195 M5_UNREACHABLE;
196 }
197 case 0x7:
198 {
199 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
200 if (opc || bits(machInst, 21))
201 return new Unknown64(machInst);
202 else
203 return new Extr64(machInst, rdzr, rn, rm, imms);
204 }
205 }
206 return new FailUnimplemented("Unhandled Case8", machInst);
207 }
208}
209}};
210
211output decoder {{
212namespace Aarch64
213{
214 StaticInstPtr
215 decodeBranchExcSys(ExtMachInst machInst)
216 {
217 switch (bits(machInst, 30, 29)) {
218 case 0x0:
219 {
220 int64_t imm = sext<26>(bits(machInst, 25, 0)) << 2;
221 if (bits(machInst, 31) == 0)
222 return new B64(machInst, imm);
223 else
224 return new Bl64(machInst, imm);
225 }
226 case 0x1:
227 {
228 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
229 if (bits(machInst, 25) == 0) {
230 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
231 if (bits(machInst, 24) == 0)
232 return new Cbz64(machInst, imm, rt);
233 else
234 return new Cbnz64(machInst, imm, rt);
235 } else {
236 uint64_t bitmask = 0x1;
237 bitmask <<= bits(machInst, 23, 19);
238 int64_t imm = sext<14>(bits(machInst, 18, 5)) << 2;
239 if (bits(machInst, 31))
240 bitmask <<= 32;
241 if (bits(machInst, 24) == 0)
242 return new Tbz64(machInst, bitmask, imm, rt);
243 else
244 return new Tbnz64(machInst, bitmask, imm, rt);
245 }
246 }
247 case 0x2:
248 // bit 30:26=10101
249 if (bits(machInst, 31) == 0) {
250 if (bits(machInst, 25, 24) || bits(machInst, 4))
251 return new Unknown64(machInst);
252 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
253 ConditionCode condCode =
254 (ConditionCode)(uint8_t)(bits(machInst, 3, 0));
255 return new BCond64(machInst, imm, condCode);
256 } else if (bits(machInst, 25, 24) == 0x0) {
257
258 if (bits(machInst, 4, 2))
259 return new Unknown64(machInst);
260
261 auto imm16 = bits(machInst, 20, 5);
262 uint8_t decVal = (bits(machInst, 1, 0) << 0) |
263 (bits(machInst, 23, 21) << 2);
264
265 switch (decVal) {
266 case 0x01:
267 return new Svc64(machInst, imm16);
268 case 0x02:
269 return new Hvc64(machInst, imm16);
270 case 0x03:
271 return new Smc64(machInst, imm16);
272 case 0x04:
273 return new Brk64(machInst, imm16);
274 case 0x08:
275 return new Hlt64(machInst, imm16);
276 case 0x15:
277 return new FailUnimplemented("dcps1", machInst);
278 case 0x16:
279 return new FailUnimplemented("dcps2", machInst);
280 case 0x17:
281 return new FailUnimplemented("dcps3", machInst);
282 default:
283 return new Unknown64(machInst);
284 }
285 } else if (bits(machInst, 25, 22) == 0x4) {
286 // bit 31:22=1101010100
287 bool l = bits(machInst, 21);
288 uint8_t op0 = bits(machInst, 20, 19);
289 uint8_t op1 = bits(machInst, 18, 16);
290 uint8_t crn = bits(machInst, 15, 12);
291 uint8_t crm = bits(machInst, 11, 8);
292 uint8_t op2 = bits(machInst, 7, 5);
293 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
294 switch (op0) {
295 case 0x0:
296 if (rt != 0x1f || l)
297 return new Unknown64(machInst);
298 if (crn == 0x2 && op1 == 0x3) {
299 switch (crm) {
300 case 0x0:
301 switch (op2) {
302 case 0x0:
303 return new NopInst(machInst);
304 case 0x1:
305 return new YieldInst(machInst);
306 case 0x2:
307 return new WfeInst(machInst);
308 case 0x3:
309 return new WfiInst(machInst);
310 case 0x4:
311 return new SevInst(machInst);
312 case 0x5:
313 return new SevlInst(machInst);
314 }
315 break;
316 case 0x1:
317 switch (op2) {
318 case 0x0:
319 return new WarnUnimplemented(
320 "pacia", machInst);
321 case 0x2:
322 return new WarnUnimplemented(
323 "pacib", machInst);
324 case 0x4:
325 return new WarnUnimplemented(
326 "autia", machInst);
327 case 0x6:
328 return new WarnUnimplemented(
329 "autib", machInst);
330 }
331 break;
332 case 0x2:
333 switch (op2) {
334 case 0x0:
335 return new WarnUnimplemented(
336 "esb", machInst);
337 case 0x1:
338 return new WarnUnimplemented(
339 "psb csync", machInst);
340 case 0x2:
341 return new WarnUnimplemented(
342 "tsb csync", machInst);
343 case 0x4:
344 return new WarnUnimplemented(
345 "csdb", machInst);
346 }
347 break;
348 case 0x3:
349 switch (op2) {
350 case 0x0:
351 case 0x1:
352 return new WarnUnimplemented(
353 "pacia", machInst);
354 case 0x2:
355 case 0x3:
356 return new WarnUnimplemented(
357 "pacib", machInst);
358 case 0x4:
359 case 0x5:
360 return new WarnUnimplemented(
361 "autia", machInst);
362 case 0x6:
363 case 0x7:
364 return new WarnUnimplemented(
365 "autib", machInst);
366 }
367 break;
368 case 0x4:
369 switch (op2 & 0x1) {
370 case 0x0:
371 return new WarnUnimplemented(
372 "bti", machInst);
373 }
374 break;
375 }
376 return new WarnUnimplemented(
377 "unallocated_hint", machInst);
378 } else if (crn == 0x3 && op1 == 0x3) {
379 switch (op2) {
380 case 0x2:
381 return new Clrex64(machInst);
382 case 0x4:
383 return new Dsb64(machInst);
384 case 0x5:
385 return new Dmb64(machInst);
386 case 0x6:
387 return new Isb64(machInst);
388 default:
389 return new Unknown64(machInst);
390 }
391 } else if (crn == 0x4) {
392 // MSR immediate: moving immediate value to selected
393 // bits of the PSTATE
394 switch (op1 << 3 | op2) {
1// Copyright (c) 2011-2019 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// Thomas Grocutt
38// Mbou Eyole
39// Giacomo Gabrielli
40
41output header {{
42namespace Aarch64
43{
44 StaticInstPtr decodeDataProcImm(ExtMachInst machInst);
45 StaticInstPtr decodeBranchExcSys(ExtMachInst machInst);
46 StaticInstPtr decodeLoadsStores(ExtMachInst machInst);
47 StaticInstPtr decodeDataProcReg(ExtMachInst machInst);
48
49 template <typename DecoderFeatures>
50 StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst);
51 StaticInstPtr decodeFp(ExtMachInst machInst);
52 template <typename DecoderFeatures>
53 StaticInstPtr decodeAdvSIMD(ExtMachInst machInst);
54 StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst);
55
56 StaticInstPtr decodeSveInt(ExtMachInst machInst);
57 StaticInstPtr decodeSveFp(ExtMachInst machInst);
58 StaticInstPtr decodeSveMem(ExtMachInst machInst);
59
60 StaticInstPtr decodeGem5Ops(ExtMachInst machInst);
61}
62}};
63
64output decoder {{
65namespace Aarch64
66{
67 StaticInstPtr
68 decodeDataProcImm(ExtMachInst machInst)
69 {
70 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
71 IntRegIndex rdsp = makeSP(rd);
72 IntRegIndex rdzr = makeZero(rd);
73 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
74 IntRegIndex rnsp = makeSP(rn);
75
76 uint8_t opc = bits(machInst, 30, 29);
77 bool sf = bits(machInst, 31);
78 bool n = bits(machInst, 22);
79 uint8_t immr = bits(machInst, 21, 16);
80 uint8_t imms = bits(machInst, 15, 10);
81 switch (bits(machInst, 25, 23)) {
82 case 0x0:
83 case 0x1:
84 {
85 uint64_t immlo = bits(machInst, 30, 29);
86 uint64_t immhi = bits(machInst, 23, 5);
87 uint64_t imm = (immlo << 0) | (immhi << 2);
88 if (bits(machInst, 31) == 0)
89 return new AdrXImm(machInst, rdzr, INTREG_ZERO, sext<21>(imm));
90 else
91 return new AdrpXImm(machInst, rdzr, INTREG_ZERO,
92 sext<33>(imm << 12));
93 }
94 case 0x2:
95 case 0x3:
96 {
97 uint32_t imm12 = bits(machInst, 21, 10);
98 uint8_t shift = bits(machInst, 23, 22);
99 uint32_t imm;
100 if (shift == 0x0)
101 imm = imm12 << 0;
102 else if (shift == 0x1)
103 imm = imm12 << 12;
104 else
105 return new Unknown64(machInst);
106 switch (opc) {
107 case 0x0:
108 return new AddXImm(machInst, rdsp, rnsp, imm);
109 case 0x1:
110 return new AddXImmCc(machInst, rdzr, rnsp, imm);
111 case 0x2:
112 return new SubXImm(machInst, rdsp, rnsp, imm);
113 case 0x3:
114 return new SubXImmCc(machInst, rdzr, rnsp, imm);
115 default:
116 M5_UNREACHABLE;
117 }
118 }
119 case 0x4:
120 {
121 if (!sf && n)
122 return new Unknown64(machInst);
123 // len = MSB(n:NOT(imms)), len < 1 is undefined.
124 uint8_t len = 0;
125 if (n) {
126 len = 6;
127 } else if (imms == 0x3f || imms == 0x3e) {
128 return new Unknown64(machInst);
129 } else {
130 len = findMsbSet(imms ^ 0x3f);
131 }
132 // Generate r, s, and size.
133 uint64_t r = bits(immr, len - 1, 0);
134 uint64_t s = bits(imms, len - 1, 0);
135 uint8_t size = 1 << len;
136 if (s == size - 1)
137 return new Unknown64(machInst);
138 // Generate the pattern with s 1s, rotated by r, with size bits.
139 uint64_t pattern = mask(s + 1);
140 if (r) {
141 pattern = (pattern >> r) | (pattern << (size - r));
142 pattern &= mask(size);
143 }
144 uint8_t width = sf ? 64 : 32;
145 // Replicate that to fill up the immediate.
146 for (unsigned i = 1; i < (width / size); i *= 2)
147 pattern |= (pattern << (i * size));
148 uint64_t imm = pattern;
149
150 switch (opc) {
151 case 0x0:
152 return new AndXImm(machInst, rdsp, rn, imm);
153 case 0x1:
154 return new OrrXImm(machInst, rdsp, rn, imm);
155 case 0x2:
156 return new EorXImm(machInst, rdsp, rn, imm);
157 case 0x3:
158 return new AndXImmCc(machInst, rdzr, rn, imm);
159 default:
160 M5_UNREACHABLE;
161 }
162 }
163 case 0x5:
164 {
165 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
166 IntRegIndex rdzr = makeZero(rd);
167 uint32_t imm16 = bits(machInst, 20, 5);
168 uint32_t hw = bits(machInst, 22, 21);
169 switch (opc) {
170 case 0x0:
171 return new Movn(machInst, rdzr, imm16, hw * 16);
172 case 0x1:
173 return new Unknown64(machInst);
174 case 0x2:
175 return new Movz(machInst, rdzr, imm16, hw * 16);
176 case 0x3:
177 return new Movk(machInst, rdzr, imm16, hw * 16);
178 default:
179 M5_UNREACHABLE;
180 }
181 }
182 case 0x6:
183 if ((sf != n) || (!sf && (bits(immr, 5) || bits(imms, 5))))
184 return new Unknown64(machInst);
185 switch (opc) {
186 case 0x0:
187 return new Sbfm64(machInst, rdzr, rn, immr, imms);
188 case 0x1:
189 return new Bfm64(machInst, rdzr, rn, immr, imms);
190 case 0x2:
191 return new Ubfm64(machInst, rdzr, rn, immr, imms);
192 case 0x3:
193 return new Unknown64(machInst);
194 default:
195 M5_UNREACHABLE;
196 }
197 case 0x7:
198 {
199 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
200 if (opc || bits(machInst, 21))
201 return new Unknown64(machInst);
202 else
203 return new Extr64(machInst, rdzr, rn, rm, imms);
204 }
205 }
206 return new FailUnimplemented("Unhandled Case8", machInst);
207 }
208}
209}};
210
211output decoder {{
212namespace Aarch64
213{
214 StaticInstPtr
215 decodeBranchExcSys(ExtMachInst machInst)
216 {
217 switch (bits(machInst, 30, 29)) {
218 case 0x0:
219 {
220 int64_t imm = sext<26>(bits(machInst, 25, 0)) << 2;
221 if (bits(machInst, 31) == 0)
222 return new B64(machInst, imm);
223 else
224 return new Bl64(machInst, imm);
225 }
226 case 0x1:
227 {
228 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
229 if (bits(machInst, 25) == 0) {
230 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
231 if (bits(machInst, 24) == 0)
232 return new Cbz64(machInst, imm, rt);
233 else
234 return new Cbnz64(machInst, imm, rt);
235 } else {
236 uint64_t bitmask = 0x1;
237 bitmask <<= bits(machInst, 23, 19);
238 int64_t imm = sext<14>(bits(machInst, 18, 5)) << 2;
239 if (bits(machInst, 31))
240 bitmask <<= 32;
241 if (bits(machInst, 24) == 0)
242 return new Tbz64(machInst, bitmask, imm, rt);
243 else
244 return new Tbnz64(machInst, bitmask, imm, rt);
245 }
246 }
247 case 0x2:
248 // bit 30:26=10101
249 if (bits(machInst, 31) == 0) {
250 if (bits(machInst, 25, 24) || bits(machInst, 4))
251 return new Unknown64(machInst);
252 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
253 ConditionCode condCode =
254 (ConditionCode)(uint8_t)(bits(machInst, 3, 0));
255 return new BCond64(machInst, imm, condCode);
256 } else if (bits(machInst, 25, 24) == 0x0) {
257
258 if (bits(machInst, 4, 2))
259 return new Unknown64(machInst);
260
261 auto imm16 = bits(machInst, 20, 5);
262 uint8_t decVal = (bits(machInst, 1, 0) << 0) |
263 (bits(machInst, 23, 21) << 2);
264
265 switch (decVal) {
266 case 0x01:
267 return new Svc64(machInst, imm16);
268 case 0x02:
269 return new Hvc64(machInst, imm16);
270 case 0x03:
271 return new Smc64(machInst, imm16);
272 case 0x04:
273 return new Brk64(machInst, imm16);
274 case 0x08:
275 return new Hlt64(machInst, imm16);
276 case 0x15:
277 return new FailUnimplemented("dcps1", machInst);
278 case 0x16:
279 return new FailUnimplemented("dcps2", machInst);
280 case 0x17:
281 return new FailUnimplemented("dcps3", machInst);
282 default:
283 return new Unknown64(machInst);
284 }
285 } else if (bits(machInst, 25, 22) == 0x4) {
286 // bit 31:22=1101010100
287 bool l = bits(machInst, 21);
288 uint8_t op0 = bits(machInst, 20, 19);
289 uint8_t op1 = bits(machInst, 18, 16);
290 uint8_t crn = bits(machInst, 15, 12);
291 uint8_t crm = bits(machInst, 11, 8);
292 uint8_t op2 = bits(machInst, 7, 5);
293 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
294 switch (op0) {
295 case 0x0:
296 if (rt != 0x1f || l)
297 return new Unknown64(machInst);
298 if (crn == 0x2 && op1 == 0x3) {
299 switch (crm) {
300 case 0x0:
301 switch (op2) {
302 case 0x0:
303 return new NopInst(machInst);
304 case 0x1:
305 return new YieldInst(machInst);
306 case 0x2:
307 return new WfeInst(machInst);
308 case 0x3:
309 return new WfiInst(machInst);
310 case 0x4:
311 return new SevInst(machInst);
312 case 0x5:
313 return new SevlInst(machInst);
314 }
315 break;
316 case 0x1:
317 switch (op2) {
318 case 0x0:
319 return new WarnUnimplemented(
320 "pacia", machInst);
321 case 0x2:
322 return new WarnUnimplemented(
323 "pacib", machInst);
324 case 0x4:
325 return new WarnUnimplemented(
326 "autia", machInst);
327 case 0x6:
328 return new WarnUnimplemented(
329 "autib", machInst);
330 }
331 break;
332 case 0x2:
333 switch (op2) {
334 case 0x0:
335 return new WarnUnimplemented(
336 "esb", machInst);
337 case 0x1:
338 return new WarnUnimplemented(
339 "psb csync", machInst);
340 case 0x2:
341 return new WarnUnimplemented(
342 "tsb csync", machInst);
343 case 0x4:
344 return new WarnUnimplemented(
345 "csdb", machInst);
346 }
347 break;
348 case 0x3:
349 switch (op2) {
350 case 0x0:
351 case 0x1:
352 return new WarnUnimplemented(
353 "pacia", machInst);
354 case 0x2:
355 case 0x3:
356 return new WarnUnimplemented(
357 "pacib", machInst);
358 case 0x4:
359 case 0x5:
360 return new WarnUnimplemented(
361 "autia", machInst);
362 case 0x6:
363 case 0x7:
364 return new WarnUnimplemented(
365 "autib", machInst);
366 }
367 break;
368 case 0x4:
369 switch (op2 & 0x1) {
370 case 0x0:
371 return new WarnUnimplemented(
372 "bti", machInst);
373 }
374 break;
375 }
376 return new WarnUnimplemented(
377 "unallocated_hint", machInst);
378 } else if (crn == 0x3 && op1 == 0x3) {
379 switch (op2) {
380 case 0x2:
381 return new Clrex64(machInst);
382 case 0x4:
383 return new Dsb64(machInst);
384 case 0x5:
385 return new Dmb64(machInst);
386 case 0x6:
387 return new Isb64(machInst);
388 default:
389 return new Unknown64(machInst);
390 }
391 } else if (crn == 0x4) {
392 // MSR immediate: moving immediate value to selected
393 // bits of the PSTATE
394 switch (op1 << 3 | op2) {
395 case 0x4:
396 // PAN
397 return new MsrImm64(
398 machInst, MISCREG_PAN, crm);
395 case 0x5:
396 // SP
397 return new MsrImm64(
398 machInst, MISCREG_SPSEL, crm);
399 case 0x1e:
400 // DAIFSet
401 return new MsrImmDAIFSet64(
402 machInst, MISCREG_DAIF, crm);
403 case 0x1f:
404 // DAIFClr
405 return new MsrImmDAIFClr64(
406 machInst, MISCREG_DAIF, crm);
407 default:
408 return new Unknown64(machInst);
409 }
410 } else {
411 return new Unknown64(machInst);
412 }
413 break;
414 case 0x1:
415 case 0x2:
416 case 0x3:
417 {
418 // bit 31:22=1101010100, 20:19=11
419 bool read = l;
420 MiscRegIndex miscReg =
421 decodeAArch64SysReg(op0, op1, crn, crm, op2);
422 if (read) {
423 if ((miscReg == MISCREG_DC_CIVAC_Xt) ||
424 (miscReg == MISCREG_DC_CVAC_Xt) ||
425 (miscReg == MISCREG_DC_IVAC_Xt) ||
426 (miscReg == MISCREG_DC_ZVA_Xt)) {
427 return new Unknown64(machInst);
428 }
429 }
430 // Check for invalid registers
431 if (miscReg == MISCREG_UNKNOWN) {
432 auto full_mnemonic =
433 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d",
434 read ? "mrs" : "msr",
435 op0, op1, crn, crm, op2);
436
437 return new FailUnimplemented(read ? "mrs" : "msr",
438 machInst, full_mnemonic);
439
440 } else if (miscReg == MISCREG_IMPDEF_UNIMPL) {
441 auto full_mnemonic =
442 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d",
443 read ? "mrs" : "msr",
444 op0, op1, crn, crm, op2);
445
446 uint32_t iss = msrMrs64IssBuild(
447 read, op0, op1, crn, crm, op2, rt);
448
449 return new MiscRegImplDefined64(
450 read ? "mrs" : "msr",
451 machInst, miscReg, read, iss, full_mnemonic,
452 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]);
453
454 } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
455 if (miscReg == MISCREG_NZCV) {
456 if (read)
457 return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg);
458 else
459 return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt);
460 }
461 uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt);
462 if (read) {
463 StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss);
464 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE])
465 si->setFlag(StaticInst::IsUnverifiable);
466 return si;
467 } else {
468 switch (miscReg) {
469 case MISCREG_DC_ZVA_Xt:
470 return new Dczva(machInst, rt, miscReg, iss);
471 case MISCREG_DC_CVAU_Xt:
472 return new Dccvau(machInst, rt, miscReg, iss);
473 case MISCREG_DC_CVAC_Xt:
474 return new Dccvac(machInst, rt, miscReg, iss);
475 case MISCREG_DC_CIVAC_Xt:
476 return new Dccivac(machInst, rt, miscReg, iss);
477 case MISCREG_DC_IVAC_Xt:
478 return new Dcivac(machInst, rt, miscReg, iss);
479 default:
480 return new Msr64(machInst, miscReg, rt, iss);
481 }
482 }
483 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
484 std::string full_mnem = csprintf("%s %s",
485 read ? "mrs" : "msr", miscRegName[miscReg]);
486 return new WarnUnimplemented(read ? "mrs" : "msr",
487 machInst, full_mnem);
488 } else {
489 return new FailUnimplemented(read ? "mrs" : "msr",
490 machInst,
491 csprintf("%s %s",
492 read ? "mrs" : "msr",
493 miscRegName[miscReg]));
494 }
495 }
496 break;
497 default:
498 M5_UNREACHABLE;
499 }
500 } else if (bits(machInst, 25) == 0x1) {
501 uint8_t opc = bits(machInst, 24, 21);
502 uint8_t op2 = bits(machInst, 20, 16);
503 uint8_t op3 = bits(machInst, 15, 10);
504 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
505 uint8_t op4 = bits(machInst, 4, 0);
506 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0)
507 return new Unknown64(machInst);
508 switch (opc) {
509 case 0x0:
510 return new Br64(machInst, rn);
511 case 0x1:
512 return new Blr64(machInst, rn);
513 case 0x2:
514 return new Ret64(machInst, rn);
515 case 0x4:
516 if (rn != 0x1f)
517 return new Unknown64(machInst);
518 return new Eret64(machInst);
519 case 0x5:
520 if (rn != 0x1f)
521 return new Unknown64(machInst);
522 return new FailUnimplemented("dret", machInst);
523 default:
524 return new Unknown64(machInst);
525 }
526 }
527 M5_FALLTHROUGH;
528 default:
529 return new Unknown64(machInst);
530 }
531 return new FailUnimplemented("Unhandled Case7", machInst);
532 }
533}
534}};
535
536output decoder {{
537namespace Aarch64
538{
539 StaticInstPtr
540 decodeLoadsStores(ExtMachInst machInst)
541 {
542 // bit 27,25=10
543 switch (bits(machInst, 29, 28)) {
544 case 0x0:
545 if (bits(machInst, 26) == 0) {
546 if (bits(machInst, 24) != 0)
547 return new Unknown64(machInst);
548 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
549 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
550 IntRegIndex rnsp = makeSP(rn);
551 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
552 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
553 uint8_t opc = (bits(machInst, 15) << 0) |
554 (bits(machInst, 23, 21) << 1);
555 uint8_t size = bits(machInst, 31, 30);
556 switch (opc) {
557 case 0x0:
558 switch (size) {
559 case 0x0:
560 return new STXRB64(machInst, rt, rnsp, rs);
561 case 0x1:
562 return new STXRH64(machInst, rt, rnsp, rs);
563 case 0x2:
564 return new STXRW64(machInst, rt, rnsp, rs);
565 case 0x3:
566 return new STXRX64(machInst, rt, rnsp, rs);
567 default:
568 M5_UNREACHABLE;
569 }
570 case 0x1:
571 switch (size) {
572 case 0x0:
573 return new STLXRB64(machInst, rt, rnsp, rs);
574 case 0x1:
575 return new STLXRH64(machInst, rt, rnsp, rs);
576 case 0x2:
577 return new STLXRW64(machInst, rt, rnsp, rs);
578 case 0x3:
579 return new STLXRX64(machInst, rt, rnsp, rs);
580 default:
581 M5_UNREACHABLE;
582 }
583 case 0x2:
584 switch (size) {
585 case 0x0:
586 case 0x1:
587 return new Unknown64(machInst);
588 case 0x2:
589 return new STXPW64(machInst, rs, rt, rt2, rnsp);
590 case 0x3:
591 return new STXPX64(machInst, rs, rt, rt2, rnsp);
592 default:
593 M5_UNREACHABLE;
594 }
595
596 case 0x3:
597 switch (size) {
598 case 0x0:
599 case 0x1:
600 return new Unknown64(machInst);
601 case 0x2:
602 return new STLXPW64(machInst, rs, rt, rt2, rnsp);
603 case 0x3:
604 return new STLXPX64(machInst, rs, rt, rt2, rnsp);
605 default:
606 M5_UNREACHABLE;
607 }
608
609 case 0x4:
610 switch (size) {
611 case 0x0:
612 return new LDXRB64(machInst, rt, rnsp, rs);
613 case 0x1:
614 return new LDXRH64(machInst, rt, rnsp, rs);
615 case 0x2:
616 return new LDXRW64(machInst, rt, rnsp, rs);
617 case 0x3:
618 return new LDXRX64(machInst, rt, rnsp, rs);
619 default:
620 M5_UNREACHABLE;
621 }
622 case 0x5:
623 switch (size) {
624 case 0x0:
625 return new LDAXRB64(machInst, rt, rnsp, rs);
626 case 0x1:
627 return new LDAXRH64(machInst, rt, rnsp, rs);
628 case 0x2:
629 return new LDAXRW64(machInst, rt, rnsp, rs);
630 case 0x3:
631 return new LDAXRX64(machInst, rt, rnsp, rs);
632 default:
633 M5_UNREACHABLE;
634 }
635 case 0x6:
636 switch (size) {
637 case 0x0:
638 case 0x1:
639 return new Unknown64(machInst);
640 case 0x2:
641 return new LDXPW64(machInst, rt, rt2, rnsp);
642 case 0x3:
643 return new LDXPX64(machInst, rt, rt2, rnsp);
644 default:
645 M5_UNREACHABLE;
646 }
647
648 case 0x7:
649 switch (size) {
650 case 0x0:
651 case 0x1:
652 return new Unknown64(machInst);
653 case 0x2:
654 return new LDAXPW64(machInst, rt, rt2, rnsp);
655 case 0x3:
656 return new LDAXPX64(machInst, rt, rt2, rnsp);
657 default:
658 M5_UNREACHABLE;
659 }
660
661 case 0x9:
662 switch (size) {
663 case 0x0:
664 return new STLRB64(machInst, rt, rnsp);
665 case 0x1:
666 return new STLRH64(machInst, rt, rnsp);
667 case 0x2:
668 return new STLRW64(machInst, rt, rnsp);
669 case 0x3:
670 return new STLRX64(machInst, rt, rnsp);
671 default:
672 M5_UNREACHABLE;
673 }
674 case 0xd:
675 switch (size) {
676 case 0x0:
677 return new LDARB64(machInst, rt, rnsp);
678 case 0x1:
679 return new LDARH64(machInst, rt, rnsp);
680 case 0x2:
681 return new LDARW64(machInst, rt, rnsp);
682 case 0x3:
683 return new LDARX64(machInst, rt, rnsp);
684 default:
685 M5_UNREACHABLE;
686 }
687 default:
688 return new Unknown64(machInst);
689 }
690 } else if (bits(machInst, 31)) {
691 return new Unknown64(machInst);
692 } else {
693 return decodeNeonMem(machInst);
694 }
695 case 0x1:
696 {
697 if (bits(machInst, 24) != 0)
698 return new Unknown64(machInst);
699 uint8_t switchVal = (bits(machInst, 26) << 0) |
700 (bits(machInst, 31, 30) << 1);
701 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
702 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
703 switch (switchVal) {
704 case 0x0:
705 return new LDRWL64_LIT(machInst, rt, imm);
706 case 0x1:
707 return new LDRSFP64_LIT(machInst, rt, imm);
708 case 0x2:
709 return new LDRXL64_LIT(machInst, rt, imm);
710 case 0x3:
711 return new LDRDFP64_LIT(machInst, rt, imm);
712 case 0x4:
713 return new LDRSWL64_LIT(machInst, rt, imm);
714 case 0x5:
715 return new BigFpMemLit("ldr", machInst, rt, imm);
716 case 0x6:
717 return new PRFM64_LIT(machInst, rt, imm);
718 default:
719 return new Unknown64(machInst);
720 }
721 }
722 case 0x2:
723 {
724 uint8_t opc = bits(machInst, 31, 30);
725 if (opc >= 3)
726 return new Unknown64(machInst);
727 uint32_t size = 0;
728 bool fp = bits(machInst, 26);
729 bool load = bits(machInst, 22);
730 if (fp) {
731 size = 4 << opc;
732 } else {
733 if ((opc == 1) && !load)
734 return new Unknown64(machInst);
735 size = (opc == 0 || opc == 1) ? 4 : 8;
736 }
737 uint8_t type = bits(machInst, 24, 23);
738 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size;
739
740 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
741 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
742 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
743
744 bool noAlloc = (type == 0);
745 bool signExt = !noAlloc && !fp && opc == 1;
746 PairMemOp::AddrMode mode;
747 const char *mnemonic = NULL;
748 switch (type) {
749 case 0x0:
750 case 0x2:
751 mode = PairMemOp::AddrMd_Offset;
752 break;
753 case 0x1:
754 mode = PairMemOp::AddrMd_PostIndex;
755 break;
756 case 0x3:
757 mode = PairMemOp::AddrMd_PreIndex;
758 break;
759 default:
760 return new Unknown64(machInst);
761 }
762 if (load) {
763 if (noAlloc)
764 mnemonic = "ldnp";
765 else if (signExt)
766 mnemonic = "ldpsw";
767 else
768 mnemonic = "ldp";
769 } else {
770 if (noAlloc)
771 mnemonic = "stnp";
772 else
773 mnemonic = "stp";
774 }
775
776 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc,
777 signExt, false, false, imm, mode, rn, rt, rt2);
778 }
779 // bit 29:27=111, 25=0
780 case 0x3:
781 {
782 uint8_t switchVal = (bits(machInst, 23, 22) << 0) |
783 (bits(machInst, 26) << 2) |
784 (bits(machInst, 31, 30) << 3);
785 if (bits(machInst, 24) == 1) {
786 uint64_t imm12 = bits(machInst, 21, 10);
787 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
788 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
789 IntRegIndex rnsp = makeSP(rn);
790 switch (switchVal) {
791 case 0x00:
792 return new STRB64_IMM(machInst, rt, rnsp, imm12);
793 case 0x01:
794 return new LDRB64_IMM(machInst, rt, rnsp, imm12);
795 case 0x02:
796 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12);
797 case 0x03:
798 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12);
799 case 0x04:
800 return new STRBFP64_IMM(machInst, rt, rnsp, imm12);
801 case 0x05:
802 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12);
803 case 0x06:
804 return new BigFpMemImm("str", machInst, false,
805 rt, rnsp, imm12 << 4);
806 case 0x07:
807 return new BigFpMemImm("ldr", machInst, true,
808 rt, rnsp, imm12 << 4);
809 case 0x08:
810 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1);
811 case 0x09:
812 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1);
813 case 0x0a:
814 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1);
815 case 0x0b:
816 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1);
817 case 0x0c:
818 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
819 case 0x0d:
820 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
821 case 0x10:
822 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2);
823 case 0x11:
824 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2);
825 case 0x12:
826 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2);
827 case 0x14:
828 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
829 case 0x15:
830 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
831 case 0x18:
832 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3);
833 case 0x19:
834 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3);
835 case 0x1a:
836 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3);
837 case 0x1c:
838 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
839 case 0x1d:
840 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
841 default:
842 return new Unknown64(machInst);
843 }
844 } else if (bits(machInst, 21) == 1) {
845 uint8_t group = bits(machInst, 11, 10);
846 switch (group) {
847 case 0x0:
848 {
849 if ((switchVal & 0x7) == 0x2 &&
850 bits(machInst, 20, 12) == 0x1fc) {
851 IntRegIndex rt = (IntRegIndex)(uint32_t)
852 bits(machInst, 4, 0);
853 IntRegIndex rn = (IntRegIndex)(uint32_t)
854 bits(machInst, 9, 5);
855 IntRegIndex rnsp = makeSP(rn);
856 uint8_t size = bits(machInst, 31, 30);
857 switch (size) {
858 case 0x0:
859 return new LDAPRB64(machInst, rt, rnsp);
860 case 0x1:
861 return new LDAPRH64(machInst, rt, rnsp);
862 case 0x2:
863 return new LDAPRW64(machInst, rt, rnsp);
864 case 0x3:
865 return new LDAPRX64(machInst, rt, rnsp);
866 default:
867 M5_UNREACHABLE;
868 }
869 } else {
870 return new Unknown64(machInst);
871 }
872 }
873 case 0x2:
874 {
875 if (!bits(machInst, 14))
876 return new Unknown64(machInst);
877 IntRegIndex rt = (IntRegIndex)(uint32_t)
878 bits(machInst, 4, 0);
879 IntRegIndex rn = (IntRegIndex)(uint32_t)
880 bits(machInst, 9, 5);
881 IntRegIndex rnsp = makeSP(rn);
882 IntRegIndex rm = (IntRegIndex)(uint32_t)
883 bits(machInst, 20, 16);
884 ArmExtendType type =
885 (ArmExtendType)(uint32_t)bits(machInst, 15, 13);
886 uint8_t s = bits(machInst, 12);
887 switch (switchVal) {
888 case 0x00:
889 return new STRB64_REG(machInst, rt, rnsp, rm,
890 type, 0);
891 case 0x01:
892 return new LDRB64_REG(machInst, rt, rnsp, rm,
893 type, 0);
894 case 0x02:
895 return new LDRSBX64_REG(machInst, rt, rnsp, rm,
896 type, 0);
897 case 0x03:
898 return new LDRSBW64_REG(machInst, rt, rnsp, rm,
899 type, 0);
900 case 0x04:
901 return new STRBFP64_REG(machInst, rt, rnsp, rm,
902 type, 0);
903 case 0x05:
904 return new LDRBFP64_REG(machInst, rt, rnsp, rm,
905 type, 0);
906 case 0x6:
907 return new BigFpMemReg("str", machInst, false,
908 rt, rnsp, rm, type, s * 4);
909 case 0x7:
910 return new BigFpMemReg("ldr", machInst, true,
911 rt, rnsp, rm, type, s * 4);
912 case 0x08:
913 return new STRH64_REG(machInst, rt, rnsp, rm,
914 type, s);
915 case 0x09:
916 return new LDRH64_REG(machInst, rt, rnsp, rm,
917 type, s);
918 case 0x0a:
919 return new LDRSHX64_REG(machInst, rt, rnsp, rm,
920 type, s);
921 case 0x0b:
922 return new LDRSHW64_REG(machInst, rt, rnsp, rm,
923 type, s);
924 case 0x0c:
925 return new STRHFP64_REG(machInst, rt, rnsp, rm,
926 type, s);
927 case 0x0d:
928 return new LDRHFP64_REG(machInst, rt, rnsp, rm,
929 type, s);
930 case 0x10:
931 return new STRW64_REG(machInst, rt, rnsp, rm,
932 type, s * 2);
933 case 0x11:
934 return new LDRW64_REG(machInst, rt, rnsp, rm,
935 type, s * 2);
936 case 0x12:
937 return new LDRSW64_REG(machInst, rt, rnsp, rm,
938 type, s * 2);
939 case 0x14:
940 return new STRSFP64_REG(machInst, rt, rnsp, rm,
941 type, s * 2);
942 case 0x15:
943 return new LDRSFP64_REG(machInst, rt, rnsp, rm,
944 type, s * 2);
945 case 0x18:
946 return new STRX64_REG(machInst, rt, rnsp, rm,
947 type, s * 3);
948 case 0x19:
949 return new LDRX64_REG(machInst, rt, rnsp, rm,
950 type, s * 3);
951 case 0x1a:
952 return new PRFM64_REG(machInst, rt, rnsp, rm,
953 type, s * 3);
954 case 0x1c:
955 return new STRDFP64_REG(machInst, rt, rnsp, rm,
956 type, s * 3);
957 case 0x1d:
958 return new LDRDFP64_REG(machInst, rt, rnsp, rm,
959 type, s * 3);
960 default:
961 return new Unknown64(machInst);
962
963 }
964 }
965 default:
966 return new Unknown64(machInst);
967 }
968 } else {
969 // bit 29:27=111, 25:24=00, 21=0
970 switch (bits(machInst, 11, 10)) {
971 case 0x0:
972 {
973 IntRegIndex rt =
974 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
975 IntRegIndex rn =
976 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
977 IntRegIndex rnsp = makeSP(rn);
978 uint64_t imm = sext<9>(bits(machInst, 20, 12));
979 switch (switchVal) {
980 case 0x00:
981 return new STURB64_IMM(machInst, rt, rnsp, imm);
982 case 0x01:
983 return new LDURB64_IMM(machInst, rt, rnsp, imm);
984 case 0x02:
985 return new LDURSBX64_IMM(machInst, rt, rnsp, imm);
986 case 0x03:
987 return new LDURSBW64_IMM(machInst, rt, rnsp, imm);
988 case 0x04:
989 return new STURBFP64_IMM(machInst, rt, rnsp, imm);
990 case 0x05:
991 return new LDURBFP64_IMM(machInst, rt, rnsp, imm);
992 case 0x06:
993 return new BigFpMemImm("stur", machInst, false,
994 rt, rnsp, imm);
995 case 0x07:
996 return new BigFpMemImm("ldur", machInst, true,
997 rt, rnsp, imm);
998 case 0x08:
999 return new STURH64_IMM(machInst, rt, rnsp, imm);
1000 case 0x09:
1001 return new LDURH64_IMM(machInst, rt, rnsp, imm);
1002 case 0x0a:
1003 return new LDURSHX64_IMM(machInst, rt, rnsp, imm);
1004 case 0x0b:
1005 return new LDURSHW64_IMM(machInst, rt, rnsp, imm);
1006 case 0x0c:
1007 return new STURHFP64_IMM(machInst, rt, rnsp, imm);
1008 case 0x0d:
1009 return new LDURHFP64_IMM(machInst, rt, rnsp, imm);
1010 case 0x10:
1011 return new STURW64_IMM(machInst, rt, rnsp, imm);
1012 case 0x11:
1013 return new LDURW64_IMM(machInst, rt, rnsp, imm);
1014 case 0x12:
1015 return new LDURSW64_IMM(machInst, rt, rnsp, imm);
1016 case 0x14:
1017 return new STURSFP64_IMM(machInst, rt, rnsp, imm);
1018 case 0x15:
1019 return new LDURSFP64_IMM(machInst, rt, rnsp, imm);
1020 case 0x18:
1021 return new STURX64_IMM(machInst, rt, rnsp, imm);
1022 case 0x19:
1023 return new LDURX64_IMM(machInst, rt, rnsp, imm);
1024 case 0x1a:
1025 return new PRFUM64_IMM(machInst, rt, rnsp, imm);
1026 case 0x1c:
1027 return new STURDFP64_IMM(machInst, rt, rnsp, imm);
1028 case 0x1d:
1029 return new LDURDFP64_IMM(machInst, rt, rnsp, imm);
1030 default:
1031 return new Unknown64(machInst);
1032 }
1033 }
1034 // bit 29:27=111, 25:24=00, 21=0, 11:10=01
1035 case 0x1:
1036 {
1037 IntRegIndex rt =
1038 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1039 IntRegIndex rn =
1040 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1041 IntRegIndex rnsp = makeSP(rn);
1042 uint64_t imm = sext<9>(bits(machInst, 20, 12));
1043 switch (switchVal) {
1044 case 0x00:
1045 return new STRB64_POST(machInst, rt, rnsp, imm);
1046 case 0x01:
1047 return new LDRB64_POST(machInst, rt, rnsp, imm);
1048 case 0x02:
1049 return new LDRSBX64_POST(machInst, rt, rnsp, imm);
1050 case 0x03:
1051 return new LDRSBW64_POST(machInst, rt, rnsp, imm);
1052 case 0x04:
1053 return new STRBFP64_POST(machInst, rt, rnsp, imm);
1054 case 0x05:
1055 return new LDRBFP64_POST(machInst, rt, rnsp, imm);
1056 case 0x06:
1057 return new BigFpMemPost("str", machInst, false,
1058 rt, rnsp, imm);
1059 case 0x07:
1060 return new BigFpMemPost("ldr", machInst, true,
1061 rt, rnsp, imm);
1062 case 0x08:
1063 return new STRH64_POST(machInst, rt, rnsp, imm);
1064 case 0x09:
1065 return new LDRH64_POST(machInst, rt, rnsp, imm);
1066 case 0x0a:
1067 return new LDRSHX64_POST(machInst, rt, rnsp, imm);
1068 case 0x0b:
1069 return new LDRSHW64_POST(machInst, rt, rnsp, imm);
1070 case 0x0c:
1071 return new STRHFP64_POST(machInst, rt, rnsp, imm);
1072 case 0x0d:
1073 return new LDRHFP64_POST(machInst, rt, rnsp, imm);
1074 case 0x10:
1075 return new STRW64_POST(machInst, rt, rnsp, imm);
1076 case 0x11:
1077 return new LDRW64_POST(machInst, rt, rnsp, imm);
1078 case 0x12:
1079 return new LDRSW64_POST(machInst, rt, rnsp, imm);
1080 case 0x14:
1081 return new STRSFP64_POST(machInst, rt, rnsp, imm);
1082 case 0x15:
1083 return new LDRSFP64_POST(machInst, rt, rnsp, imm);
1084 case 0x18:
1085 return new STRX64_POST(machInst, rt, rnsp, imm);
1086 case 0x19:
1087 return new LDRX64_POST(machInst, rt, rnsp, imm);
1088 case 0x1c:
1089 return new STRDFP64_POST(machInst, rt, rnsp, imm);
1090 case 0x1d:
1091 return new LDRDFP64_POST(machInst, rt, rnsp, imm);
1092 default:
1093 return new Unknown64(machInst);
1094 }
1095 }
1096 case 0x2:
1097 {
1098 IntRegIndex rt =
1099 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1100 IntRegIndex rn =
1101 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1102 IntRegIndex rnsp = makeSP(rn);
1103 uint64_t imm = sext<9>(bits(machInst, 20, 12));
1104 switch (switchVal) {
1105 case 0x00:
1106 return new STTRB64_IMM(machInst, rt, rnsp, imm);
1107 case 0x01:
1108 return new LDTRB64_IMM(machInst, rt, rnsp, imm);
1109 case 0x02:
1110 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm);
1111 case 0x03:
1112 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm);
1113 case 0x08:
1114 return new STTRH64_IMM(machInst, rt, rnsp, imm);
1115 case 0x09:
1116 return new LDTRH64_IMM(machInst, rt, rnsp, imm);
1117 case 0x0a:
1118 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm);
1119 case 0x0b:
1120 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm);
1121 case 0x10:
1122 return new STTRW64_IMM(machInst, rt, rnsp, imm);
1123 case 0x11:
1124 return new LDTRW64_IMM(machInst, rt, rnsp, imm);
1125 case 0x12:
1126 return new LDTRSW64_IMM(machInst, rt, rnsp, imm);
1127 case 0x18:
1128 return new STTRX64_IMM(machInst, rt, rnsp, imm);
1129 case 0x19:
1130 return new LDTRX64_IMM(machInst, rt, rnsp, imm);
1131 default:
1132 return new Unknown64(machInst);
1133 }
1134 }
1135 case 0x3:
1136 {
1137 IntRegIndex rt =
1138 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1139 IntRegIndex rn =
1140 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1141 IntRegIndex rnsp = makeSP(rn);
1142 uint64_t imm = sext<9>(bits(machInst, 20, 12));
1143 switch (switchVal) {
1144 case 0x00:
1145 return new STRB64_PRE(machInst, rt, rnsp, imm);
1146 case 0x01:
1147 return new LDRB64_PRE(machInst, rt, rnsp, imm);
1148 case 0x02:
1149 return new LDRSBX64_PRE(machInst, rt, rnsp, imm);
1150 case 0x03:
1151 return new LDRSBW64_PRE(machInst, rt, rnsp, imm);
1152 case 0x04:
1153 return new STRBFP64_PRE(machInst, rt, rnsp, imm);
1154 case 0x05:
1155 return new LDRBFP64_PRE(machInst, rt, rnsp, imm);
1156 case 0x06:
1157 return new BigFpMemPre("str", machInst, false,
1158 rt, rnsp, imm);
1159 case 0x07:
1160 return new BigFpMemPre("ldr", machInst, true,
1161 rt, rnsp, imm);
1162 case 0x08:
1163 return new STRH64_PRE(machInst, rt, rnsp, imm);
1164 case 0x09:
1165 return new LDRH64_PRE(machInst, rt, rnsp, imm);
1166 case 0x0a:
1167 return new LDRSHX64_PRE(machInst, rt, rnsp, imm);
1168 case 0x0b:
1169 return new LDRSHW64_PRE(machInst, rt, rnsp, imm);
1170 case 0x0c:
1171 return new STRHFP64_PRE(machInst, rt, rnsp, imm);
1172 case 0x0d:
1173 return new LDRHFP64_PRE(machInst, rt, rnsp, imm);
1174 case 0x10:
1175 return new STRW64_PRE(machInst, rt, rnsp, imm);
1176 case 0x11:
1177 return new LDRW64_PRE(machInst, rt, rnsp, imm);
1178 case 0x12:
1179 return new LDRSW64_PRE(machInst, rt, rnsp, imm);
1180 case 0x14:
1181 return new STRSFP64_PRE(machInst, rt, rnsp, imm);
1182 case 0x15:
1183 return new LDRSFP64_PRE(machInst, rt, rnsp, imm);
1184 case 0x18:
1185 return new STRX64_PRE(machInst, rt, rnsp, imm);
1186 case 0x19:
1187 return new LDRX64_PRE(machInst, rt, rnsp, imm);
1188 case 0x1c:
1189 return new STRDFP64_PRE(machInst, rt, rnsp, imm);
1190 case 0x1d:
1191 return new LDRDFP64_PRE(machInst, rt, rnsp, imm);
1192 default:
1193 return new Unknown64(machInst);
1194 }
1195 }
1196 default:
1197 M5_UNREACHABLE;
1198 }
1199 }
1200 }
1201 default:
1202 M5_UNREACHABLE;
1203 }
1204 return new FailUnimplemented("Unhandled Case1", machInst);
1205 }
1206}
1207}};
1208
1209output decoder {{
1210namespace Aarch64
1211{
1212 StaticInstPtr
1213 decodeDataProcReg(ExtMachInst machInst)
1214 {
1215 uint8_t switchVal = (bits(machInst, 28) << 1) |
1216 (bits(machInst, 24) << 0);
1217 switch (switchVal) {
1218 case 0x0:
1219 {
1220 uint8_t switchVal = (bits(machInst, 21) << 0) |
1221 (bits(machInst, 30, 29) << 1);
1222 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1223 uint8_t imm6 = bits(machInst, 15, 10);
1224 bool sf = bits(machInst, 31);
1225 if (!sf && (imm6 & 0x20))
1226 return new Unknown64(machInst);
1227 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1228 IntRegIndex rdzr = makeZero(rd);
1229 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1230 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1231
1232 switch (switchVal) {
1233 case 0x0:
1234 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type);
1235 case 0x1:
1236 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type);
1237 case 0x2:
1238 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type);
1239 case 0x3:
1240 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type);
1241 case 0x4:
1242 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type);
1243 case 0x5:
1244 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type);
1245 case 0x6:
1246 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1247 case 0x7:
1248 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1249 default:
1250 M5_UNREACHABLE;
1251 }
1252 }
1253 case 0x1:
1254 {
1255 uint8_t switchVal = bits(machInst, 30, 29);
1256 if (bits(machInst, 21) == 0) {
1257 ArmShiftType type =
1258 (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1259 if (type == ROR)
1260 return new Unknown64(machInst);
1261 uint8_t imm6 = bits(machInst, 15, 10);
1262 if (!bits(machInst, 31) && bits(imm6, 5))
1263 return new Unknown64(machInst);
1264 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1265 IntRegIndex rdzr = makeZero(rd);
1266 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1267 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1268 switch (switchVal) {
1269 case 0x0:
1270 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type);
1271 case 0x1:
1272 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1273 case 0x2:
1274 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type);
1275 case 0x3:
1276 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1277 default:
1278 M5_UNREACHABLE;
1279 }
1280 } else {
1281 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4)
1282 return new Unknown64(machInst);
1283 ArmExtendType type =
1284 (ArmExtendType)(uint8_t)bits(machInst, 15, 13);
1285 uint8_t imm3 = bits(machInst, 12, 10);
1286 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1287 IntRegIndex rdsp = makeSP(rd);
1288 IntRegIndex rdzr = makeZero(rd);
1289 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1290 IntRegIndex rnsp = makeSP(rn);
1291 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1292
1293 switch (switchVal) {
1294 case 0x0:
1295 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1296 case 0x1:
1297 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1298 case 0x2:
1299 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1300 case 0x3:
1301 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1302 default:
1303 M5_UNREACHABLE;
1304 }
1305 }
1306 }
1307 case 0x2:
1308 {
1309 if (bits(machInst, 21) == 1)
1310 return new Unknown64(machInst);
1311 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1312 IntRegIndex rdzr = makeZero(rd);
1313 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1314 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1315 switch (bits(machInst, 23, 22)) {
1316 case 0x0:
1317 {
1318 if (bits(machInst, 15, 10))
1319 return new Unknown64(machInst);
1320 uint8_t switchVal = bits(machInst, 30, 29);
1321 switch (switchVal) {
1322 case 0x0:
1323 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1324 case 0x1:
1325 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1326 case 0x2:
1327 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1328 case 0x3:
1329 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1330 default:
1331 M5_UNREACHABLE;
1332 }
1333 }
1334 case 0x1:
1335 {
1336 if ((bits(machInst, 4) == 1) ||
1337 (bits(machInst, 10) == 1) ||
1338 (bits(machInst, 29) == 0)) {
1339 return new Unknown64(machInst);
1340 }
1341 ConditionCode cond =
1342 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1343 uint8_t flags = bits(machInst, 3, 0);
1344 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1345 if (bits(machInst, 11) == 0) {
1346 IntRegIndex rm =
1347 (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1348 if (bits(machInst, 30) == 0) {
1349 return new CcmnReg64(machInst, rn, rm, cond, flags);
1350 } else {
1351 return new CcmpReg64(machInst, rn, rm, cond, flags);
1352 }
1353 } else {
1354 uint8_t imm5 = bits(machInst, 20, 16);
1355 if (bits(machInst, 30) == 0) {
1356 return new CcmnImm64(machInst, rn, imm5, cond, flags);
1357 } else {
1358 return new CcmpImm64(machInst, rn, imm5, cond, flags);
1359 }
1360 }
1361 }
1362 case 0x2:
1363 {
1364 if (bits(machInst, 29) == 1 ||
1365 bits(machInst, 11) == 1) {
1366 return new Unknown64(machInst);
1367 }
1368 uint8_t switchVal = (bits(machInst, 10) << 0) |
1369 (bits(machInst, 30) << 1);
1370 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1371 IntRegIndex rdzr = makeZero(rd);
1372 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1373 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1374 ConditionCode cond =
1375 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1376 switch (switchVal) {
1377 case 0x0:
1378 return new Csel64(machInst, rdzr, rn, rm, cond);
1379 case 0x1:
1380 return new Csinc64(machInst, rdzr, rn, rm, cond);
1381 case 0x2:
1382 return new Csinv64(machInst, rdzr, rn, rm, cond);
1383 case 0x3:
1384 return new Csneg64(machInst, rdzr, rn, rm, cond);
1385 default:
1386 M5_UNREACHABLE;
1387 }
1388 }
1389 case 0x3:
1390 if (bits(machInst, 30) == 0) {
1391 if (bits(machInst, 29) != 0)
1392 return new Unknown64(machInst);
1393 uint8_t switchVal = bits(machInst, 15, 10);
1394 switch (switchVal) {
1395 case 0x2:
1396 return new Udiv64(machInst, rdzr, rn, rm);
1397 case 0x3:
1398 return new Sdiv64(machInst, rdzr, rn, rm);
1399 case 0x8:
1400 return new Lslv64(machInst, rdzr, rn, rm);
1401 case 0x9:
1402 return new Lsrv64(machInst, rdzr, rn, rm);
1403 case 0xa:
1404 return new Asrv64(machInst, rdzr, rn, rm);
1405 case 0xb:
1406 return new Rorv64(machInst, rdzr, rn, rm);
1407 case 0x10:
1408 return new Crc32b64(machInst, rdzr, rn, rm);
1409 case 0x11:
1410 return new Crc32h64(machInst, rdzr, rn, rm);
1411 case 0x12:
1412 return new Crc32w64(machInst, rdzr, rn, rm);
1413 case 0x13:
1414 return new Crc32x64(machInst, rdzr, rn, rm);
1415 case 0x14:
1416 return new Crc32cb64(machInst, rdzr, rn, rm);
1417 case 0x15:
1418 return new Crc32ch64(machInst, rdzr, rn, rm);
1419 case 0x16:
1420 return new Crc32cw64(machInst, rdzr, rn, rm);
1421 case 0x17:
1422 return new Crc32cx64(machInst, rdzr, rn, rm);
1423 default:
1424 return new Unknown64(machInst);
1425 }
1426 } else {
1427 if (bits(machInst, 20, 16) != 0 ||
1428 bits(machInst, 29) != 0) {
1429 return new Unknown64(machInst);
1430 }
1431 uint8_t switchVal = bits(machInst, 15, 10);
1432 switch (switchVal) {
1433 case 0x0:
1434 return new Rbit64(machInst, rdzr, rn);
1435 case 0x1:
1436 return new Rev1664(machInst, rdzr, rn);
1437 case 0x2:
1438 if (bits(machInst, 31) == 0)
1439 return new Rev64(machInst, rdzr, rn);
1440 else
1441 return new Rev3264(machInst, rdzr, rn);
1442 case 0x3:
1443 if (bits(machInst, 31) != 1)
1444 return new Unknown64(machInst);
1445 return new Rev64(machInst, rdzr, rn);
1446 case 0x4:
1447 return new Clz64(machInst, rdzr, rn);
1448 case 0x5:
1449 return new Cls64(machInst, rdzr, rn);
1450 default:
1451 return new Unknown64(machInst);
1452 }
1453 }
1454 default:
1455 M5_UNREACHABLE;
1456 }
1457 }
1458 case 0x3:
1459 {
1460 if (bits(machInst, 30, 29) != 0x0 ||
1461 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0))
1462 return new Unknown64(machInst);
1463 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1464 IntRegIndex rdzr = makeZero(rd);
1465 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1466 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1467 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1468 switch (bits(machInst, 23, 21)) {
1469 case 0x0:
1470 if (bits(machInst, 15) == 0)
1471 return new Madd64(machInst, rdzr, ra, rn, rm);
1472 else
1473 return new Msub64(machInst, rdzr, ra, rn, rm);
1474 case 0x1:
1475 if (bits(machInst, 15) == 0)
1476 return new Smaddl64(machInst, rdzr, ra, rn, rm);
1477 else
1478 return new Smsubl64(machInst, rdzr, ra, rn, rm);
1479 case 0x2:
1480 if (bits(machInst, 15) != 0)
1481 return new Unknown64(machInst);
1482 return new Smulh64(machInst, rdzr, rn, rm);
1483 case 0x5:
1484 if (bits(machInst, 15) == 0)
1485 return new Umaddl64(machInst, rdzr, ra, rn, rm);
1486 else
1487 return new Umsubl64(machInst, rdzr, ra, rn, rm);
1488 case 0x6:
1489 if (bits(machInst, 15) != 0)
1490 return new Unknown64(machInst);
1491 return new Umulh64(machInst, rdzr, rn, rm);
1492 default:
1493 return new Unknown64(machInst);
1494 }
1495 }
1496 default:
1497 M5_UNREACHABLE;
1498 }
1499 return new FailUnimplemented("Unhandled Case2", machInst);
1500 }
1501}
1502}};
1503
1504output decoder {{
1505namespace Aarch64
1506{
1507 template <typename DecoderFeatures>
1508 StaticInstPtr
1509 decodeAdvSIMD(ExtMachInst machInst)
1510 {
1511 if (bits(machInst, 24) == 1) {
1512 if (bits(machInst, 10) == 0) {
1513 return decodeNeonIndexedElem<DecoderFeatures>(machInst);
1514 } else if (bits(machInst, 23) == 1) {
1515 return new Unknown64(machInst);
1516 } else {
1517 if (bits(machInst, 22, 19)) {
1518 return decodeNeonShiftByImm(machInst);
1519 } else {
1520 return decodeNeonModImm(machInst);
1521 }
1522 }
1523 } else if (bits(machInst, 21) == 1) {
1524 if (bits(machInst, 10) == 1) {
1525 return decodeNeon3Same<DecoderFeatures>(machInst);
1526 } else if (bits(machInst, 11) == 0) {
1527 return decodeNeon3Diff(machInst);
1528 } else if (bits(machInst, 20, 17) == 0x0) {
1529 return decodeNeon2RegMisc(machInst);
1530 } else if (bits(machInst, 20, 17) == 0x4) {
1531 return decodeCryptoAES(machInst);
1532 } else if (bits(machInst, 20, 17) == 0x8) {
1533 return decodeNeonAcrossLanes(machInst);
1534 } else {
1535 return new Unknown64(machInst);
1536 }
1537 } else if (bits(machInst, 24) ||
1538 bits(machInst, 21) ||
1539 bits(machInst, 15)) {
1540 return new Unknown64(machInst);
1541 } else if (bits(machInst, 10) == 1) {
1542 if (bits(machInst, 23, 22))
1543 return new Unknown64(machInst);
1544 return decodeNeonCopy(machInst);
1545 } else if (bits(machInst, 29) == 1) {
1546 return decodeNeonExt(machInst);
1547 } else if (bits(machInst, 11) == 1) {
1548 return decodeNeonZipUzpTrn(machInst);
1549 } else if (bits(machInst, 23, 22) == 0x0) {
1550 return decodeNeonTblTbx(machInst);
1551 } else {
1552 return new Unknown64(machInst);
1553 }
1554 return new FailUnimplemented("Unhandled Case3", machInst);
1555 }
1556}
1557}};
1558
1559
1560output decoder {{
1561namespace Aarch64
1562{
1563 StaticInstPtr
1564 // bit 30=0, 28:25=1111
1565 decodeFp(ExtMachInst machInst)
1566 {
1567 if (bits(machInst, 24) == 1) {
1568 if (bits(machInst, 31) || bits(machInst, 29))
1569 return new Unknown64(machInst);
1570 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1571 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1572 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1573 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10);
1574 uint8_t switchVal = (bits(machInst, 23, 21) << 1) |
1575 (bits(machInst, 15) << 0);
1576 switch (switchVal) {
1577 case 0x0: // FMADD Sd = Sa + Sn*Sm
1578 return new FMAddS(machInst, rd, rn, rm, ra);
1579 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm
1580 return new FMSubS(machInst, rd, rn, rm, ra);
1581 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm
1582 return new FNMAddS(machInst, rd, rn, rm, ra);
1583 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm
1584 return new FNMSubS(machInst, rd, rn, rm, ra);
1585 case 0x4: // FMADD Dd = Da + Dn*Dm
1586 return new FMAddD(machInst, rd, rn, rm, ra);
1587 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm
1588 return new FMSubD(machInst, rd, rn, rm, ra);
1589 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm
1590 return new FNMAddD(machInst, rd, rn, rm, ra);
1591 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm
1592 return new FNMSubD(machInst, rd, rn, rm, ra);
1593 default:
1594 return new Unknown64(machInst);
1595 }
1596 } else if (bits(machInst, 21) == 0) {
1597 bool s = bits(machInst, 29);
1598 if (s)
1599 return new Unknown64(machInst);
1600 uint8_t switchVal = bits(machInst, 20, 16);
1601 uint8_t type = bits(machInst, 23, 22);
1602 uint8_t scale = bits(machInst, 15, 10);
1603 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1604 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1605 if (bits(machInst, 18, 17) == 3 && scale != 0)
1606 return new Unknown64(machInst);
1607 // 30:24=0011110, 21=0
1608 switch (switchVal) {
1609 case 0x00:
1610 return new FailUnimplemented("fcvtns", machInst);
1611 case 0x01:
1612 return new FailUnimplemented("fcvtnu", machInst);
1613 case 0x02:
1614 switch ( (bits(machInst, 31) << 2) | type ) {
1615 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits))
1616 return new FcvtSFixedFpSW(machInst, rd, rn, scale);
1617 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits))
1618 return new FcvtSFixedFpDW(machInst, rd, rn, scale);
1619 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits))
1620 return new FcvtSFixedFpSX(machInst, rd, rn, scale);
1621 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits))
1622 return new FcvtSFixedFpDX(machInst, rd, rn, scale);
1623 default:
1624 return new Unknown64(machInst);
1625 }
1626 case 0x03:
1627 switch ( (bits(machInst, 31) << 2) | type ) {
1628 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits))
1629 return new FcvtUFixedFpSW(machInst, rd, rn, scale);
1630 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits))
1631 return new FcvtUFixedFpDW(machInst, rd, rn, scale);
1632 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits))
1633 return new FcvtUFixedFpSX(machInst, rd, rn, scale);
1634 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits))
1635 return new FcvtUFixedFpDX(machInst, rd, rn, scale);
1636 default:
1637 return new Unknown64(machInst);
1638 }
1639 case 0x04:
1640 return new FailUnimplemented("fcvtas", machInst);
1641 case 0x05:
1642 return new FailUnimplemented("fcvtau", machInst);
1643 case 0x08:
1644 return new FailUnimplemented("fcvtps", machInst);
1645 case 0x09:
1646 return new FailUnimplemented("fcvtpu", machInst);
1647 case 0x0e:
1648 return new FailUnimplemented("fmov elem. to 64", machInst);
1649 case 0x0f:
1650 return new FailUnimplemented("fmov 64 bit", machInst);
1651 case 0x10:
1652 return new FailUnimplemented("fcvtms", machInst);
1653 case 0x11:
1654 return new FailUnimplemented("fcvtmu", machInst);
1655 case 0x18:
1656 switch ( (bits(machInst, 31) << 2) | type ) {
1657 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1658 return new FcvtFpSFixedSW(machInst, rd, rn, scale);
1659 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1660 return new FcvtFpSFixedDW(machInst, rd, rn, scale);
1661 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1662 return new FcvtFpSFixedSX(machInst, rd, rn, scale);
1663 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1664 return new FcvtFpSFixedDX(machInst, rd, rn, scale);
1665 default:
1666 return new Unknown64(machInst);
1667 }
1668 case 0x19:
1669 switch ( (bits(machInst, 31) << 2) | type ) {
1670 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1671 return new FcvtFpUFixedSW(machInst, rd, rn, scale);
1672 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1673 return new FcvtFpUFixedDW(machInst, rd, rn, scale);
1674 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1675 return new FcvtFpUFixedSX(machInst, rd, rn, scale);
1676 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1677 return new FcvtFpUFixedDX(machInst, rd, rn, scale);
1678 default:
1679 return new Unknown64(machInst);
1680 }
1681 default:
1682 return new Unknown64(machInst);
1683 }
1684 } else {
1685 // 30=0, 28:24=11110, 21=1
1686 uint8_t type = bits(machInst, 23, 22);
1687 uint8_t imm8 = bits(machInst, 20, 13);
1688 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1689 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1690 switch (bits(machInst, 11, 10)) {
1691 case 0x0:
1692 if (bits(machInst, 12) == 1) {
1693 if (bits(machInst, 31) ||
1694 bits(machInst, 29) ||
1695 bits(machInst, 9, 5)) {
1696 return new Unknown64(machInst);
1697 }
1698 // 31:29=000, 28:24=11110, 21=1, 12:10=100
1699 if (type == 0) {
1700 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5)
1701 // :imm8<5:0>:Zeros(19)
1702 uint32_t imm = vfp_modified_imm(imm8,
1703 FpDataType::Fp32);
1704 return new FmovImmS(machInst, rd, imm);
1705 } else if (type == 1) {
1706 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8)
1707 // :imm8<5:0>:Zeros(48)
1708 uint64_t imm = vfp_modified_imm(imm8,
1709 FpDataType::Fp64);
1710 return new FmovImmD(machInst, rd, imm);
1711 } else {
1712 return new Unknown64(machInst);
1713 }
1714 } else if (bits(machInst, 13) == 1) {
1715 if (bits(machInst, 31) ||
1716 bits(machInst, 29) ||
1717 bits(machInst, 15, 14) ||
1718 bits(machInst, 23) ||
1719 bits(machInst, 2, 0)) {
1720 return new Unknown64(machInst);
1721 }
1722 uint8_t switchVal = (bits(machInst, 4, 3) << 0) |
1723 (bits(machInst, 22) << 2);
1724 IntRegIndex rm = (IntRegIndex)(uint32_t)
1725 bits(machInst, 20, 16);
1726 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000
1727 switch (switchVal) {
1728 case 0x0:
1729 // FCMP flags = compareQuiet(Sn,Sm)
1730 return new FCmpRegS(machInst, rn, rm);
1731 case 0x1:
1732 // FCMP flags = compareQuiet(Sn,0.0)
1733 return new FCmpImmS(machInst, rn, 0);
1734 case 0x2:
1735 // FCMPE flags = compareSignaling(Sn,Sm)
1736 return new FCmpERegS(machInst, rn, rm);
1737 case 0x3:
1738 // FCMPE flags = compareSignaling(Sn,0.0)
1739 return new FCmpEImmS(machInst, rn, 0);
1740 case 0x4:
1741 // FCMP flags = compareQuiet(Dn,Dm)
1742 return new FCmpRegD(machInst, rn, rm);
1743 case 0x5:
1744 // FCMP flags = compareQuiet(Dn,0.0)
1745 return new FCmpImmD(machInst, rn, 0);
1746 case 0x6:
1747 // FCMPE flags = compareSignaling(Dn,Dm)
1748 return new FCmpERegD(machInst, rn, rm);
1749 case 0x7:
1750 // FCMPE flags = compareSignaling(Dn,0.0)
1751 return new FCmpEImmD(machInst, rn, 0);
1752 default:
1753 return new Unknown64(machInst);
1754 }
1755 } else if (bits(machInst, 14) == 1) {
1756 if (bits(machInst, 31) || bits(machInst, 29))
1757 return new Unknown64(machInst);
1758 uint8_t opcode = bits(machInst, 20, 15);
1759 // Bits 31:24=00011110, 21=1, 14:10=10000
1760 switch (opcode) {
1761 case 0x0:
1762 if (type == 0)
1763 // FMOV Sd = Sn
1764 return new FmovRegS(machInst, rd, rn);
1765 else if (type == 1)
1766 // FMOV Dd = Dn
1767 return new FmovRegD(machInst, rd, rn);
1768 break;
1769 case 0x1:
1770 if (type == 0)
1771 // FABS Sd = abs(Sn)
1772 return new FAbsS(machInst, rd, rn);
1773 else if (type == 1)
1774 // FABS Dd = abs(Dn)
1775 return new FAbsD(machInst, rd, rn);
1776 break;
1777 case 0x2:
1778 if (type == 0)
1779 // FNEG Sd = -Sn
1780 return new FNegS(machInst, rd, rn);
1781 else if (type == 1)
1782 // FNEG Dd = -Dn
1783 return new FNegD(machInst, rd, rn);
1784 break;
1785 case 0x3:
1786 if (type == 0)
1787 // FSQRT Sd = sqrt(Sn)
1788 return new FSqrtS(machInst, rd, rn);
1789 else if (type == 1)
1790 // FSQRT Dd = sqrt(Dn)
1791 return new FSqrtD(machInst, rd, rn);
1792 break;
1793 case 0x4:
1794 if (type == 1)
1795 // FCVT Sd = convertFormat(Dn)
1796 return new FcvtFpDFpS(machInst, rd, rn);
1797 else if (type == 3)
1798 // FCVT Sd = convertFormat(Hn)
1799 return new FcvtFpHFpS(machInst, rd, rn);
1800 break;
1801 case 0x5:
1802 if (type == 0)
1803 // FCVT Dd = convertFormat(Sn)
1804 return new FCvtFpSFpD(machInst, rd, rn);
1805 else if (type == 3)
1806 // FCVT Dd = convertFormat(Hn)
1807 return new FcvtFpHFpD(machInst, rd, rn);
1808 break;
1809 case 0x7:
1810 if (type == 0)
1811 // FCVT Hd = convertFormat(Sn)
1812 return new FcvtFpSFpH(machInst, rd, rn);
1813 else if (type == 1)
1814 // FCVT Hd = convertFormat(Dn)
1815 return new FcvtFpDFpH(machInst, rd, rn);
1816 break;
1817 case 0x8:
1818 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn)
1819 return new FRIntNS(machInst, rd, rn);
1820 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn)
1821 return new FRIntND(machInst, rd, rn);
1822 break;
1823 case 0x9:
1824 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn)
1825 return new FRIntPS(machInst, rd, rn);
1826 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn)
1827 return new FRIntPD(machInst, rd, rn);
1828 break;
1829 case 0xa:
1830 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn)
1831 return new FRIntMS(machInst, rd, rn);
1832 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn)
1833 return new FRIntMD(machInst, rd, rn);
1834 break;
1835 case 0xb:
1836 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn)
1837 return new FRIntZS(machInst, rd, rn);
1838 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn)
1839 return new FRIntZD(machInst, rd, rn);
1840 break;
1841 case 0xc:
1842 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn)
1843 return new FRIntAS(machInst, rd, rn);
1844 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn)
1845 return new FRIntAD(machInst, rd, rn);
1846 break;
1847 case 0xe:
1848 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn)
1849 return new FRIntXS(machInst, rd, rn);
1850 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn)
1851 return new FRIntXD(machInst, rd, rn);
1852 break;
1853 case 0xf:
1854 if (type == 0) // FRINTI Sd = roundToIntegral(Sn)
1855 return new FRIntIS(machInst, rd, rn);
1856 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn)
1857 return new FRIntID(machInst, rd, rn);
1858 break;
1859 default:
1860 return new Unknown64(machInst);
1861 }
1862 return new Unknown64(machInst);
1863 } else if (bits(machInst, 15) == 1) {
1864 return new Unknown64(machInst);
1865 } else {
1866 if (bits(machInst, 29))
1867 return new Unknown64(machInst);
1868 uint8_t rmode = bits(machInst, 20, 19);
1869 uint8_t switchVal1 = bits(machInst, 18, 16);
1870 uint8_t switchVal2 = (type << 1) | bits(machInst, 31);
1871 // 30:24=0011110, 21=1, 15:10=000000
1872 switch (switchVal1) {
1873 case 0x0:
1874 switch ((switchVal2 << 2) | rmode) {
1875 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn)
1876 return new FcvtFpSIntWSN(machInst, rd, rn);
1877 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn)
1878 return new FcvtFpSIntWSP(machInst, rd, rn);
1879 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn)
1880 return new FcvtFpSIntWSM(machInst, rd, rn);
1881 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn)
1882 return new FcvtFpSIntWSZ(machInst, rd, rn);
1883 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn)
1884 return new FcvtFpSIntXSN(machInst, rd, rn);
1885 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn)
1886 return new FcvtFpSIntXSP(machInst, rd, rn);
1887 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn)
1888 return new FcvtFpSIntXSM(machInst, rd, rn);
1889 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn)
1890 return new FcvtFpSIntXSZ(machInst, rd, rn);
1891 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn)
1892 return new FcvtFpSIntWDN(machInst, rd, rn);
1893 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn)
1894 return new FcvtFpSIntWDP(machInst, rd, rn);
1895 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn)
1896 return new FcvtFpSIntWDM(machInst, rd, rn);
1897 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn)
1898 return new FcvtFpSIntWDZ(machInst, rd, rn);
1899 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn)
1900 return new FcvtFpSIntXDN(machInst, rd, rn);
1901 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn)
1902 return new FcvtFpSIntXDP(machInst, rd, rn);
1903 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn)
1904 return new FcvtFpSIntXDM(machInst, rd, rn);
1905 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn)
1906 return new FcvtFpSIntXDZ(machInst, rd, rn);
1907 default:
1908 return new Unknown64(machInst);
1909 }
1910 case 0x1:
1911 switch ((switchVal2 << 2) | rmode) {
1912 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn)
1913 return new FcvtFpUIntWSN(machInst, rd, rn);
1914 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn)
1915 return new FcvtFpUIntWSP(machInst, rd, rn);
1916 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn)
1917 return new FcvtFpUIntWSM(machInst, rd, rn);
1918 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn)
1919 return new FcvtFpUIntWSZ(machInst, rd, rn);
1920 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn)
1921 return new FcvtFpUIntXSN(machInst, rd, rn);
1922 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn)
1923 return new FcvtFpUIntXSP(machInst, rd, rn);
1924 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn)
1925 return new FcvtFpUIntXSM(machInst, rd, rn);
1926 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn)
1927 return new FcvtFpUIntXSZ(machInst, rd, rn);
1928 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn)
1929 return new FcvtFpUIntWDN(machInst, rd, rn);
1930 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn)
1931 return new FcvtFpUIntWDP(machInst, rd, rn);
1932 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn)
1933 return new FcvtFpUIntWDM(machInst, rd, rn);
1934 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn)
1935 return new FcvtFpUIntWDZ(machInst, rd, rn);
1936 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn)
1937 return new FcvtFpUIntXDN(machInst, rd, rn);
1938 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn)
1939 return new FcvtFpUIntXDP(machInst, rd, rn);
1940 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn)
1941 return new FcvtFpUIntXDM(machInst, rd, rn);
1942 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn)
1943 return new FcvtFpUIntXDZ(machInst, rd, rn);
1944 default:
1945 return new Unknown64(machInst);
1946 }
1947 case 0x2:
1948 if (rmode != 0)
1949 return new Unknown64(machInst);
1950 switch (switchVal2) {
1951 case 0: // SCVTF Sd = convertFromInt(Wn)
1952 return new FcvtWSIntFpS(machInst, rd, rn);
1953 case 1: // SCVTF Sd = convertFromInt(Xn)
1954 return new FcvtXSIntFpS(machInst, rd, rn);
1955 case 2: // SCVTF Dd = convertFromInt(Wn)
1956 return new FcvtWSIntFpD(machInst, rd, rn);
1957 case 3: // SCVTF Dd = convertFromInt(Xn)
1958 return new FcvtXSIntFpD(machInst, rd, rn);
1959 default:
1960 return new Unknown64(machInst);
1961 }
1962 case 0x3:
1963 switch (switchVal2) {
1964 case 0: // UCVTF Sd = convertFromInt(Wn)
1965 return new FcvtWUIntFpS(machInst, rd, rn);
1966 case 1: // UCVTF Sd = convertFromInt(Xn)
1967 return new FcvtXUIntFpS(machInst, rd, rn);
1968 case 2: // UCVTF Dd = convertFromInt(Wn)
1969 return new FcvtWUIntFpD(machInst, rd, rn);
1970 case 3: // UCVTF Dd = convertFromInt(Xn)
1971 return new FcvtXUIntFpD(machInst, rd, rn);
1972 default:
1973 return new Unknown64(machInst);
1974 }
1975 case 0x4:
1976 if (rmode != 0)
1977 return new Unknown64(machInst);
1978 switch (switchVal2) {
1979 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn)
1980 return new FcvtFpSIntWSA(machInst, rd, rn);
1981 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn)
1982 return new FcvtFpSIntXSA(machInst, rd, rn);
1983 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1984 return new FcvtFpSIntWDA(machInst, rd, rn);
1985 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1986 return new FcvtFpSIntXDA(machInst, rd, rn);
1987 default:
1988 return new Unknown64(machInst);
1989 }
1990 case 0x5:
1991 switch (switchVal2) {
1992 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn)
1993 return new FcvtFpUIntWSA(machInst, rd, rn);
1994 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn)
1995 return new FcvtFpUIntXSA(machInst, rd, rn);
1996 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn)
1997 return new FcvtFpUIntWDA(machInst, rd, rn);
1998 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn)
1999 return new FcvtFpUIntXDA(machInst, rd, rn);
2000 default:
2001 return new Unknown64(machInst);
2002 }
2003 case 0x06:
2004 switch (switchVal2) {
2005 case 0: // FMOV Wd = Sn
2006 if (rmode != 0)
2007 return new Unknown64(machInst);
2008 return new FmovRegCoreW(machInst, rd, rn);
2009 case 3: // FMOV Xd = Dn
2010 if (rmode != 0)
2011 return new Unknown64(machInst);
2012 return new FmovRegCoreX(machInst, rd, rn);
2013 case 5: // FMOV Xd = Vn<127:64>
2014 if (rmode != 1)
2015 return new Unknown64(machInst);
2016 return new FmovURegCoreX(machInst, rd, rn);
2017 default:
2018 return new Unknown64(machInst);
2019 }
2020 break;
2021 case 0x07:
2022 switch (switchVal2) {
2023 case 0: // FMOV Sd = Wn
2024 if (rmode != 0)
2025 return new Unknown64(machInst);
2026 return new FmovCoreRegW(machInst, rd, rn);
2027 case 3: // FMOV Xd = Dn
2028 if (rmode != 0)
2029 return new Unknown64(machInst);
2030 return new FmovCoreRegX(machInst, rd, rn);
2031 case 5: // FMOV Xd = Vn<127:64>
2032 if (rmode != 1)
2033 return new Unknown64(machInst);
2034 return new FmovUCoreRegX(machInst, rd, rn);
2035 default:
2036 return new Unknown64(machInst);
2037 }
2038 break;
2039 default: // Warning! missing cases in switch statement above, that still need to be added
2040 return new Unknown64(machInst);
2041 }
2042 }
2043 M5_UNREACHABLE;
2044 case 0x1:
2045 {
2046 if (bits(machInst, 31) ||
2047 bits(machInst, 29) ||
2048 bits(machInst, 23)) {
2049 return new Unknown64(machInst);
2050 }
2051 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16);
2052 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5);
2053 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0);
2054 ConditionCode cond =
2055 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2056 uint8_t switchVal = (bits(machInst, 4) << 0) |
2057 (bits(machInst, 22) << 1);
2058 // 31:23=000111100, 21=1, 11:10=01
2059 switch (switchVal) {
2060 case 0x0:
2061 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv
2062 return new FCCmpRegS(machInst, rn, rm, cond, imm);
2063 case 0x1:
2064 // FCCMP flags = if cond then compareSignaling(Sn,Sm)
2065 // else #nzcv
2066 return new FCCmpERegS(machInst, rn, rm, cond, imm);
2067 case 0x2:
2068 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv
2069 return new FCCmpRegD(machInst, rn, rm, cond, imm);
2070 case 0x3:
2071 // FCCMP flags = if cond then compareSignaling(Dn,Dm)
2072 // else #nzcv
2073 return new FCCmpERegD(machInst, rn, rm, cond, imm);
2074 default:
2075 return new Unknown64(machInst);
2076 }
2077 }
2078 case 0x2:
2079 {
2080 if (bits(machInst, 31) ||
2081 bits(machInst, 29) ||
2082 bits(machInst, 23)) {
2083 return new Unknown64(machInst);
2084 }
2085 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2086 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2087 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2088 uint8_t switchVal = (bits(machInst, 15, 12) << 0) |
2089 (bits(machInst, 22) << 4);
2090 switch (switchVal) {
2091 case 0x00: // FMUL Sd = Sn * Sm
2092 return new FMulS(machInst, rd, rn, rm);
2093 case 0x10: // FMUL Dd = Dn * Dm
2094 return new FMulD(machInst, rd, rn, rm);
2095 case 0x01: // FDIV Sd = Sn / Sm
2096 return new FDivS(machInst, rd, rn, rm);
2097 case 0x11: // FDIV Dd = Dn / Dm
2098 return new FDivD(machInst, rd, rn, rm);
2099 case 0x02: // FADD Sd = Sn + Sm
2100 return new FAddS(machInst, rd, rn, rm);
2101 case 0x12: // FADD Dd = Dn + Dm
2102 return new FAddD(machInst, rd, rn, rm);
2103 case 0x03: // FSUB Sd = Sn - Sm
2104 return new FSubS(machInst, rd, rn, rm);
2105 case 0x13: // FSUB Dd = Dn - Dm
2106 return new FSubD(machInst, rd, rn, rm);
2107 case 0x04: // FMAX Sd = max(Sn, Sm)
2108 return new FMaxS(machInst, rd, rn, rm);
2109 case 0x14: // FMAX Dd = max(Dn, Dm)
2110 return new FMaxD(machInst, rd, rn, rm);
2111 case 0x05: // FMIN Sd = min(Sn, Sm)
2112 return new FMinS(machInst, rd, rn, rm);
2113 case 0x15: // FMIN Dd = min(Dn, Dm)
2114 return new FMinD(machInst, rd, rn, rm);
2115 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm)
2116 return new FMaxNMS(machInst, rd, rn, rm);
2117 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm)
2118 return new FMaxNMD(machInst, rd, rn, rm);
2119 case 0x07: // FMINNM Sd = minNum(Sn, Sm)
2120 return new FMinNMS(machInst, rd, rn, rm);
2121 case 0x17: // FMINNM Dd = minNum(Dn, Dm)
2122 return new FMinNMD(machInst, rd, rn, rm);
2123 case 0x08: // FNMUL Sd = -(Sn * Sm)
2124 return new FNMulS(machInst, rd, rn, rm);
2125 case 0x18: // FNMUL Dd = -(Dn * Dm)
2126 return new FNMulD(machInst, rd, rn, rm);
2127 default:
2128 return new Unknown64(machInst);
2129 }
2130 }
2131 case 0x3:
2132 {
2133 if (bits(machInst, 31) || bits(machInst, 29))
2134 return new Unknown64(machInst);
2135 uint8_t type = bits(machInst, 23, 22);
2136 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2137 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2138 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2139 ConditionCode cond =
2140 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2141 if (type == 0) // FCSEL Sd = if cond then Sn else Sm
2142 return new FCSelS(machInst, rd, rn, rm, cond);
2143 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm
2144 return new FCSelD(machInst, rd, rn, rm, cond);
2145 else
2146 return new Unknown64(machInst);
2147 }
2148 default:
2149 M5_UNREACHABLE;
2150 }
2151 }
2152 M5_UNREACHABLE;
2153 }
2154}
2155}};
2156
2157output decoder {{
2158namespace Aarch64
2159{
2160 StaticInstPtr
2161 decodeAdvSIMDScalar(ExtMachInst machInst)
2162 {
2163 if (bits(machInst, 24) == 1) {
2164 if (bits(machInst, 10) == 0) {
2165 return decodeNeonScIndexedElem(machInst);
2166 } else if (bits(machInst, 23) == 0) {
2167 return decodeNeonScShiftByImm(machInst);
2168 }
2169 } else if (bits(machInst, 21) == 1) {
2170 if (bits(machInst, 10) == 1) {
2171 return decodeNeonSc3Same(machInst);
2172 } else if (bits(machInst, 11) == 0) {
2173 return decodeNeonSc3Diff(machInst);
2174 } else if (bits(machInst, 20, 17) == 0x0) {
2175 return decodeNeonSc2RegMisc(machInst);
2176 } else if (bits(machInst, 20, 17) == 0x4) {
2177 return decodeCryptoTwoRegSHA(machInst);
2178 } else if (bits(machInst, 20, 17) == 0x8) {
2179 return decodeNeonScPwise(machInst);
2180 } else {
2181 return new Unknown64(machInst);
2182 }
2183 } else if (bits(machInst, 23, 22) == 0 &&
2184 bits(machInst, 15) == 0) {
2185 if (bits(machInst, 10) == 1) {
2186 return decodeNeonScCopy(machInst);
2187 } else {
2188 return decodeCryptoThreeRegSHA(machInst);
2189 }
2190 } else {
2191 return new Unknown64(machInst);
2192 }
2193 return new FailUnimplemented("Unhandled Case6", machInst);
2194 }
2195}
2196}};
2197
2198output decoder {{
2199namespace Aarch64
2200{
2201 template <typename DecoderFeatures>
2202 StaticInstPtr
2203 decodeFpAdvSIMD(ExtMachInst machInst)
2204 {
2205
2206 if (bits(machInst, 28) == 0) {
2207 if (bits(machInst, 31) == 0) {
2208 return decodeAdvSIMD<DecoderFeatures>(machInst);
2209 } else {
2210 return new Unknown64(machInst);
2211 }
2212 } else if (bits(machInst, 30) == 0) {
2213 return decodeFp(machInst);
2214 } else if (bits(machInst, 31) == 0) {
2215 return decodeAdvSIMDScalar(machInst);
2216 } else {
2217 return new Unknown64(machInst);
2218 }
2219 }
2220}
2221}};
2222
2223let {{
2224 decoder_output ='''
2225namespace Aarch64
2226{'''
2227 for decoderFlavour, type_dict in decoders.iteritems():
2228 decoder_output +='''
2229template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst);
2230''' % { "df" : decoderFlavour }
2231 decoder_output +='''
2232}'''
2233}};
2234
2235output decoder {{
2236namespace Aarch64
2237{
2238 StaticInstPtr
2239 decodeGem5Ops(ExtMachInst machInst)
2240 {
2241 const uint32_t m5func = bits(machInst, 23, 16);
2242 switch (m5func) {
2243 case M5OP_ARM: return new Arm(machInst);
2244 case M5OP_QUIESCE: return new Quiesce(machInst);
2245 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst);
2246 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst);
2247 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst);
2248 case M5OP_RPNS: return new Rpns64(machInst);
2249 case M5OP_WAKE_CPU: return new WakeCPU64(machInst);
2250 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst);
2251 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst);
2252 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst);
2253 case M5OP_EXIT: return new M5exit64(machInst);
2254 case M5OP_FAIL: return new M5fail64(machInst);
2255 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst);
2256 case M5OP_INIT_PARAM: return new Initparam64(machInst);
2257 case M5OP_RESET_STATS: return new Resetstats64(machInst);
2258 case M5OP_DUMP_STATS: return new Dumpstats64(machInst);
2259 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst);
2260 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst);
2261 case M5OP_WRITE_FILE: return new M5writefile64(machInst);
2262 case M5OP_READ_FILE: return new M5readfile64(machInst);
2263 case M5OP_DEBUG_BREAK: return new M5break(machInst);
2264 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst);
2265 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst);
2266 case M5OP_PANIC: return new M5panic(machInst);
2267 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst);
2268 case M5OP_WORK_END: return new M5workend64(machInst);
2269 default: return new Unknown64(machInst);
2270 }
2271 }
2272}
2273}};
2274
2275def format Aarch64() {{
2276 decode_block = '''
2277 {
2278 using namespace Aarch64;
2279 if (bits(machInst, 27) == 0x0) {
2280 if (bits(machInst, 28) == 0x0) {
2281 if (bits(machInst, 26, 25) != 0x2) {
2282 return new Unknown64(machInst);
2283 }
2284 if (bits(machInst, 31) == 0x0) {
2285 switch (bits(machInst, 30, 29)) {
2286 case 0x0:
2287 case 0x1:
2288 case 0x2:
2289 return decodeSveInt(machInst);
2290 case 0x3:
2291 return decodeSveFp(machInst);
2292 }
2293 } else {
2294 return decodeSveMem(machInst);
2295 }
2296 } else if (bits(machInst, 26) == 0)
2297 // bit 28:26=100
2298 return decodeDataProcImm(machInst);
2299 else
2300 // bit 28:26=101
2301 return decodeBranchExcSys(machInst);
2302 } else if (bits(machInst, 25) == 0) {
2303 // bit 27=1, 25=0
2304 return decodeLoadsStores(machInst);
2305 } else if (bits(machInst, 26) == 0) {
2306 // bit 27:25=101
2307 return decodeDataProcReg(machInst);
2308 } else if (bits(machInst, 24) == 1 &&
2309 bits(machInst, 31, 28) == 0xF) {
2310 return decodeGem5Ops(machInst);
2311 } else {
2312 // bit 27:25=111
2313 switch(decoderFlavour){
2314 default:
2315 return decodeFpAdvSIMD<GenericDecoder>(machInst);
2316 }
2317 }
2318 }
2319 '''
2320}};
399 case 0x5:
400 // SP
401 return new MsrImm64(
402 machInst, MISCREG_SPSEL, crm);
403 case 0x1e:
404 // DAIFSet
405 return new MsrImmDAIFSet64(
406 machInst, MISCREG_DAIF, crm);
407 case 0x1f:
408 // DAIFClr
409 return new MsrImmDAIFClr64(
410 machInst, MISCREG_DAIF, crm);
411 default:
412 return new Unknown64(machInst);
413 }
414 } else {
415 return new Unknown64(machInst);
416 }
417 break;
418 case 0x1:
419 case 0x2:
420 case 0x3:
421 {
422 // bit 31:22=1101010100, 20:19=11
423 bool read = l;
424 MiscRegIndex miscReg =
425 decodeAArch64SysReg(op0, op1, crn, crm, op2);
426 if (read) {
427 if ((miscReg == MISCREG_DC_CIVAC_Xt) ||
428 (miscReg == MISCREG_DC_CVAC_Xt) ||
429 (miscReg == MISCREG_DC_IVAC_Xt) ||
430 (miscReg == MISCREG_DC_ZVA_Xt)) {
431 return new Unknown64(machInst);
432 }
433 }
434 // Check for invalid registers
435 if (miscReg == MISCREG_UNKNOWN) {
436 auto full_mnemonic =
437 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d",
438 read ? "mrs" : "msr",
439 op0, op1, crn, crm, op2);
440
441 return new FailUnimplemented(read ? "mrs" : "msr",
442 machInst, full_mnemonic);
443
444 } else if (miscReg == MISCREG_IMPDEF_UNIMPL) {
445 auto full_mnemonic =
446 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d",
447 read ? "mrs" : "msr",
448 op0, op1, crn, crm, op2);
449
450 uint32_t iss = msrMrs64IssBuild(
451 read, op0, op1, crn, crm, op2, rt);
452
453 return new MiscRegImplDefined64(
454 read ? "mrs" : "msr",
455 machInst, miscReg, read, iss, full_mnemonic,
456 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]);
457
458 } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
459 if (miscReg == MISCREG_NZCV) {
460 if (read)
461 return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg);
462 else
463 return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt);
464 }
465 uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt);
466 if (read) {
467 StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss);
468 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE])
469 si->setFlag(StaticInst::IsUnverifiable);
470 return si;
471 } else {
472 switch (miscReg) {
473 case MISCREG_DC_ZVA_Xt:
474 return new Dczva(machInst, rt, miscReg, iss);
475 case MISCREG_DC_CVAU_Xt:
476 return new Dccvau(machInst, rt, miscReg, iss);
477 case MISCREG_DC_CVAC_Xt:
478 return new Dccvac(machInst, rt, miscReg, iss);
479 case MISCREG_DC_CIVAC_Xt:
480 return new Dccivac(machInst, rt, miscReg, iss);
481 case MISCREG_DC_IVAC_Xt:
482 return new Dcivac(machInst, rt, miscReg, iss);
483 default:
484 return new Msr64(machInst, miscReg, rt, iss);
485 }
486 }
487 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
488 std::string full_mnem = csprintf("%s %s",
489 read ? "mrs" : "msr", miscRegName[miscReg]);
490 return new WarnUnimplemented(read ? "mrs" : "msr",
491 machInst, full_mnem);
492 } else {
493 return new FailUnimplemented(read ? "mrs" : "msr",
494 machInst,
495 csprintf("%s %s",
496 read ? "mrs" : "msr",
497 miscRegName[miscReg]));
498 }
499 }
500 break;
501 default:
502 M5_UNREACHABLE;
503 }
504 } else if (bits(machInst, 25) == 0x1) {
505 uint8_t opc = bits(machInst, 24, 21);
506 uint8_t op2 = bits(machInst, 20, 16);
507 uint8_t op3 = bits(machInst, 15, 10);
508 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
509 uint8_t op4 = bits(machInst, 4, 0);
510 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0)
511 return new Unknown64(machInst);
512 switch (opc) {
513 case 0x0:
514 return new Br64(machInst, rn);
515 case 0x1:
516 return new Blr64(machInst, rn);
517 case 0x2:
518 return new Ret64(machInst, rn);
519 case 0x4:
520 if (rn != 0x1f)
521 return new Unknown64(machInst);
522 return new Eret64(machInst);
523 case 0x5:
524 if (rn != 0x1f)
525 return new Unknown64(machInst);
526 return new FailUnimplemented("dret", machInst);
527 default:
528 return new Unknown64(machInst);
529 }
530 }
531 M5_FALLTHROUGH;
532 default:
533 return new Unknown64(machInst);
534 }
535 return new FailUnimplemented("Unhandled Case7", machInst);
536 }
537}
538}};
539
540output decoder {{
541namespace Aarch64
542{
543 StaticInstPtr
544 decodeLoadsStores(ExtMachInst machInst)
545 {
546 // bit 27,25=10
547 switch (bits(machInst, 29, 28)) {
548 case 0x0:
549 if (bits(machInst, 26) == 0) {
550 if (bits(machInst, 24) != 0)
551 return new Unknown64(machInst);
552 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
553 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
554 IntRegIndex rnsp = makeSP(rn);
555 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
556 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
557 uint8_t opc = (bits(machInst, 15) << 0) |
558 (bits(machInst, 23, 21) << 1);
559 uint8_t size = bits(machInst, 31, 30);
560 switch (opc) {
561 case 0x0:
562 switch (size) {
563 case 0x0:
564 return new STXRB64(machInst, rt, rnsp, rs);
565 case 0x1:
566 return new STXRH64(machInst, rt, rnsp, rs);
567 case 0x2:
568 return new STXRW64(machInst, rt, rnsp, rs);
569 case 0x3:
570 return new STXRX64(machInst, rt, rnsp, rs);
571 default:
572 M5_UNREACHABLE;
573 }
574 case 0x1:
575 switch (size) {
576 case 0x0:
577 return new STLXRB64(machInst, rt, rnsp, rs);
578 case 0x1:
579 return new STLXRH64(machInst, rt, rnsp, rs);
580 case 0x2:
581 return new STLXRW64(machInst, rt, rnsp, rs);
582 case 0x3:
583 return new STLXRX64(machInst, rt, rnsp, rs);
584 default:
585 M5_UNREACHABLE;
586 }
587 case 0x2:
588 switch (size) {
589 case 0x0:
590 case 0x1:
591 return new Unknown64(machInst);
592 case 0x2:
593 return new STXPW64(machInst, rs, rt, rt2, rnsp);
594 case 0x3:
595 return new STXPX64(machInst, rs, rt, rt2, rnsp);
596 default:
597 M5_UNREACHABLE;
598 }
599
600 case 0x3:
601 switch (size) {
602 case 0x0:
603 case 0x1:
604 return new Unknown64(machInst);
605 case 0x2:
606 return new STLXPW64(machInst, rs, rt, rt2, rnsp);
607 case 0x3:
608 return new STLXPX64(machInst, rs, rt, rt2, rnsp);
609 default:
610 M5_UNREACHABLE;
611 }
612
613 case 0x4:
614 switch (size) {
615 case 0x0:
616 return new LDXRB64(machInst, rt, rnsp, rs);
617 case 0x1:
618 return new LDXRH64(machInst, rt, rnsp, rs);
619 case 0x2:
620 return new LDXRW64(machInst, rt, rnsp, rs);
621 case 0x3:
622 return new LDXRX64(machInst, rt, rnsp, rs);
623 default:
624 M5_UNREACHABLE;
625 }
626 case 0x5:
627 switch (size) {
628 case 0x0:
629 return new LDAXRB64(machInst, rt, rnsp, rs);
630 case 0x1:
631 return new LDAXRH64(machInst, rt, rnsp, rs);
632 case 0x2:
633 return new LDAXRW64(machInst, rt, rnsp, rs);
634 case 0x3:
635 return new LDAXRX64(machInst, rt, rnsp, rs);
636 default:
637 M5_UNREACHABLE;
638 }
639 case 0x6:
640 switch (size) {
641 case 0x0:
642 case 0x1:
643 return new Unknown64(machInst);
644 case 0x2:
645 return new LDXPW64(machInst, rt, rt2, rnsp);
646 case 0x3:
647 return new LDXPX64(machInst, rt, rt2, rnsp);
648 default:
649 M5_UNREACHABLE;
650 }
651
652 case 0x7:
653 switch (size) {
654 case 0x0:
655 case 0x1:
656 return new Unknown64(machInst);
657 case 0x2:
658 return new LDAXPW64(machInst, rt, rt2, rnsp);
659 case 0x3:
660 return new LDAXPX64(machInst, rt, rt2, rnsp);
661 default:
662 M5_UNREACHABLE;
663 }
664
665 case 0x9:
666 switch (size) {
667 case 0x0:
668 return new STLRB64(machInst, rt, rnsp);
669 case 0x1:
670 return new STLRH64(machInst, rt, rnsp);
671 case 0x2:
672 return new STLRW64(machInst, rt, rnsp);
673 case 0x3:
674 return new STLRX64(machInst, rt, rnsp);
675 default:
676 M5_UNREACHABLE;
677 }
678 case 0xd:
679 switch (size) {
680 case 0x0:
681 return new LDARB64(machInst, rt, rnsp);
682 case 0x1:
683 return new LDARH64(machInst, rt, rnsp);
684 case 0x2:
685 return new LDARW64(machInst, rt, rnsp);
686 case 0x3:
687 return new LDARX64(machInst, rt, rnsp);
688 default:
689 M5_UNREACHABLE;
690 }
691 default:
692 return new Unknown64(machInst);
693 }
694 } else if (bits(machInst, 31)) {
695 return new Unknown64(machInst);
696 } else {
697 return decodeNeonMem(machInst);
698 }
699 case 0x1:
700 {
701 if (bits(machInst, 24) != 0)
702 return new Unknown64(machInst);
703 uint8_t switchVal = (bits(machInst, 26) << 0) |
704 (bits(machInst, 31, 30) << 1);
705 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2;
706 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
707 switch (switchVal) {
708 case 0x0:
709 return new LDRWL64_LIT(machInst, rt, imm);
710 case 0x1:
711 return new LDRSFP64_LIT(machInst, rt, imm);
712 case 0x2:
713 return new LDRXL64_LIT(machInst, rt, imm);
714 case 0x3:
715 return new LDRDFP64_LIT(machInst, rt, imm);
716 case 0x4:
717 return new LDRSWL64_LIT(machInst, rt, imm);
718 case 0x5:
719 return new BigFpMemLit("ldr", machInst, rt, imm);
720 case 0x6:
721 return new PRFM64_LIT(machInst, rt, imm);
722 default:
723 return new Unknown64(machInst);
724 }
725 }
726 case 0x2:
727 {
728 uint8_t opc = bits(machInst, 31, 30);
729 if (opc >= 3)
730 return new Unknown64(machInst);
731 uint32_t size = 0;
732 bool fp = bits(machInst, 26);
733 bool load = bits(machInst, 22);
734 if (fp) {
735 size = 4 << opc;
736 } else {
737 if ((opc == 1) && !load)
738 return new Unknown64(machInst);
739 size = (opc == 0 || opc == 1) ? 4 : 8;
740 }
741 uint8_t type = bits(machInst, 24, 23);
742 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size;
743
744 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
745 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
746 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
747
748 bool noAlloc = (type == 0);
749 bool signExt = !noAlloc && !fp && opc == 1;
750 PairMemOp::AddrMode mode;
751 const char *mnemonic = NULL;
752 switch (type) {
753 case 0x0:
754 case 0x2:
755 mode = PairMemOp::AddrMd_Offset;
756 break;
757 case 0x1:
758 mode = PairMemOp::AddrMd_PostIndex;
759 break;
760 case 0x3:
761 mode = PairMemOp::AddrMd_PreIndex;
762 break;
763 default:
764 return new Unknown64(machInst);
765 }
766 if (load) {
767 if (noAlloc)
768 mnemonic = "ldnp";
769 else if (signExt)
770 mnemonic = "ldpsw";
771 else
772 mnemonic = "ldp";
773 } else {
774 if (noAlloc)
775 mnemonic = "stnp";
776 else
777 mnemonic = "stp";
778 }
779
780 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc,
781 signExt, false, false, imm, mode, rn, rt, rt2);
782 }
783 // bit 29:27=111, 25=0
784 case 0x3:
785 {
786 uint8_t switchVal = (bits(machInst, 23, 22) << 0) |
787 (bits(machInst, 26) << 2) |
788 (bits(machInst, 31, 30) << 3);
789 if (bits(machInst, 24) == 1) {
790 uint64_t imm12 = bits(machInst, 21, 10);
791 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
792 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
793 IntRegIndex rnsp = makeSP(rn);
794 switch (switchVal) {
795 case 0x00:
796 return new STRB64_IMM(machInst, rt, rnsp, imm12);
797 case 0x01:
798 return new LDRB64_IMM(machInst, rt, rnsp, imm12);
799 case 0x02:
800 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12);
801 case 0x03:
802 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12);
803 case 0x04:
804 return new STRBFP64_IMM(machInst, rt, rnsp, imm12);
805 case 0x05:
806 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12);
807 case 0x06:
808 return new BigFpMemImm("str", machInst, false,
809 rt, rnsp, imm12 << 4);
810 case 0x07:
811 return new BigFpMemImm("ldr", machInst, true,
812 rt, rnsp, imm12 << 4);
813 case 0x08:
814 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1);
815 case 0x09:
816 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1);
817 case 0x0a:
818 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1);
819 case 0x0b:
820 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1);
821 case 0x0c:
822 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
823 case 0x0d:
824 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1);
825 case 0x10:
826 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2);
827 case 0x11:
828 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2);
829 case 0x12:
830 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2);
831 case 0x14:
832 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
833 case 0x15:
834 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2);
835 case 0x18:
836 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3);
837 case 0x19:
838 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3);
839 case 0x1a:
840 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3);
841 case 0x1c:
842 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
843 case 0x1d:
844 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3);
845 default:
846 return new Unknown64(machInst);
847 }
848 } else if (bits(machInst, 21) == 1) {
849 uint8_t group = bits(machInst, 11, 10);
850 switch (group) {
851 case 0x0:
852 {
853 if ((switchVal & 0x7) == 0x2 &&
854 bits(machInst, 20, 12) == 0x1fc) {
855 IntRegIndex rt = (IntRegIndex)(uint32_t)
856 bits(machInst, 4, 0);
857 IntRegIndex rn = (IntRegIndex)(uint32_t)
858 bits(machInst, 9, 5);
859 IntRegIndex rnsp = makeSP(rn);
860 uint8_t size = bits(machInst, 31, 30);
861 switch (size) {
862 case 0x0:
863 return new LDAPRB64(machInst, rt, rnsp);
864 case 0x1:
865 return new LDAPRH64(machInst, rt, rnsp);
866 case 0x2:
867 return new LDAPRW64(machInst, rt, rnsp);
868 case 0x3:
869 return new LDAPRX64(machInst, rt, rnsp);
870 default:
871 M5_UNREACHABLE;
872 }
873 } else {
874 return new Unknown64(machInst);
875 }
876 }
877 case 0x2:
878 {
879 if (!bits(machInst, 14))
880 return new Unknown64(machInst);
881 IntRegIndex rt = (IntRegIndex)(uint32_t)
882 bits(machInst, 4, 0);
883 IntRegIndex rn = (IntRegIndex)(uint32_t)
884 bits(machInst, 9, 5);
885 IntRegIndex rnsp = makeSP(rn);
886 IntRegIndex rm = (IntRegIndex)(uint32_t)
887 bits(machInst, 20, 16);
888 ArmExtendType type =
889 (ArmExtendType)(uint32_t)bits(machInst, 15, 13);
890 uint8_t s = bits(machInst, 12);
891 switch (switchVal) {
892 case 0x00:
893 return new STRB64_REG(machInst, rt, rnsp, rm,
894 type, 0);
895 case 0x01:
896 return new LDRB64_REG(machInst, rt, rnsp, rm,
897 type, 0);
898 case 0x02:
899 return new LDRSBX64_REG(machInst, rt, rnsp, rm,
900 type, 0);
901 case 0x03:
902 return new LDRSBW64_REG(machInst, rt, rnsp, rm,
903 type, 0);
904 case 0x04:
905 return new STRBFP64_REG(machInst, rt, rnsp, rm,
906 type, 0);
907 case 0x05:
908 return new LDRBFP64_REG(machInst, rt, rnsp, rm,
909 type, 0);
910 case 0x6:
911 return new BigFpMemReg("str", machInst, false,
912 rt, rnsp, rm, type, s * 4);
913 case 0x7:
914 return new BigFpMemReg("ldr", machInst, true,
915 rt, rnsp, rm, type, s * 4);
916 case 0x08:
917 return new STRH64_REG(machInst, rt, rnsp, rm,
918 type, s);
919 case 0x09:
920 return new LDRH64_REG(machInst, rt, rnsp, rm,
921 type, s);
922 case 0x0a:
923 return new LDRSHX64_REG(machInst, rt, rnsp, rm,
924 type, s);
925 case 0x0b:
926 return new LDRSHW64_REG(machInst, rt, rnsp, rm,
927 type, s);
928 case 0x0c:
929 return new STRHFP64_REG(machInst, rt, rnsp, rm,
930 type, s);
931 case 0x0d:
932 return new LDRHFP64_REG(machInst, rt, rnsp, rm,
933 type, s);
934 case 0x10:
935 return new STRW64_REG(machInst, rt, rnsp, rm,
936 type, s * 2);
937 case 0x11:
938 return new LDRW64_REG(machInst, rt, rnsp, rm,
939 type, s * 2);
940 case 0x12:
941 return new LDRSW64_REG(machInst, rt, rnsp, rm,
942 type, s * 2);
943 case 0x14:
944 return new STRSFP64_REG(machInst, rt, rnsp, rm,
945 type, s * 2);
946 case 0x15:
947 return new LDRSFP64_REG(machInst, rt, rnsp, rm,
948 type, s * 2);
949 case 0x18:
950 return new STRX64_REG(machInst, rt, rnsp, rm,
951 type, s * 3);
952 case 0x19:
953 return new LDRX64_REG(machInst, rt, rnsp, rm,
954 type, s * 3);
955 case 0x1a:
956 return new PRFM64_REG(machInst, rt, rnsp, rm,
957 type, s * 3);
958 case 0x1c:
959 return new STRDFP64_REG(machInst, rt, rnsp, rm,
960 type, s * 3);
961 case 0x1d:
962 return new LDRDFP64_REG(machInst, rt, rnsp, rm,
963 type, s * 3);
964 default:
965 return new Unknown64(machInst);
966
967 }
968 }
969 default:
970 return new Unknown64(machInst);
971 }
972 } else {
973 // bit 29:27=111, 25:24=00, 21=0
974 switch (bits(machInst, 11, 10)) {
975 case 0x0:
976 {
977 IntRegIndex rt =
978 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
979 IntRegIndex rn =
980 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
981 IntRegIndex rnsp = makeSP(rn);
982 uint64_t imm = sext<9>(bits(machInst, 20, 12));
983 switch (switchVal) {
984 case 0x00:
985 return new STURB64_IMM(machInst, rt, rnsp, imm);
986 case 0x01:
987 return new LDURB64_IMM(machInst, rt, rnsp, imm);
988 case 0x02:
989 return new LDURSBX64_IMM(machInst, rt, rnsp, imm);
990 case 0x03:
991 return new LDURSBW64_IMM(machInst, rt, rnsp, imm);
992 case 0x04:
993 return new STURBFP64_IMM(machInst, rt, rnsp, imm);
994 case 0x05:
995 return new LDURBFP64_IMM(machInst, rt, rnsp, imm);
996 case 0x06:
997 return new BigFpMemImm("stur", machInst, false,
998 rt, rnsp, imm);
999 case 0x07:
1000 return new BigFpMemImm("ldur", machInst, true,
1001 rt, rnsp, imm);
1002 case 0x08:
1003 return new STURH64_IMM(machInst, rt, rnsp, imm);
1004 case 0x09:
1005 return new LDURH64_IMM(machInst, rt, rnsp, imm);
1006 case 0x0a:
1007 return new LDURSHX64_IMM(machInst, rt, rnsp, imm);
1008 case 0x0b:
1009 return new LDURSHW64_IMM(machInst, rt, rnsp, imm);
1010 case 0x0c:
1011 return new STURHFP64_IMM(machInst, rt, rnsp, imm);
1012 case 0x0d:
1013 return new LDURHFP64_IMM(machInst, rt, rnsp, imm);
1014 case 0x10:
1015 return new STURW64_IMM(machInst, rt, rnsp, imm);
1016 case 0x11:
1017 return new LDURW64_IMM(machInst, rt, rnsp, imm);
1018 case 0x12:
1019 return new LDURSW64_IMM(machInst, rt, rnsp, imm);
1020 case 0x14:
1021 return new STURSFP64_IMM(machInst, rt, rnsp, imm);
1022 case 0x15:
1023 return new LDURSFP64_IMM(machInst, rt, rnsp, imm);
1024 case 0x18:
1025 return new STURX64_IMM(machInst, rt, rnsp, imm);
1026 case 0x19:
1027 return new LDURX64_IMM(machInst, rt, rnsp, imm);
1028 case 0x1a:
1029 return new PRFUM64_IMM(machInst, rt, rnsp, imm);
1030 case 0x1c:
1031 return new STURDFP64_IMM(machInst, rt, rnsp, imm);
1032 case 0x1d:
1033 return new LDURDFP64_IMM(machInst, rt, rnsp, imm);
1034 default:
1035 return new Unknown64(machInst);
1036 }
1037 }
1038 // bit 29:27=111, 25:24=00, 21=0, 11:10=01
1039 case 0x1:
1040 {
1041 IntRegIndex rt =
1042 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1043 IntRegIndex rn =
1044 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1045 IntRegIndex rnsp = makeSP(rn);
1046 uint64_t imm = sext<9>(bits(machInst, 20, 12));
1047 switch (switchVal) {
1048 case 0x00:
1049 return new STRB64_POST(machInst, rt, rnsp, imm);
1050 case 0x01:
1051 return new LDRB64_POST(machInst, rt, rnsp, imm);
1052 case 0x02:
1053 return new LDRSBX64_POST(machInst, rt, rnsp, imm);
1054 case 0x03:
1055 return new LDRSBW64_POST(machInst, rt, rnsp, imm);
1056 case 0x04:
1057 return new STRBFP64_POST(machInst, rt, rnsp, imm);
1058 case 0x05:
1059 return new LDRBFP64_POST(machInst, rt, rnsp, imm);
1060 case 0x06:
1061 return new BigFpMemPost("str", machInst, false,
1062 rt, rnsp, imm);
1063 case 0x07:
1064 return new BigFpMemPost("ldr", machInst, true,
1065 rt, rnsp, imm);
1066 case 0x08:
1067 return new STRH64_POST(machInst, rt, rnsp, imm);
1068 case 0x09:
1069 return new LDRH64_POST(machInst, rt, rnsp, imm);
1070 case 0x0a:
1071 return new LDRSHX64_POST(machInst, rt, rnsp, imm);
1072 case 0x0b:
1073 return new LDRSHW64_POST(machInst, rt, rnsp, imm);
1074 case 0x0c:
1075 return new STRHFP64_POST(machInst, rt, rnsp, imm);
1076 case 0x0d:
1077 return new LDRHFP64_POST(machInst, rt, rnsp, imm);
1078 case 0x10:
1079 return new STRW64_POST(machInst, rt, rnsp, imm);
1080 case 0x11:
1081 return new LDRW64_POST(machInst, rt, rnsp, imm);
1082 case 0x12:
1083 return new LDRSW64_POST(machInst, rt, rnsp, imm);
1084 case 0x14:
1085 return new STRSFP64_POST(machInst, rt, rnsp, imm);
1086 case 0x15:
1087 return new LDRSFP64_POST(machInst, rt, rnsp, imm);
1088 case 0x18:
1089 return new STRX64_POST(machInst, rt, rnsp, imm);
1090 case 0x19:
1091 return new LDRX64_POST(machInst, rt, rnsp, imm);
1092 case 0x1c:
1093 return new STRDFP64_POST(machInst, rt, rnsp, imm);
1094 case 0x1d:
1095 return new LDRDFP64_POST(machInst, rt, rnsp, imm);
1096 default:
1097 return new Unknown64(machInst);
1098 }
1099 }
1100 case 0x2:
1101 {
1102 IntRegIndex rt =
1103 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1104 IntRegIndex rn =
1105 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1106 IntRegIndex rnsp = makeSP(rn);
1107 uint64_t imm = sext<9>(bits(machInst, 20, 12));
1108 switch (switchVal) {
1109 case 0x00:
1110 return new STTRB64_IMM(machInst, rt, rnsp, imm);
1111 case 0x01:
1112 return new LDTRB64_IMM(machInst, rt, rnsp, imm);
1113 case 0x02:
1114 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm);
1115 case 0x03:
1116 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm);
1117 case 0x08:
1118 return new STTRH64_IMM(machInst, rt, rnsp, imm);
1119 case 0x09:
1120 return new LDTRH64_IMM(machInst, rt, rnsp, imm);
1121 case 0x0a:
1122 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm);
1123 case 0x0b:
1124 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm);
1125 case 0x10:
1126 return new STTRW64_IMM(machInst, rt, rnsp, imm);
1127 case 0x11:
1128 return new LDTRW64_IMM(machInst, rt, rnsp, imm);
1129 case 0x12:
1130 return new LDTRSW64_IMM(machInst, rt, rnsp, imm);
1131 case 0x18:
1132 return new STTRX64_IMM(machInst, rt, rnsp, imm);
1133 case 0x19:
1134 return new LDTRX64_IMM(machInst, rt, rnsp, imm);
1135 default:
1136 return new Unknown64(machInst);
1137 }
1138 }
1139 case 0x3:
1140 {
1141 IntRegIndex rt =
1142 (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1143 IntRegIndex rn =
1144 (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1145 IntRegIndex rnsp = makeSP(rn);
1146 uint64_t imm = sext<9>(bits(machInst, 20, 12));
1147 switch (switchVal) {
1148 case 0x00:
1149 return new STRB64_PRE(machInst, rt, rnsp, imm);
1150 case 0x01:
1151 return new LDRB64_PRE(machInst, rt, rnsp, imm);
1152 case 0x02:
1153 return new LDRSBX64_PRE(machInst, rt, rnsp, imm);
1154 case 0x03:
1155 return new LDRSBW64_PRE(machInst, rt, rnsp, imm);
1156 case 0x04:
1157 return new STRBFP64_PRE(machInst, rt, rnsp, imm);
1158 case 0x05:
1159 return new LDRBFP64_PRE(machInst, rt, rnsp, imm);
1160 case 0x06:
1161 return new BigFpMemPre("str", machInst, false,
1162 rt, rnsp, imm);
1163 case 0x07:
1164 return new BigFpMemPre("ldr", machInst, true,
1165 rt, rnsp, imm);
1166 case 0x08:
1167 return new STRH64_PRE(machInst, rt, rnsp, imm);
1168 case 0x09:
1169 return new LDRH64_PRE(machInst, rt, rnsp, imm);
1170 case 0x0a:
1171 return new LDRSHX64_PRE(machInst, rt, rnsp, imm);
1172 case 0x0b:
1173 return new LDRSHW64_PRE(machInst, rt, rnsp, imm);
1174 case 0x0c:
1175 return new STRHFP64_PRE(machInst, rt, rnsp, imm);
1176 case 0x0d:
1177 return new LDRHFP64_PRE(machInst, rt, rnsp, imm);
1178 case 0x10:
1179 return new STRW64_PRE(machInst, rt, rnsp, imm);
1180 case 0x11:
1181 return new LDRW64_PRE(machInst, rt, rnsp, imm);
1182 case 0x12:
1183 return new LDRSW64_PRE(machInst, rt, rnsp, imm);
1184 case 0x14:
1185 return new STRSFP64_PRE(machInst, rt, rnsp, imm);
1186 case 0x15:
1187 return new LDRSFP64_PRE(machInst, rt, rnsp, imm);
1188 case 0x18:
1189 return new STRX64_PRE(machInst, rt, rnsp, imm);
1190 case 0x19:
1191 return new LDRX64_PRE(machInst, rt, rnsp, imm);
1192 case 0x1c:
1193 return new STRDFP64_PRE(machInst, rt, rnsp, imm);
1194 case 0x1d:
1195 return new LDRDFP64_PRE(machInst, rt, rnsp, imm);
1196 default:
1197 return new Unknown64(machInst);
1198 }
1199 }
1200 default:
1201 M5_UNREACHABLE;
1202 }
1203 }
1204 }
1205 default:
1206 M5_UNREACHABLE;
1207 }
1208 return new FailUnimplemented("Unhandled Case1", machInst);
1209 }
1210}
1211}};
1212
1213output decoder {{
1214namespace Aarch64
1215{
1216 StaticInstPtr
1217 decodeDataProcReg(ExtMachInst machInst)
1218 {
1219 uint8_t switchVal = (bits(machInst, 28) << 1) |
1220 (bits(machInst, 24) << 0);
1221 switch (switchVal) {
1222 case 0x0:
1223 {
1224 uint8_t switchVal = (bits(machInst, 21) << 0) |
1225 (bits(machInst, 30, 29) << 1);
1226 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1227 uint8_t imm6 = bits(machInst, 15, 10);
1228 bool sf = bits(machInst, 31);
1229 if (!sf && (imm6 & 0x20))
1230 return new Unknown64(machInst);
1231 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1232 IntRegIndex rdzr = makeZero(rd);
1233 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1234 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1235
1236 switch (switchVal) {
1237 case 0x0:
1238 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type);
1239 case 0x1:
1240 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type);
1241 case 0x2:
1242 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type);
1243 case 0x3:
1244 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type);
1245 case 0x4:
1246 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type);
1247 case 0x5:
1248 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type);
1249 case 0x6:
1250 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1251 case 0x7:
1252 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1253 default:
1254 M5_UNREACHABLE;
1255 }
1256 }
1257 case 0x1:
1258 {
1259 uint8_t switchVal = bits(machInst, 30, 29);
1260 if (bits(machInst, 21) == 0) {
1261 ArmShiftType type =
1262 (ArmShiftType)(uint8_t)bits(machInst, 23, 22);
1263 if (type == ROR)
1264 return new Unknown64(machInst);
1265 uint8_t imm6 = bits(machInst, 15, 10);
1266 if (!bits(machInst, 31) && bits(imm6, 5))
1267 return new Unknown64(machInst);
1268 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1269 IntRegIndex rdzr = makeZero(rd);
1270 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1271 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1272 switch (switchVal) {
1273 case 0x0:
1274 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type);
1275 case 0x1:
1276 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1277 case 0x2:
1278 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type);
1279 case 0x3:
1280 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type);
1281 default:
1282 M5_UNREACHABLE;
1283 }
1284 } else {
1285 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4)
1286 return new Unknown64(machInst);
1287 ArmExtendType type =
1288 (ArmExtendType)(uint8_t)bits(machInst, 15, 13);
1289 uint8_t imm3 = bits(machInst, 12, 10);
1290 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1291 IntRegIndex rdsp = makeSP(rd);
1292 IntRegIndex rdzr = makeZero(rd);
1293 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1294 IntRegIndex rnsp = makeSP(rn);
1295 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1296
1297 switch (switchVal) {
1298 case 0x0:
1299 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1300 case 0x1:
1301 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1302 case 0x2:
1303 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3);
1304 case 0x3:
1305 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3);
1306 default:
1307 M5_UNREACHABLE;
1308 }
1309 }
1310 }
1311 case 0x2:
1312 {
1313 if (bits(machInst, 21) == 1)
1314 return new Unknown64(machInst);
1315 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1316 IntRegIndex rdzr = makeZero(rd);
1317 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1318 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1319 switch (bits(machInst, 23, 22)) {
1320 case 0x0:
1321 {
1322 if (bits(machInst, 15, 10))
1323 return new Unknown64(machInst);
1324 uint8_t switchVal = bits(machInst, 30, 29);
1325 switch (switchVal) {
1326 case 0x0:
1327 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1328 case 0x1:
1329 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1330 case 0x2:
1331 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL);
1332 case 0x3:
1333 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL);
1334 default:
1335 M5_UNREACHABLE;
1336 }
1337 }
1338 case 0x1:
1339 {
1340 if ((bits(machInst, 4) == 1) ||
1341 (bits(machInst, 10) == 1) ||
1342 (bits(machInst, 29) == 0)) {
1343 return new Unknown64(machInst);
1344 }
1345 ConditionCode cond =
1346 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1347 uint8_t flags = bits(machInst, 3, 0);
1348 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1349 if (bits(machInst, 11) == 0) {
1350 IntRegIndex rm =
1351 (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1352 if (bits(machInst, 30) == 0) {
1353 return new CcmnReg64(machInst, rn, rm, cond, flags);
1354 } else {
1355 return new CcmpReg64(machInst, rn, rm, cond, flags);
1356 }
1357 } else {
1358 uint8_t imm5 = bits(machInst, 20, 16);
1359 if (bits(machInst, 30) == 0) {
1360 return new CcmnImm64(machInst, rn, imm5, cond, flags);
1361 } else {
1362 return new CcmpImm64(machInst, rn, imm5, cond, flags);
1363 }
1364 }
1365 }
1366 case 0x2:
1367 {
1368 if (bits(machInst, 29) == 1 ||
1369 bits(machInst, 11) == 1) {
1370 return new Unknown64(machInst);
1371 }
1372 uint8_t switchVal = (bits(machInst, 10) << 0) |
1373 (bits(machInst, 30) << 1);
1374 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1375 IntRegIndex rdzr = makeZero(rd);
1376 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1377 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1378 ConditionCode cond =
1379 (ConditionCode)(uint8_t)bits(machInst, 15, 12);
1380 switch (switchVal) {
1381 case 0x0:
1382 return new Csel64(machInst, rdzr, rn, rm, cond);
1383 case 0x1:
1384 return new Csinc64(machInst, rdzr, rn, rm, cond);
1385 case 0x2:
1386 return new Csinv64(machInst, rdzr, rn, rm, cond);
1387 case 0x3:
1388 return new Csneg64(machInst, rdzr, rn, rm, cond);
1389 default:
1390 M5_UNREACHABLE;
1391 }
1392 }
1393 case 0x3:
1394 if (bits(machInst, 30) == 0) {
1395 if (bits(machInst, 29) != 0)
1396 return new Unknown64(machInst);
1397 uint8_t switchVal = bits(machInst, 15, 10);
1398 switch (switchVal) {
1399 case 0x2:
1400 return new Udiv64(machInst, rdzr, rn, rm);
1401 case 0x3:
1402 return new Sdiv64(machInst, rdzr, rn, rm);
1403 case 0x8:
1404 return new Lslv64(machInst, rdzr, rn, rm);
1405 case 0x9:
1406 return new Lsrv64(machInst, rdzr, rn, rm);
1407 case 0xa:
1408 return new Asrv64(machInst, rdzr, rn, rm);
1409 case 0xb:
1410 return new Rorv64(machInst, rdzr, rn, rm);
1411 case 0x10:
1412 return new Crc32b64(machInst, rdzr, rn, rm);
1413 case 0x11:
1414 return new Crc32h64(machInst, rdzr, rn, rm);
1415 case 0x12:
1416 return new Crc32w64(machInst, rdzr, rn, rm);
1417 case 0x13:
1418 return new Crc32x64(machInst, rdzr, rn, rm);
1419 case 0x14:
1420 return new Crc32cb64(machInst, rdzr, rn, rm);
1421 case 0x15:
1422 return new Crc32ch64(machInst, rdzr, rn, rm);
1423 case 0x16:
1424 return new Crc32cw64(machInst, rdzr, rn, rm);
1425 case 0x17:
1426 return new Crc32cx64(machInst, rdzr, rn, rm);
1427 default:
1428 return new Unknown64(machInst);
1429 }
1430 } else {
1431 if (bits(machInst, 20, 16) != 0 ||
1432 bits(machInst, 29) != 0) {
1433 return new Unknown64(machInst);
1434 }
1435 uint8_t switchVal = bits(machInst, 15, 10);
1436 switch (switchVal) {
1437 case 0x0:
1438 return new Rbit64(machInst, rdzr, rn);
1439 case 0x1:
1440 return new Rev1664(machInst, rdzr, rn);
1441 case 0x2:
1442 if (bits(machInst, 31) == 0)
1443 return new Rev64(machInst, rdzr, rn);
1444 else
1445 return new Rev3264(machInst, rdzr, rn);
1446 case 0x3:
1447 if (bits(machInst, 31) != 1)
1448 return new Unknown64(machInst);
1449 return new Rev64(machInst, rdzr, rn);
1450 case 0x4:
1451 return new Clz64(machInst, rdzr, rn);
1452 case 0x5:
1453 return new Cls64(machInst, rdzr, rn);
1454 default:
1455 return new Unknown64(machInst);
1456 }
1457 }
1458 default:
1459 M5_UNREACHABLE;
1460 }
1461 }
1462 case 0x3:
1463 {
1464 if (bits(machInst, 30, 29) != 0x0 ||
1465 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0))
1466 return new Unknown64(machInst);
1467 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0);
1468 IntRegIndex rdzr = makeZero(rd);
1469 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5);
1470 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10);
1471 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16);
1472 switch (bits(machInst, 23, 21)) {
1473 case 0x0:
1474 if (bits(machInst, 15) == 0)
1475 return new Madd64(machInst, rdzr, ra, rn, rm);
1476 else
1477 return new Msub64(machInst, rdzr, ra, rn, rm);
1478 case 0x1:
1479 if (bits(machInst, 15) == 0)
1480 return new Smaddl64(machInst, rdzr, ra, rn, rm);
1481 else
1482 return new Smsubl64(machInst, rdzr, ra, rn, rm);
1483 case 0x2:
1484 if (bits(machInst, 15) != 0)
1485 return new Unknown64(machInst);
1486 return new Smulh64(machInst, rdzr, rn, rm);
1487 case 0x5:
1488 if (bits(machInst, 15) == 0)
1489 return new Umaddl64(machInst, rdzr, ra, rn, rm);
1490 else
1491 return new Umsubl64(machInst, rdzr, ra, rn, rm);
1492 case 0x6:
1493 if (bits(machInst, 15) != 0)
1494 return new Unknown64(machInst);
1495 return new Umulh64(machInst, rdzr, rn, rm);
1496 default:
1497 return new Unknown64(machInst);
1498 }
1499 }
1500 default:
1501 M5_UNREACHABLE;
1502 }
1503 return new FailUnimplemented("Unhandled Case2", machInst);
1504 }
1505}
1506}};
1507
1508output decoder {{
1509namespace Aarch64
1510{
1511 template <typename DecoderFeatures>
1512 StaticInstPtr
1513 decodeAdvSIMD(ExtMachInst machInst)
1514 {
1515 if (bits(machInst, 24) == 1) {
1516 if (bits(machInst, 10) == 0) {
1517 return decodeNeonIndexedElem<DecoderFeatures>(machInst);
1518 } else if (bits(machInst, 23) == 1) {
1519 return new Unknown64(machInst);
1520 } else {
1521 if (bits(machInst, 22, 19)) {
1522 return decodeNeonShiftByImm(machInst);
1523 } else {
1524 return decodeNeonModImm(machInst);
1525 }
1526 }
1527 } else if (bits(machInst, 21) == 1) {
1528 if (bits(machInst, 10) == 1) {
1529 return decodeNeon3Same<DecoderFeatures>(machInst);
1530 } else if (bits(machInst, 11) == 0) {
1531 return decodeNeon3Diff(machInst);
1532 } else if (bits(machInst, 20, 17) == 0x0) {
1533 return decodeNeon2RegMisc(machInst);
1534 } else if (bits(machInst, 20, 17) == 0x4) {
1535 return decodeCryptoAES(machInst);
1536 } else if (bits(machInst, 20, 17) == 0x8) {
1537 return decodeNeonAcrossLanes(machInst);
1538 } else {
1539 return new Unknown64(machInst);
1540 }
1541 } else if (bits(machInst, 24) ||
1542 bits(machInst, 21) ||
1543 bits(machInst, 15)) {
1544 return new Unknown64(machInst);
1545 } else if (bits(machInst, 10) == 1) {
1546 if (bits(machInst, 23, 22))
1547 return new Unknown64(machInst);
1548 return decodeNeonCopy(machInst);
1549 } else if (bits(machInst, 29) == 1) {
1550 return decodeNeonExt(machInst);
1551 } else if (bits(machInst, 11) == 1) {
1552 return decodeNeonZipUzpTrn(machInst);
1553 } else if (bits(machInst, 23, 22) == 0x0) {
1554 return decodeNeonTblTbx(machInst);
1555 } else {
1556 return new Unknown64(machInst);
1557 }
1558 return new FailUnimplemented("Unhandled Case3", machInst);
1559 }
1560}
1561}};
1562
1563
1564output decoder {{
1565namespace Aarch64
1566{
1567 StaticInstPtr
1568 // bit 30=0, 28:25=1111
1569 decodeFp(ExtMachInst machInst)
1570 {
1571 if (bits(machInst, 24) == 1) {
1572 if (bits(machInst, 31) || bits(machInst, 29))
1573 return new Unknown64(machInst);
1574 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1575 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1576 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
1577 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10);
1578 uint8_t switchVal = (bits(machInst, 23, 21) << 1) |
1579 (bits(machInst, 15) << 0);
1580 switch (switchVal) {
1581 case 0x0: // FMADD Sd = Sa + Sn*Sm
1582 return new FMAddS(machInst, rd, rn, rm, ra);
1583 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm
1584 return new FMSubS(machInst, rd, rn, rm, ra);
1585 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm
1586 return new FNMAddS(machInst, rd, rn, rm, ra);
1587 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm
1588 return new FNMSubS(machInst, rd, rn, rm, ra);
1589 case 0x4: // FMADD Dd = Da + Dn*Dm
1590 return new FMAddD(machInst, rd, rn, rm, ra);
1591 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm
1592 return new FMSubD(machInst, rd, rn, rm, ra);
1593 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm
1594 return new FNMAddD(machInst, rd, rn, rm, ra);
1595 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm
1596 return new FNMSubD(machInst, rd, rn, rm, ra);
1597 default:
1598 return new Unknown64(machInst);
1599 }
1600 } else if (bits(machInst, 21) == 0) {
1601 bool s = bits(machInst, 29);
1602 if (s)
1603 return new Unknown64(machInst);
1604 uint8_t switchVal = bits(machInst, 20, 16);
1605 uint8_t type = bits(machInst, 23, 22);
1606 uint8_t scale = bits(machInst, 15, 10);
1607 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1608 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1609 if (bits(machInst, 18, 17) == 3 && scale != 0)
1610 return new Unknown64(machInst);
1611 // 30:24=0011110, 21=0
1612 switch (switchVal) {
1613 case 0x00:
1614 return new FailUnimplemented("fcvtns", machInst);
1615 case 0x01:
1616 return new FailUnimplemented("fcvtnu", machInst);
1617 case 0x02:
1618 switch ( (bits(machInst, 31) << 2) | type ) {
1619 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits))
1620 return new FcvtSFixedFpSW(machInst, rd, rn, scale);
1621 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits))
1622 return new FcvtSFixedFpDW(machInst, rd, rn, scale);
1623 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits))
1624 return new FcvtSFixedFpSX(machInst, rd, rn, scale);
1625 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits))
1626 return new FcvtSFixedFpDX(machInst, rd, rn, scale);
1627 default:
1628 return new Unknown64(machInst);
1629 }
1630 case 0x03:
1631 switch ( (bits(machInst, 31) << 2) | type ) {
1632 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits))
1633 return new FcvtUFixedFpSW(machInst, rd, rn, scale);
1634 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits))
1635 return new FcvtUFixedFpDW(machInst, rd, rn, scale);
1636 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits))
1637 return new FcvtUFixedFpSX(machInst, rd, rn, scale);
1638 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits))
1639 return new FcvtUFixedFpDX(machInst, rd, rn, scale);
1640 default:
1641 return new Unknown64(machInst);
1642 }
1643 case 0x04:
1644 return new FailUnimplemented("fcvtas", machInst);
1645 case 0x05:
1646 return new FailUnimplemented("fcvtau", machInst);
1647 case 0x08:
1648 return new FailUnimplemented("fcvtps", machInst);
1649 case 0x09:
1650 return new FailUnimplemented("fcvtpu", machInst);
1651 case 0x0e:
1652 return new FailUnimplemented("fmov elem. to 64", machInst);
1653 case 0x0f:
1654 return new FailUnimplemented("fmov 64 bit", machInst);
1655 case 0x10:
1656 return new FailUnimplemented("fcvtms", machInst);
1657 case 0x11:
1658 return new FailUnimplemented("fcvtmu", machInst);
1659 case 0x18:
1660 switch ( (bits(machInst, 31) << 2) | type ) {
1661 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1662 return new FcvtFpSFixedSW(machInst, rd, rn, scale);
1663 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1664 return new FcvtFpSFixedDW(machInst, rd, rn, scale);
1665 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1666 return new FcvtFpSFixedSX(machInst, rd, rn, scale);
1667 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1668 return new FcvtFpSFixedDX(machInst, rd, rn, scale);
1669 default:
1670 return new Unknown64(machInst);
1671 }
1672 case 0x19:
1673 switch ( (bits(machInst, 31) << 2) | type ) {
1674 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits))
1675 return new FcvtFpUFixedSW(machInst, rd, rn, scale);
1676 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits))
1677 return new FcvtFpUFixedDW(machInst, rd, rn, scale);
1678 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits))
1679 return new FcvtFpUFixedSX(machInst, rd, rn, scale);
1680 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits))
1681 return new FcvtFpUFixedDX(machInst, rd, rn, scale);
1682 default:
1683 return new Unknown64(machInst);
1684 }
1685 default:
1686 return new Unknown64(machInst);
1687 }
1688 } else {
1689 // 30=0, 28:24=11110, 21=1
1690 uint8_t type = bits(machInst, 23, 22);
1691 uint8_t imm8 = bits(machInst, 20, 13);
1692 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
1693 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
1694 switch (bits(machInst, 11, 10)) {
1695 case 0x0:
1696 if (bits(machInst, 12) == 1) {
1697 if (bits(machInst, 31) ||
1698 bits(machInst, 29) ||
1699 bits(machInst, 9, 5)) {
1700 return new Unknown64(machInst);
1701 }
1702 // 31:29=000, 28:24=11110, 21=1, 12:10=100
1703 if (type == 0) {
1704 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5)
1705 // :imm8<5:0>:Zeros(19)
1706 uint32_t imm = vfp_modified_imm(imm8,
1707 FpDataType::Fp32);
1708 return new FmovImmS(machInst, rd, imm);
1709 } else if (type == 1) {
1710 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8)
1711 // :imm8<5:0>:Zeros(48)
1712 uint64_t imm = vfp_modified_imm(imm8,
1713 FpDataType::Fp64);
1714 return new FmovImmD(machInst, rd, imm);
1715 } else {
1716 return new Unknown64(machInst);
1717 }
1718 } else if (bits(machInst, 13) == 1) {
1719 if (bits(machInst, 31) ||
1720 bits(machInst, 29) ||
1721 bits(machInst, 15, 14) ||
1722 bits(machInst, 23) ||
1723 bits(machInst, 2, 0)) {
1724 return new Unknown64(machInst);
1725 }
1726 uint8_t switchVal = (bits(machInst, 4, 3) << 0) |
1727 (bits(machInst, 22) << 2);
1728 IntRegIndex rm = (IntRegIndex)(uint32_t)
1729 bits(machInst, 20, 16);
1730 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000
1731 switch (switchVal) {
1732 case 0x0:
1733 // FCMP flags = compareQuiet(Sn,Sm)
1734 return new FCmpRegS(machInst, rn, rm);
1735 case 0x1:
1736 // FCMP flags = compareQuiet(Sn,0.0)
1737 return new FCmpImmS(machInst, rn, 0);
1738 case 0x2:
1739 // FCMPE flags = compareSignaling(Sn,Sm)
1740 return new FCmpERegS(machInst, rn, rm);
1741 case 0x3:
1742 // FCMPE flags = compareSignaling(Sn,0.0)
1743 return new FCmpEImmS(machInst, rn, 0);
1744 case 0x4:
1745 // FCMP flags = compareQuiet(Dn,Dm)
1746 return new FCmpRegD(machInst, rn, rm);
1747 case 0x5:
1748 // FCMP flags = compareQuiet(Dn,0.0)
1749 return new FCmpImmD(machInst, rn, 0);
1750 case 0x6:
1751 // FCMPE flags = compareSignaling(Dn,Dm)
1752 return new FCmpERegD(machInst, rn, rm);
1753 case 0x7:
1754 // FCMPE flags = compareSignaling(Dn,0.0)
1755 return new FCmpEImmD(machInst, rn, 0);
1756 default:
1757 return new Unknown64(machInst);
1758 }
1759 } else if (bits(machInst, 14) == 1) {
1760 if (bits(machInst, 31) || bits(machInst, 29))
1761 return new Unknown64(machInst);
1762 uint8_t opcode = bits(machInst, 20, 15);
1763 // Bits 31:24=00011110, 21=1, 14:10=10000
1764 switch (opcode) {
1765 case 0x0:
1766 if (type == 0)
1767 // FMOV Sd = Sn
1768 return new FmovRegS(machInst, rd, rn);
1769 else if (type == 1)
1770 // FMOV Dd = Dn
1771 return new FmovRegD(machInst, rd, rn);
1772 break;
1773 case 0x1:
1774 if (type == 0)
1775 // FABS Sd = abs(Sn)
1776 return new FAbsS(machInst, rd, rn);
1777 else if (type == 1)
1778 // FABS Dd = abs(Dn)
1779 return new FAbsD(machInst, rd, rn);
1780 break;
1781 case 0x2:
1782 if (type == 0)
1783 // FNEG Sd = -Sn
1784 return new FNegS(machInst, rd, rn);
1785 else if (type == 1)
1786 // FNEG Dd = -Dn
1787 return new FNegD(machInst, rd, rn);
1788 break;
1789 case 0x3:
1790 if (type == 0)
1791 // FSQRT Sd = sqrt(Sn)
1792 return new FSqrtS(machInst, rd, rn);
1793 else if (type == 1)
1794 // FSQRT Dd = sqrt(Dn)
1795 return new FSqrtD(machInst, rd, rn);
1796 break;
1797 case 0x4:
1798 if (type == 1)
1799 // FCVT Sd = convertFormat(Dn)
1800 return new FcvtFpDFpS(machInst, rd, rn);
1801 else if (type == 3)
1802 // FCVT Sd = convertFormat(Hn)
1803 return new FcvtFpHFpS(machInst, rd, rn);
1804 break;
1805 case 0x5:
1806 if (type == 0)
1807 // FCVT Dd = convertFormat(Sn)
1808 return new FCvtFpSFpD(machInst, rd, rn);
1809 else if (type == 3)
1810 // FCVT Dd = convertFormat(Hn)
1811 return new FcvtFpHFpD(machInst, rd, rn);
1812 break;
1813 case 0x7:
1814 if (type == 0)
1815 // FCVT Hd = convertFormat(Sn)
1816 return new FcvtFpSFpH(machInst, rd, rn);
1817 else if (type == 1)
1818 // FCVT Hd = convertFormat(Dn)
1819 return new FcvtFpDFpH(machInst, rd, rn);
1820 break;
1821 case 0x8:
1822 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn)
1823 return new FRIntNS(machInst, rd, rn);
1824 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn)
1825 return new FRIntND(machInst, rd, rn);
1826 break;
1827 case 0x9:
1828 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn)
1829 return new FRIntPS(machInst, rd, rn);
1830 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn)
1831 return new FRIntPD(machInst, rd, rn);
1832 break;
1833 case 0xa:
1834 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn)
1835 return new FRIntMS(machInst, rd, rn);
1836 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn)
1837 return new FRIntMD(machInst, rd, rn);
1838 break;
1839 case 0xb:
1840 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn)
1841 return new FRIntZS(machInst, rd, rn);
1842 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn)
1843 return new FRIntZD(machInst, rd, rn);
1844 break;
1845 case 0xc:
1846 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn)
1847 return new FRIntAS(machInst, rd, rn);
1848 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn)
1849 return new FRIntAD(machInst, rd, rn);
1850 break;
1851 case 0xe:
1852 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn)
1853 return new FRIntXS(machInst, rd, rn);
1854 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn)
1855 return new FRIntXD(machInst, rd, rn);
1856 break;
1857 case 0xf:
1858 if (type == 0) // FRINTI Sd = roundToIntegral(Sn)
1859 return new FRIntIS(machInst, rd, rn);
1860 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn)
1861 return new FRIntID(machInst, rd, rn);
1862 break;
1863 default:
1864 return new Unknown64(machInst);
1865 }
1866 return new Unknown64(machInst);
1867 } else if (bits(machInst, 15) == 1) {
1868 return new Unknown64(machInst);
1869 } else {
1870 if (bits(machInst, 29))
1871 return new Unknown64(machInst);
1872 uint8_t rmode = bits(machInst, 20, 19);
1873 uint8_t switchVal1 = bits(machInst, 18, 16);
1874 uint8_t switchVal2 = (type << 1) | bits(machInst, 31);
1875 // 30:24=0011110, 21=1, 15:10=000000
1876 switch (switchVal1) {
1877 case 0x0:
1878 switch ((switchVal2 << 2) | rmode) {
1879 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn)
1880 return new FcvtFpSIntWSN(machInst, rd, rn);
1881 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn)
1882 return new FcvtFpSIntWSP(machInst, rd, rn);
1883 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn)
1884 return new FcvtFpSIntWSM(machInst, rd, rn);
1885 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn)
1886 return new FcvtFpSIntWSZ(machInst, rd, rn);
1887 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn)
1888 return new FcvtFpSIntXSN(machInst, rd, rn);
1889 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn)
1890 return new FcvtFpSIntXSP(machInst, rd, rn);
1891 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn)
1892 return new FcvtFpSIntXSM(machInst, rd, rn);
1893 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn)
1894 return new FcvtFpSIntXSZ(machInst, rd, rn);
1895 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn)
1896 return new FcvtFpSIntWDN(machInst, rd, rn);
1897 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn)
1898 return new FcvtFpSIntWDP(machInst, rd, rn);
1899 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn)
1900 return new FcvtFpSIntWDM(machInst, rd, rn);
1901 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn)
1902 return new FcvtFpSIntWDZ(machInst, rd, rn);
1903 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn)
1904 return new FcvtFpSIntXDN(machInst, rd, rn);
1905 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn)
1906 return new FcvtFpSIntXDP(machInst, rd, rn);
1907 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn)
1908 return new FcvtFpSIntXDM(machInst, rd, rn);
1909 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn)
1910 return new FcvtFpSIntXDZ(machInst, rd, rn);
1911 default:
1912 return new Unknown64(machInst);
1913 }
1914 case 0x1:
1915 switch ((switchVal2 << 2) | rmode) {
1916 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn)
1917 return new FcvtFpUIntWSN(machInst, rd, rn);
1918 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn)
1919 return new FcvtFpUIntWSP(machInst, rd, rn);
1920 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn)
1921 return new FcvtFpUIntWSM(machInst, rd, rn);
1922 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn)
1923 return new FcvtFpUIntWSZ(machInst, rd, rn);
1924 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn)
1925 return new FcvtFpUIntXSN(machInst, rd, rn);
1926 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn)
1927 return new FcvtFpUIntXSP(machInst, rd, rn);
1928 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn)
1929 return new FcvtFpUIntXSM(machInst, rd, rn);
1930 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn)
1931 return new FcvtFpUIntXSZ(machInst, rd, rn);
1932 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn)
1933 return new FcvtFpUIntWDN(machInst, rd, rn);
1934 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn)
1935 return new FcvtFpUIntWDP(machInst, rd, rn);
1936 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn)
1937 return new FcvtFpUIntWDM(machInst, rd, rn);
1938 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn)
1939 return new FcvtFpUIntWDZ(machInst, rd, rn);
1940 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn)
1941 return new FcvtFpUIntXDN(machInst, rd, rn);
1942 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn)
1943 return new FcvtFpUIntXDP(machInst, rd, rn);
1944 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn)
1945 return new FcvtFpUIntXDM(machInst, rd, rn);
1946 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn)
1947 return new FcvtFpUIntXDZ(machInst, rd, rn);
1948 default:
1949 return new Unknown64(machInst);
1950 }
1951 case 0x2:
1952 if (rmode != 0)
1953 return new Unknown64(machInst);
1954 switch (switchVal2) {
1955 case 0: // SCVTF Sd = convertFromInt(Wn)
1956 return new FcvtWSIntFpS(machInst, rd, rn);
1957 case 1: // SCVTF Sd = convertFromInt(Xn)
1958 return new FcvtXSIntFpS(machInst, rd, rn);
1959 case 2: // SCVTF Dd = convertFromInt(Wn)
1960 return new FcvtWSIntFpD(machInst, rd, rn);
1961 case 3: // SCVTF Dd = convertFromInt(Xn)
1962 return new FcvtXSIntFpD(machInst, rd, rn);
1963 default:
1964 return new Unknown64(machInst);
1965 }
1966 case 0x3:
1967 switch (switchVal2) {
1968 case 0: // UCVTF Sd = convertFromInt(Wn)
1969 return new FcvtWUIntFpS(machInst, rd, rn);
1970 case 1: // UCVTF Sd = convertFromInt(Xn)
1971 return new FcvtXUIntFpS(machInst, rd, rn);
1972 case 2: // UCVTF Dd = convertFromInt(Wn)
1973 return new FcvtWUIntFpD(machInst, rd, rn);
1974 case 3: // UCVTF Dd = convertFromInt(Xn)
1975 return new FcvtXUIntFpD(machInst, rd, rn);
1976 default:
1977 return new Unknown64(machInst);
1978 }
1979 case 0x4:
1980 if (rmode != 0)
1981 return new Unknown64(machInst);
1982 switch (switchVal2) {
1983 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn)
1984 return new FcvtFpSIntWSA(machInst, rd, rn);
1985 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn)
1986 return new FcvtFpSIntXSA(machInst, rd, rn);
1987 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1988 return new FcvtFpSIntWDA(machInst, rd, rn);
1989 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn)
1990 return new FcvtFpSIntXDA(machInst, rd, rn);
1991 default:
1992 return new Unknown64(machInst);
1993 }
1994 case 0x5:
1995 switch (switchVal2) {
1996 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn)
1997 return new FcvtFpUIntWSA(machInst, rd, rn);
1998 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn)
1999 return new FcvtFpUIntXSA(machInst, rd, rn);
2000 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn)
2001 return new FcvtFpUIntWDA(machInst, rd, rn);
2002 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn)
2003 return new FcvtFpUIntXDA(machInst, rd, rn);
2004 default:
2005 return new Unknown64(machInst);
2006 }
2007 case 0x06:
2008 switch (switchVal2) {
2009 case 0: // FMOV Wd = Sn
2010 if (rmode != 0)
2011 return new Unknown64(machInst);
2012 return new FmovRegCoreW(machInst, rd, rn);
2013 case 3: // FMOV Xd = Dn
2014 if (rmode != 0)
2015 return new Unknown64(machInst);
2016 return new FmovRegCoreX(machInst, rd, rn);
2017 case 5: // FMOV Xd = Vn<127:64>
2018 if (rmode != 1)
2019 return new Unknown64(machInst);
2020 return new FmovURegCoreX(machInst, rd, rn);
2021 default:
2022 return new Unknown64(machInst);
2023 }
2024 break;
2025 case 0x07:
2026 switch (switchVal2) {
2027 case 0: // FMOV Sd = Wn
2028 if (rmode != 0)
2029 return new Unknown64(machInst);
2030 return new FmovCoreRegW(machInst, rd, rn);
2031 case 3: // FMOV Xd = Dn
2032 if (rmode != 0)
2033 return new Unknown64(machInst);
2034 return new FmovCoreRegX(machInst, rd, rn);
2035 case 5: // FMOV Xd = Vn<127:64>
2036 if (rmode != 1)
2037 return new Unknown64(machInst);
2038 return new FmovUCoreRegX(machInst, rd, rn);
2039 default:
2040 return new Unknown64(machInst);
2041 }
2042 break;
2043 default: // Warning! missing cases in switch statement above, that still need to be added
2044 return new Unknown64(machInst);
2045 }
2046 }
2047 M5_UNREACHABLE;
2048 case 0x1:
2049 {
2050 if (bits(machInst, 31) ||
2051 bits(machInst, 29) ||
2052 bits(machInst, 23)) {
2053 return new Unknown64(machInst);
2054 }
2055 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16);
2056 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5);
2057 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0);
2058 ConditionCode cond =
2059 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2060 uint8_t switchVal = (bits(machInst, 4) << 0) |
2061 (bits(machInst, 22) << 1);
2062 // 31:23=000111100, 21=1, 11:10=01
2063 switch (switchVal) {
2064 case 0x0:
2065 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv
2066 return new FCCmpRegS(machInst, rn, rm, cond, imm);
2067 case 0x1:
2068 // FCCMP flags = if cond then compareSignaling(Sn,Sm)
2069 // else #nzcv
2070 return new FCCmpERegS(machInst, rn, rm, cond, imm);
2071 case 0x2:
2072 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv
2073 return new FCCmpRegD(machInst, rn, rm, cond, imm);
2074 case 0x3:
2075 // FCCMP flags = if cond then compareSignaling(Dn,Dm)
2076 // else #nzcv
2077 return new FCCmpERegD(machInst, rn, rm, cond, imm);
2078 default:
2079 return new Unknown64(machInst);
2080 }
2081 }
2082 case 0x2:
2083 {
2084 if (bits(machInst, 31) ||
2085 bits(machInst, 29) ||
2086 bits(machInst, 23)) {
2087 return new Unknown64(machInst);
2088 }
2089 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2090 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2091 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2092 uint8_t switchVal = (bits(machInst, 15, 12) << 0) |
2093 (bits(machInst, 22) << 4);
2094 switch (switchVal) {
2095 case 0x00: // FMUL Sd = Sn * Sm
2096 return new FMulS(machInst, rd, rn, rm);
2097 case 0x10: // FMUL Dd = Dn * Dm
2098 return new FMulD(machInst, rd, rn, rm);
2099 case 0x01: // FDIV Sd = Sn / Sm
2100 return new FDivS(machInst, rd, rn, rm);
2101 case 0x11: // FDIV Dd = Dn / Dm
2102 return new FDivD(machInst, rd, rn, rm);
2103 case 0x02: // FADD Sd = Sn + Sm
2104 return new FAddS(machInst, rd, rn, rm);
2105 case 0x12: // FADD Dd = Dn + Dm
2106 return new FAddD(machInst, rd, rn, rm);
2107 case 0x03: // FSUB Sd = Sn - Sm
2108 return new FSubS(machInst, rd, rn, rm);
2109 case 0x13: // FSUB Dd = Dn - Dm
2110 return new FSubD(machInst, rd, rn, rm);
2111 case 0x04: // FMAX Sd = max(Sn, Sm)
2112 return new FMaxS(machInst, rd, rn, rm);
2113 case 0x14: // FMAX Dd = max(Dn, Dm)
2114 return new FMaxD(machInst, rd, rn, rm);
2115 case 0x05: // FMIN Sd = min(Sn, Sm)
2116 return new FMinS(machInst, rd, rn, rm);
2117 case 0x15: // FMIN Dd = min(Dn, Dm)
2118 return new FMinD(machInst, rd, rn, rm);
2119 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm)
2120 return new FMaxNMS(machInst, rd, rn, rm);
2121 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm)
2122 return new FMaxNMD(machInst, rd, rn, rm);
2123 case 0x07: // FMINNM Sd = minNum(Sn, Sm)
2124 return new FMinNMS(machInst, rd, rn, rm);
2125 case 0x17: // FMINNM Dd = minNum(Dn, Dm)
2126 return new FMinNMD(machInst, rd, rn, rm);
2127 case 0x08: // FNMUL Sd = -(Sn * Sm)
2128 return new FNMulS(machInst, rd, rn, rm);
2129 case 0x18: // FNMUL Dd = -(Dn * Dm)
2130 return new FNMulD(machInst, rd, rn, rm);
2131 default:
2132 return new Unknown64(machInst);
2133 }
2134 }
2135 case 0x3:
2136 {
2137 if (bits(machInst, 31) || bits(machInst, 29))
2138 return new Unknown64(machInst);
2139 uint8_t type = bits(machInst, 23, 22);
2140 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0);
2141 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5);
2142 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16);
2143 ConditionCode cond =
2144 (ConditionCode)(uint8_t)(bits(machInst, 15, 12));
2145 if (type == 0) // FCSEL Sd = if cond then Sn else Sm
2146 return new FCSelS(machInst, rd, rn, rm, cond);
2147 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm
2148 return new FCSelD(machInst, rd, rn, rm, cond);
2149 else
2150 return new Unknown64(machInst);
2151 }
2152 default:
2153 M5_UNREACHABLE;
2154 }
2155 }
2156 M5_UNREACHABLE;
2157 }
2158}
2159}};
2160
2161output decoder {{
2162namespace Aarch64
2163{
2164 StaticInstPtr
2165 decodeAdvSIMDScalar(ExtMachInst machInst)
2166 {
2167 if (bits(machInst, 24) == 1) {
2168 if (bits(machInst, 10) == 0) {
2169 return decodeNeonScIndexedElem(machInst);
2170 } else if (bits(machInst, 23) == 0) {
2171 return decodeNeonScShiftByImm(machInst);
2172 }
2173 } else if (bits(machInst, 21) == 1) {
2174 if (bits(machInst, 10) == 1) {
2175 return decodeNeonSc3Same(machInst);
2176 } else if (bits(machInst, 11) == 0) {
2177 return decodeNeonSc3Diff(machInst);
2178 } else if (bits(machInst, 20, 17) == 0x0) {
2179 return decodeNeonSc2RegMisc(machInst);
2180 } else if (bits(machInst, 20, 17) == 0x4) {
2181 return decodeCryptoTwoRegSHA(machInst);
2182 } else if (bits(machInst, 20, 17) == 0x8) {
2183 return decodeNeonScPwise(machInst);
2184 } else {
2185 return new Unknown64(machInst);
2186 }
2187 } else if (bits(machInst, 23, 22) == 0 &&
2188 bits(machInst, 15) == 0) {
2189 if (bits(machInst, 10) == 1) {
2190 return decodeNeonScCopy(machInst);
2191 } else {
2192 return decodeCryptoThreeRegSHA(machInst);
2193 }
2194 } else {
2195 return new Unknown64(machInst);
2196 }
2197 return new FailUnimplemented("Unhandled Case6", machInst);
2198 }
2199}
2200}};
2201
2202output decoder {{
2203namespace Aarch64
2204{
2205 template <typename DecoderFeatures>
2206 StaticInstPtr
2207 decodeFpAdvSIMD(ExtMachInst machInst)
2208 {
2209
2210 if (bits(machInst, 28) == 0) {
2211 if (bits(machInst, 31) == 0) {
2212 return decodeAdvSIMD<DecoderFeatures>(machInst);
2213 } else {
2214 return new Unknown64(machInst);
2215 }
2216 } else if (bits(machInst, 30) == 0) {
2217 return decodeFp(machInst);
2218 } else if (bits(machInst, 31) == 0) {
2219 return decodeAdvSIMDScalar(machInst);
2220 } else {
2221 return new Unknown64(machInst);
2222 }
2223 }
2224}
2225}};
2226
2227let {{
2228 decoder_output ='''
2229namespace Aarch64
2230{'''
2231 for decoderFlavour, type_dict in decoders.iteritems():
2232 decoder_output +='''
2233template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst);
2234''' % { "df" : decoderFlavour }
2235 decoder_output +='''
2236}'''
2237}};
2238
2239output decoder {{
2240namespace Aarch64
2241{
2242 StaticInstPtr
2243 decodeGem5Ops(ExtMachInst machInst)
2244 {
2245 const uint32_t m5func = bits(machInst, 23, 16);
2246 switch (m5func) {
2247 case M5OP_ARM: return new Arm(machInst);
2248 case M5OP_QUIESCE: return new Quiesce(machInst);
2249 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst);
2250 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst);
2251 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst);
2252 case M5OP_RPNS: return new Rpns64(machInst);
2253 case M5OP_WAKE_CPU: return new WakeCPU64(machInst);
2254 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst);
2255 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst);
2256 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst);
2257 case M5OP_EXIT: return new M5exit64(machInst);
2258 case M5OP_FAIL: return new M5fail64(machInst);
2259 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst);
2260 case M5OP_INIT_PARAM: return new Initparam64(machInst);
2261 case M5OP_RESET_STATS: return new Resetstats64(machInst);
2262 case M5OP_DUMP_STATS: return new Dumpstats64(machInst);
2263 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst);
2264 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst);
2265 case M5OP_WRITE_FILE: return new M5writefile64(machInst);
2266 case M5OP_READ_FILE: return new M5readfile64(machInst);
2267 case M5OP_DEBUG_BREAK: return new M5break(machInst);
2268 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst);
2269 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst);
2270 case M5OP_PANIC: return new M5panic(machInst);
2271 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst);
2272 case M5OP_WORK_END: return new M5workend64(machInst);
2273 default: return new Unknown64(machInst);
2274 }
2275 }
2276}
2277}};
2278
2279def format Aarch64() {{
2280 decode_block = '''
2281 {
2282 using namespace Aarch64;
2283 if (bits(machInst, 27) == 0x0) {
2284 if (bits(machInst, 28) == 0x0) {
2285 if (bits(machInst, 26, 25) != 0x2) {
2286 return new Unknown64(machInst);
2287 }
2288 if (bits(machInst, 31) == 0x0) {
2289 switch (bits(machInst, 30, 29)) {
2290 case 0x0:
2291 case 0x1:
2292 case 0x2:
2293 return decodeSveInt(machInst);
2294 case 0x3:
2295 return decodeSveFp(machInst);
2296 }
2297 } else {
2298 return decodeSveMem(machInst);
2299 }
2300 } else if (bits(machInst, 26) == 0)
2301 // bit 28:26=100
2302 return decodeDataProcImm(machInst);
2303 else
2304 // bit 28:26=101
2305 return decodeBranchExcSys(machInst);
2306 } else if (bits(machInst, 25) == 0) {
2307 // bit 27=1, 25=0
2308 return decodeLoadsStores(machInst);
2309 } else if (bits(machInst, 26) == 0) {
2310 // bit 27:25=101
2311 return decodeDataProcReg(machInst);
2312 } else if (bits(machInst, 24) == 1 &&
2313 bits(machInst, 31, 28) == 0xF) {
2314 return decodeGem5Ops(machInst);
2315 } else {
2316 // bit 27:25=111
2317 switch(decoderFlavour){
2318 default:
2319 return decodeFpAdvSIMD<GenericDecoder>(machInst);
2320 }
2321 }
2322 }
2323 '''
2324}};