data.isa revision 7141:423e3dce3e27
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder.  You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39    instDecode = '''
40          case %(opcode)#x:
41            if (immShift) {
42                if (setCc) {
43                    return new %(className)sDRegCc(machInst, %(dest)s, %(op1)s,
44                                                   rm, imm5, type);
45                } else {
46                    return new %(className)sDReg(machInst, %(dest)s, %(op1)s,
47                                                 rm, imm5, type);
48                }
49            } else {
50                if (setCc) {
51                    return new %(className)sDRegRegCc(machInst, %(dest)s,
52                                                      %(op1)s, rm, rs, type);
53                } else {
54                    return new %(className)sDRegReg(machInst, %(dest)s,
55                                                    %(op1)s, rm, rs, type);
56                }
57            }
58            break;
59    '''
60
61    def instCode(opcode, mnem, dest="rd", op1="rn"):
62        global instDecode
63        return instDecode % { "className": mnem.capitalize(),
64                              "opcode": opcode,
65                              "dest": dest,
66                              "op1": op1 }
67
68    decode_block = '''
69    {
70        const bool immShift = (bits(machInst, 4) == 0);
71        const bool setCc = (bits(machInst, 20) == 1);
72        const uint32_t imm5 = bits(machInst, 11, 7);
73        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
74        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
75        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
76        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
77        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
78        switch (OPCODE) {
79    '''
80    decode_block += instCode(0x0, "and")
81    decode_block += instCode(0x1, "eor")
82    decode_block += instCode(0x2, "sub")
83    decode_block += instCode(0x3, "rsb")
84    decode_block += instCode(0x4, "add")
85    decode_block += instCode(0x5, "adc")
86    decode_block += instCode(0x6, "sbc")
87    decode_block += instCode(0x7, "rsc")
88    decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
89    decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
90    decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
91    decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
92    decode_block += instCode(0xc, "orr")
93    decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
94    decode_block += instCode(0xe, "bic")
95    decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
96    decode_block += '''
97          default:
98            return new Unknown(machInst);
99        }
100    }
101    '''
102}};
103
104def format ArmDataProcImm() {{
105    instDecode = '''
106          case %(opcode)#x:
107            if (setCc) {
108                return new %(className)sDImmCc(machInst, %(dest)s, %(op1)s,
109                                               imm, rotC);
110            } else {
111                return new %(className)sDImm(machInst, %(dest)s, %(op1)s,
112                                             imm, rotC);
113            }
114            break;
115    '''
116
117    def instCode(opcode, mnem, dest="rd", op1="rn"):
118        global instDecode
119        return instDecode % { "className": mnem.capitalize(),
120                              "opcode": opcode,
121                              "dest": dest,
122                              "op1": op1 }
123
124    decode_block = '''
125    {
126        const bool setCc = (bits(machInst, 20) == 1);
127        const uint32_t unrotated = bits(machInst, 7, 0);
128        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
129        const bool rotC = (rotation != 0);
130        const uint32_t imm = rotate_imm(unrotated, rotation);
131        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
132        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
133        switch (OPCODE) {
134    '''
135    decode_block += instCode(0x0, "and")
136    decode_block += instCode(0x1, "eor")
137    decode_block += instCode(0x2, "sub")
138    decode_block += instCode(0x3, "rsb")
139    decode_block += instCode(0x4, "add")
140    decode_block += instCode(0x5, "adc")
141    decode_block += instCode(0x6, "sbc")
142    decode_block += instCode(0x7, "rsc")
143    decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
144    decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
145    decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
146    decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
147    decode_block += instCode(0xc, "orr")
148    decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
149    decode_block += instCode(0xe, "bic")
150    decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
151    decode_block += '''
152          default:
153            return new Unknown(machInst);
154        }
155    }
156    '''
157}};
158
159def format Thumb16ShiftAddSubMoveCmp() {{
160    decode_block = '''
161    {
162        const uint32_t imm5 = bits(machInst, 10, 6);
163        const uint32_t imm3 = bits(machInst, 8, 6);
164        const uint32_t imm8 = bits(machInst, 7, 0);
165        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
166        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
167        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
168        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
169        switch (bits(machInst, 13, 11)) {
170          case 0x0: // lsl
171            return new MovDReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
172          case 0x1: // lsr
173            return new MovDReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
174          case 0x2: // asr
175            return new MovDReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
176          case 0x3:
177            switch (bits(machInst, 10, 9)) {
178              case 0x0:
179                return new AddDReg(machInst, rd, rn, rm, 0, LSL);
180              case 0x1:
181                return new SubDReg(machInst, rd, rn, rm, 0, LSL);
182              case 0x2:
183                return new AddDImm(machInst, rd, rn, imm3, true);
184              case 0x3:
185                return new SubDImm(machInst, rd, rn, imm3, true);
186            }
187          case 0x4:
188            return new MovDImm(machInst, rd8, INTREG_ZERO, imm8, true);
189          case 0x5:
190            return new CmpDImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
191          case 0x6:
192            return new AddDImm(machInst, rd8, rd8, imm8, true);
193          case 0x7:
194            return new SubDImm(machInst, rd8, rd8, imm8, true);
195        }
196    }
197    '''
198}};
199
200def format Thumb16DataProcessing() {{
201    decode_block = '''
202    {
203        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
204        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
205        switch (bits(machInst, 9, 6)) {
206          case 0x0:
207            return new AndDReg(machInst, rdn, rdn, rm, 0, LSL);
208          case 0x1:
209            return new EorDReg(machInst, rdn, rdn, rm, 0, LSL);
210          case 0x2: //lsl
211            return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
212          case 0x3: //lsr
213            return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
214          case 0x4: //asr
215            return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
216          case 0x5:
217            return new AdcDReg(machInst, rdn, rdn, rm, 0, LSL);
218          case 0x6:
219            return new SbcDReg(machInst, rdn, rdn, rm, 0, LSL);
220          case 0x7: // ror
221            return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
222          case 0x8:
223            return new TstDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
224          case 0x9:
225            return new RsbDImm(machInst, rdn, rm, 0, true);
226          case 0xa:
227            return new CmpDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
228          case 0xb:
229            return new CmnDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
230          case 0xc:
231            return new OrrDReg(machInst, rdn, rdn, rm, 0, LSL);
232          case 0xd:
233            //XXX Implement me!
234            return new WarnUnimplemented("mul", machInst);
235          case 0xe:
236            return new BicDReg(machInst, rdn, rdn, rm, 0, LSL);
237          case 0xf:
238            return new MvnDReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
239        }
240    }
241    '''
242}};
243
244def format Thumb16SpecDataAndBx() {{
245    decode_block = '''
246    {
247        const IntRegIndex rdn =
248            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
249                                    (bits(machInst, 7) << 3));
250        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
251        switch (bits(machInst, 9, 8)) {
252          case 0x0:
253            return new AddDReg(machInst, rdn, rdn, rm, 0, LSL);
254          case 0x1:
255            return new CmpDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
256          case 0x2:
257            return new MovDReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
258          case 0x3:
259            if (bits(machInst, 7) == 0)
260                return new WarnUnimplemented("bx", machInst);
261            else
262                // The register version.
263                return new WarnUnimplemented("blx", machInst);
264        }
265    }
266    '''
267}};
268
269def format Thumb16Adr() {{
270    decode_block = '''
271    {
272        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
273        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
274        return new AddDImm(machInst, rd, INTREG_PC, imm8, true);
275    }
276    '''
277}};
278
279def format Thumb16AddSp() {{
280    decode_block = '''
281    {
282        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
283        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
284        return new AddDImm(machInst, rd, INTREG_SP, imm8, true);
285    }
286    '''
287}};
288
289def format Thumb16Misc() {{
290    decode_block = '''
291    {
292        switch (bits(machInst, 11, 8)) {
293          case 0x0:
294            if (bits(machInst, 7)) {
295                return new SubDImm(machInst, INTREG_SP, INTREG_SP,
296                                   bits(machInst, 6, 0) << 2, true);
297            } else {
298                return new AddDImm(machInst, INTREG_SP, INTREG_SP,
299                                   bits(machInst, 6, 0) << 2, true);
300            }
301          case 0x1:
302            return new WarnUnimplemented("cbz", machInst);
303          case 0x2:
304            switch (bits(machInst, 7, 6)) {
305              case 0x0:
306                return new WarnUnimplemented("sxth", machInst);
307              case 0x1:
308                return new WarnUnimplemented("sxtb", machInst);
309              case 0x2:
310                return new WarnUnimplemented("uxth", machInst);
311              case 0x3:
312                return new WarnUnimplemented("uxtb", machInst);
313            }
314          case 0x3:
315            return new WarnUnimplemented("cbnz", machInst);
316          case 0x4:
317          case 0x5:
318            return new WarnUnimplemented("push", machInst);
319          case 0x6:
320            {
321                const uint32_t opBits = bits(machInst, 7, 5);
322                if (opBits == 2) {
323                    return new WarnUnimplemented("setend", machInst);
324                } else if (opBits == 3) {
325                    return new WarnUnimplemented("cps", machInst);
326                }
327            }
328          case 0x9:
329            return new WarnUnimplemented("cbz", machInst);
330          case 0xa:
331            switch (bits(machInst, 7, 5)) {
332              case 0x0:
333                return new WarnUnimplemented("rev", machInst);
334              case 0x1:
335                return new WarnUnimplemented("rev16", machInst);
336              case 0x3:
337                return new WarnUnimplemented("revsh", machInst);
338              default:
339                break;
340            }
341            break;
342          case 0xb:
343            return new WarnUnimplemented("cbnz", machInst);
344          case 0xc:
345          case 0xd:
346            return new WarnUnimplemented("pop", machInst);
347          case 0xe:
348            return new WarnUnimplemented("bkpt", machInst);
349          case 0xf:
350            if (bits(machInst, 3, 0) != 0)
351                return new WarnUnimplemented("it", machInst);
352            switch (bits(machInst, 7, 4)) {
353              case 0x0:
354                return new WarnUnimplemented("nop", machInst);
355              case 0x1:
356                return new WarnUnimplemented("yield", machInst);
357              case 0x2:
358                return new WarnUnimplemented("wfe", machInst);
359              case 0x3:
360                return new WarnUnimplemented("wfi", machInst);
361              case 0x4:
362                return new WarnUnimplemented("sev", machInst);
363              default:
364                return new WarnUnimplemented("unallocated_hint", machInst);
365            }
366          default:
367            break;
368        }
369        return new Unknown(machInst);
370    }
371    '''
372}};
373
374def format Thumb32DataProcModImm() {{
375
376    def decInst(mnem, dest="rd", op1="rn"):
377        return '''
378            if (s) {
379                return new %(mnem)sDImmCc(machInst, %(dest)s,
380                                          %(op1)s, imm, true);
381            } else {
382                return new %(mnem)sDImm(machInst, %(dest)s,
383                                        %(op1)s, imm, true);
384            }
385        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
386
387    decode_block = '''
388    {
389        const uint32_t op = bits(machInst, 24, 21);
390        const bool s = (bits(machInst, 20) == 1);
391        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
392        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
393        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
394                                 bits(machInst, 14, 12);
395        const uint32_t dataImm = bits(machInst, 7, 0);
396        const uint32_t imm = modified_imm(ctrlImm, dataImm);
397        switch (op) {
398          case 0x0:
399            if (rd == INTREG_PC) {
400                %(tst)s
401            } else {
402                %(and)s
403            }
404          case 0x1:
405            %(bic)s
406          case 0x2:
407            if (rn == INTREG_PC) {
408                %(mov)s
409            } else {
410                %(orr)s
411            }
412          case 0x3:
413            if (rn == INTREG_PC) {
414                %(mvn)s
415            } else {
416                %(orn)s
417            }
418          case 0x4:
419            if (rd == INTREG_PC) {
420                %(teq)s
421            } else {
422                %(eor)s
423            }
424          case 0x8:
425            if (rd == INTREG_PC) {
426                %(cmn)s
427            } else {
428                %(add)s
429            }
430          case 0xa:
431            %(adc)s
432          case 0xb:
433            %(sbc)s
434          case 0xd:
435            if (rd == INTREG_PC) {
436                %(cmp)s
437            } else {
438                %(sub)s
439            }
440          case 0xe:
441            %(rsb)s
442          default:
443            return new Unknown(machInst);
444        }
445    }
446    ''' % {
447        "tst" : decInst("Tst", "INTREG_ZERO"),
448        "and" : decInst("And"),
449        "bic" : decInst("Bic"),
450        "mov" : decInst("Mov", op1="INTREG_ZERO"),
451        "orr" : decInst("Orr"),
452        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
453        "orn" : decInst("Orn"),
454        "teq" : decInst("Teq", dest="INTREG_ZERO"),
455        "eor" : decInst("Eor"),
456        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
457        "add" : decInst("Add"),
458        "adc" : decInst("Adc"),
459        "sbc" : decInst("Sbc"),
460        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
461        "sub" : decInst("Sub"),
462        "rsb" : decInst("Rsb")
463    }
464}};
465
466def format Thumb32DataProcShiftReg() {{
467
468    def decInst(mnem, dest="rd", op1="rn"):
469        return '''
470            if (s) {
471                return new %(mnem)sDRegCc(machInst, %(dest)s,
472                                          %(op1)s, rm, amt, type);
473            } else {
474                return new %(mnem)sDReg(machInst, %(dest)s,
475                                        %(op1)s, rm, amt, type);
476            }
477        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
478
479    decode_block = '''
480    {
481        const uint32_t op = bits(machInst, 24, 21);
482        const bool s = (bits(machInst, 20) == 1);
483        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
484        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
485        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
486        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
487                              bits(machInst, 7, 6);
488        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
489        switch (op) {
490          case 0x0:
491            if (rd == INTREG_PC) {
492                %(tst)s
493            } else {
494                %(and)s
495            }
496          case 0x1:
497            %(bic)s
498          case 0x2:
499            if (rn == INTREG_PC) {
500                %(mov)s
501            } else {
502                %(orr)s
503            }
504          case 0x3:
505            if (rn == INTREG_PC) {
506                %(mvn)s
507            } else {
508                %(orn)s
509            }
510          case 0x4:
511            if (rd == INTREG_PC) {
512                %(teq)s
513            } else {
514                %(eor)s
515            }
516          case 0x6:
517            return new WarnUnimplemented("pkh", machInst);
518          case 0x8:
519            if (rd == INTREG_PC) {
520                %(cmn)s
521            } else {
522                %(add)s
523            }
524          case 0xa:
525            %(adc)s
526          case 0xb:
527            %(sbc)s
528          case 0xd:
529            if (rd == INTREG_PC) {
530                %(cmp)s
531            } else {
532                %(sub)s
533            }
534          case 0xe:
535            %(rsb)s
536          default:
537            return new Unknown(machInst);
538        }
539    }
540    ''' % {
541        "tst" : decInst("Tst", "INTREG_ZERO"),
542        "and" : decInst("And"),
543        "bic" : decInst("Bic"),
544        "mov" : decInst("Mov", op1="INTREG_ZERO"),
545        "orr" : decInst("Orr"),
546        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
547        "orn" : decInst("Orn"),
548        "teq" : decInst("Teq", "INTREG_ZERO"),
549        "eor" : decInst("Eor"),
550        "cmn" : decInst("Cmn", "INTREG_ZERO"),
551        "add" : decInst("Add"),
552        "adc" : decInst("Adc"),
553        "sbc" : decInst("Sbc"),
554        "cmp" : decInst("Cmp", "INTREG_ZERO"),
555        "sub" : decInst("Sub"),
556        "rsb" : decInst("Rsb")
557    }
558}};
559