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