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