]> git.saurik.com Git - apple/javascriptcore.git/blob - disassembler/ARMv7/ARMv7DOpcode.h
13e209db77ccedd82975049ded74d678c9105c6a
[apple/javascriptcore.git] / disassembler / ARMv7 / ARMv7DOpcode.h
1 /*
2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef ARMv7DOpcode_h
27 #define ARMv7DOpcode_h
28
29 #if USE(ARMV7_DISASSEMBLER)
30
31 #include <stdint.h>
32 #include <wtf/Assertions.h>
33
34 namespace JSC { namespace ARMv7Disassembler {
35
36 class ARMv7DOpcode {
37 public:
38 static void init();
39
40 ARMv7DOpcode()
41 : m_opcode(0)
42 , m_bufferOffset(0)
43 {
44 init();
45
46 for (unsigned i = 0; i < 4; i++)
47 m_ifThenConditions[i] = CondNone;
48
49 endITBlock();
50
51 m_formatBuffer[0] = '\0';
52 }
53
54 const char* disassemble(uint16_t*& currentPC);
55
56 protected:
57 const unsigned RegSP = 0xd;
58 const unsigned RegLR = 0xe;
59 const unsigned RegPC = 0xf;
60
61 void fetchOpcode(uint16_t*&);
62 bool is32BitInstruction() { return (m_opcode & 0xfffff800) > 0xe000; }
63 bool isFPInstruction() { return (m_opcode & 0xfc000e00) == 0xec000a00; }
64
65 static const char* const s_conditionNames[16];
66 static const char* const s_shiftNames[4];
67 static const char* const s_optionName[8];
68 static const char* const s_specialRegisterNames[3];
69
70 static const char* conditionName(unsigned condition) { return s_conditionNames[condition & 0xf]; }
71 static const char* shiftName(unsigned shiftValue) { return s_shiftNames[shiftValue & 0x3]; }
72
73 bool inITBlock() { return m_ITConditionIndex < m_ITBlocksize; }
74 bool startingITBlock() { return m_ITConditionIndex == m_ITBlocksize + 1; }
75
76 void startITBlock(unsigned, unsigned);
77 void saveITConditionAt(unsigned, unsigned);
78 void endITBlock()
79 {
80 m_currentITCondition = CondNone;
81 m_ITConditionIndex = 0;
82 m_ITBlocksize = 0;
83 }
84
85 void bufferPrintf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
86 void appendInstructionName(const char*, bool addS = false);
87
88 void appendInstructionNameNoITBlock(const char* instructionName)
89 {
90 bufferPrintf(" %-7.7s", instructionName);
91 }
92
93 void appendRegisterName(unsigned);
94 void appendRegisterList(unsigned);
95 void appendFPRegisterName(char, unsigned);
96
97 void appendSeparator()
98 {
99 bufferPrintf(", ");
100 }
101
102 void appendCharacter(const char c)
103 {
104 bufferPrintf("%c", c);
105 }
106
107 void appendString(const char* string)
108 {
109 bufferPrintf("%s", string);
110 }
111
112 void appendShiftType(unsigned shiftValue)
113 {
114 bufferPrintf("%s ", shiftName(shiftValue));
115 }
116
117 void appendSignedImmediate(int immediate)
118 {
119 bufferPrintf("#%d", immediate);
120 }
121
122 void appendUnsignedImmediate(unsigned immediate)
123 {
124 bufferPrintf("#%u", immediate);
125 }
126
127 void appendPCRelativeOffset(int32_t immediate)
128 {
129 bufferPrintf("0x%x", reinterpret_cast<uint32_t>(m_currentPC + immediate));
130 }
131
132 void appendShiftAmount(unsigned amount)
133 {
134 bufferPrintf("lsl #%u", 16 * amount);
135 }
136
137 static const int bufferSize = 81;
138 static const unsigned char CondNone = 0xe;
139 static const unsigned MaxITBlockSize = 4;
140
141 char m_formatBuffer[bufferSize];
142 unsigned char m_ifThenConditions[MaxITBlockSize];
143 uint16_t* m_currentPC;
144 uint32_t m_opcode;
145 int m_bufferOffset;
146 int m_currentITCondition;
147 unsigned m_ITConditionIndex;
148 unsigned m_ITBlocksize;
149
150 private:
151 static bool s_initialized;
152 };
153
154 #define DEFINE_STATIC_FORMAT16(klass, thisObj) \
155 static const char* format(ARMv7D16BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
156
157 class ARMv7D16BitOpcode : public ARMv7DOpcode {
158 private:
159 class OpcodeGroup {
160 public:
161 OpcodeGroup(uint16_t opcodeMask, uint16_t opcodePattern, const char* (*format)(ARMv7D16BitOpcode*))
162 : m_opcodeMask(opcodeMask)
163 , m_opcodePattern(opcodePattern)
164 , m_format(format)
165 , m_next(0)
166 {
167 }
168
169 void setNext(OpcodeGroup* next)
170 {
171 m_next = next;
172 }
173
174 OpcodeGroup* next()
175 {
176 return m_next;
177 }
178
179 bool matches(uint16_t opcode)
180 {
181 return (opcode & m_opcodeMask) == m_opcodePattern;
182 }
183
184 const char* format(ARMv7D16BitOpcode* thisObj)
185 {
186 return m_format(thisObj);
187 }
188
189 public:
190 static const unsigned opcodeTableSize = 32;
191 static const unsigned opcodeTableMask = opcodeTableSize-1;
192
193 // private:
194 uint16_t m_opcodeMask;
195 uint16_t m_opcodePattern;
196 const char* (*m_format)(ARMv7D16BitOpcode*);
197 OpcodeGroup* m_next;
198 };
199
200 public:
201 static void init();
202
203 const char* defaultFormat();
204 const char* doDisassemble();
205
206 protected:
207 unsigned rm() { return (m_opcode >> 3) & 0x7; }
208 unsigned rd() { return m_opcode & 0x7; }
209 unsigned opcodeGroupNumber(unsigned opcode) { return (opcode >> 11) & OpcodeGroup::opcodeTableMask; }
210
211 private:
212 static OpcodeGroup* opcodeTable[OpcodeGroup::opcodeTableSize];
213 };
214
215 class ARMv7DOpcodeAddRegisterT2 : public ARMv7D16BitOpcode {
216 public:
217 static const uint16_t s_mask = 0xff00;
218 static const uint16_t s_pattern = 0x4400;
219
220 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddRegisterT2, thisObj);
221
222 protected:
223 const char* format();
224
225 unsigned rdn() { return ((m_opcode >> 4) & 0x8) | (m_opcode & 0x7); }
226 unsigned rm() { return ((m_opcode >> 3) & 0xf); }
227 };
228
229 class ARMv7DOpcodeAddSPPlusImmediate : public ARMv7D16BitOpcode {
230 public:
231 static const uint16_t s_mask = 0xf800;
232 static const uint16_t s_pattern = 0xc800;
233
234 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSPPlusImmediate, thisObj);
235
236 protected:
237 const char* format();
238
239 unsigned rd() { return (m_opcode >> 8) & 0x7; }
240 unsigned immediate8() { return m_opcode & 0x0ff; }
241 };
242
243 class ARMv7DOpcodeAddSubtract : public ARMv7D16BitOpcode {
244 protected:
245 static const char* const s_opNames[2];
246 };
247
248 class ARMv7DOpcodeAddSubtractT1 : public ARMv7DOpcodeAddSubtract {
249 public:
250 static const uint16_t s_mask = 0xfc00;
251 static const uint16_t s_pattern = 0x1800;
252
253 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractT1, thisObj);
254
255 protected:
256 const char* format();
257
258 const char* opName() { return s_opNames[op()]; }
259
260 unsigned op() { return (m_opcode >> 9) & 0x1; }
261 unsigned rm() { return (m_opcode >> 6) & 0x7; }
262 unsigned rn() { return (m_opcode >> 3) & 0x7; }
263 };
264
265 class ARMv7DOpcodeAddSubtractImmediate3 : public ARMv7DOpcodeAddSubtract {
266 public:
267 static const uint16_t s_mask = 0xfc00;
268 static const uint16_t s_pattern = 0x1c00;
269
270 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractImmediate3, thisObj);
271
272 protected:
273 const char* format();
274
275 const char* opName() { return s_opNames[op()]; }
276
277 unsigned op() { return (m_opcode >> 9) & 0x1; }
278 unsigned immediate3() { return (m_opcode >> 6) & 0x7; }
279 unsigned rn() { return (m_opcode >> 3) & 0x7; }
280 };
281
282 class ARMv7DOpcodeAddSubtractImmediate8 : public ARMv7DOpcodeAddSubtract {
283 public:
284 static const uint16_t s_mask = 0xf000;
285 static const uint16_t s_pattern = 0x3000;
286
287 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractImmediate8, thisObj);
288
289 protected:
290 const char* format();
291
292 const char* opName() { return s_opNames[op()]; }
293
294 unsigned op() { return (m_opcode >> 11) & 0x1; }
295 unsigned rdn() { return (m_opcode >> 8) & 0x7; }
296 unsigned immediate8() { return m_opcode & 0xff; }
297 };
298
299 class ARMv7DOpcodeBranchConditionalT1 : public ARMv7D16BitOpcode {
300 public:
301 static const uint16_t s_mask = 0xf000;
302 static const uint16_t s_pattern = 0xd000;
303
304 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchConditionalT1, thisObj);
305
306 protected:
307 const char* format();
308
309 unsigned condition() { return (m_opcode >> 8) & 0xf; }
310 int offset() { return static_cast<int>(m_opcode & 0xff); }
311 };
312
313 class ARMv7DOpcodeBranchExchangeT1 : public ARMv7D16BitOpcode {
314 public:
315 static const uint16_t s_mask = 0xff00;
316 static const uint16_t s_pattern = 0x4700;
317
318 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchExchangeT1, thisObj);
319
320 protected:
321 const char* format();
322
323 const char* opName() { return (m_opcode & 0x80) ? "blx" : "bx"; }
324 unsigned rm() { return ((m_opcode >> 3) & 0xf); }
325 };
326
327 class ARMv7DOpcodeBranchT2 : public ARMv7D16BitOpcode {
328 public:
329 static const uint16_t s_mask = 0xf800;
330 static const uint16_t s_pattern = 0xe000;
331
332 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchT2, thisObj);
333
334 protected:
335 const char* format();
336
337 int immediate11() { return static_cast<int>(m_opcode & 0x7ff); }
338 };
339
340 class ARMv7DOpcodeCompareImmediateT1 : public ARMv7D16BitOpcode {
341 public:
342 static const uint16_t s_mask = 0xf800;
343 static const uint16_t s_pattern = 0x2800;
344
345 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareImmediateT1, thisObj);
346
347 protected:
348 const char* format();
349
350 unsigned rn() { return (m_opcode >> 8) & 0x3; }
351 unsigned immediate8() { return m_opcode & 0xff; }
352 };
353
354 class ARMv7DOpcodeCompareRegisterT1 : public ARMv7D16BitOpcode {
355 public:
356 static const uint16_t s_mask = 0xffc0;
357 static const uint16_t s_pattern = 0x4280;
358
359 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareRegisterT1, thisObj);
360
361 protected:
362 const char* format();
363
364 unsigned rn() { return m_opcode & 0x7; }
365 };
366
367 class ARMv7DOpcodeCompareRegisterT2 : public ARMv7D16BitOpcode {
368 public:
369 static const uint16_t s_mask = 0xff00;
370 static const uint16_t s_pattern = 0x4500;
371
372 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareRegisterT2, thisObj);
373
374 protected:
375 const char* format();
376
377 unsigned rn() { return ((m_opcode >> 4) & 0x8) | (m_opcode & 0x7); }
378 unsigned rm() { return ((m_opcode >> 3) & 0xf); }
379 };
380
381 class ARMv7DOpcodeDataProcessingRegisterT1 : public ARMv7D16BitOpcode {
382 private:
383 static const char* const s_opNames[16];
384
385 public:
386 static const uint16_t s_mask = 0xfc00;
387 static const uint16_t s_pattern = 0x4000;
388
389 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeDataProcessingRegisterT1, thisObj);
390
391 protected:
392 const char* format();
393
394 const char* opName() { return s_opNames[op()]; }
395
396 unsigned op() { return (m_opcode >> 6) & 0xf; }
397
398 unsigned rm() { return (m_opcode >> 3) & 0x7; }
399 unsigned rdn() { return m_opcode & 0x7; }
400 };
401
402 class ARMv7DOpcodeGeneratePCRelativeAddress : public ARMv7D16BitOpcode {
403 public:
404 static const uint16_t s_mask = 0xf800;
405 static const uint16_t s_pattern = 0xa000;
406
407 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeGeneratePCRelativeAddress, thisObj);
408
409 protected:
410 const char* format();
411
412 unsigned rd() { return (m_opcode >> 8) & 0x7; }
413 unsigned immediate8() { return m_opcode & 0x0ff; }
414 };
415
416 class ARMv7DOpcodeLoadFromLiteralPool : public ARMv7D16BitOpcode {
417 public:
418 static const uint16_t s_mask = 0xf800;
419 static const uint16_t s_pattern = 0x4800;
420
421 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadFromLiteralPool, thisObj);
422
423 protected:
424 const char* format();
425
426 unsigned rt() { return (m_opcode >> 8) & 0x7; }
427 unsigned immediate8() { return m_opcode & 0x0ff; }
428 };
429
430 class ARMv7DOpcodeLoadStoreRegisterImmediate : public ARMv7D16BitOpcode {
431 private:
432 static const char* const s_opNames[6];
433
434 public:
435 const char* format();
436
437 protected:
438 const char* opName() { return s_opNames[op()]; }
439
440 unsigned op() { return ((m_opcode >> 11) & 0x1f) - 0xc; }
441 unsigned immediate5() { return (m_opcode >> 6) & 0x01f; }
442 unsigned rn() { return (m_opcode >> 3) & 0x7; }
443 unsigned rt() { return m_opcode & 0x7; }
444 unsigned scale();
445 };
446
447 class ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte : public ARMv7DOpcodeLoadStoreRegisterImmediate {
448 public:
449 static const uint16_t s_mask = 0xe000;
450 static const uint16_t s_pattern = 0x6000;
451
452 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate, thisObj);
453 };
454
455 class ARMv7DOpcodeStoreRegisterImmediateHalfWord : public ARMv7DOpcodeLoadStoreRegisterImmediate {
456 public:
457 static const uint16_t s_mask = 0xf800;
458 static const uint16_t s_pattern = 0x8000;
459
460 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate, thisObj);
461 };
462
463 class ARMv7DOpcodeLoadRegisterImmediateHalfWord : public ARMv7DOpcodeLoadStoreRegisterImmediate {
464 public:
465 static const uint16_t s_mask = 0xf800;
466 static const uint16_t s_pattern = 0x8800;
467
468 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate, thisObj);
469 };
470
471 class ARMv7DOpcodeLoadStoreRegisterOffsetT1 : public ARMv7D16BitOpcode {
472 private:
473 static const char* const s_opNames[8];
474
475 public:
476 static const uint16_t s_mask = 0xf000;
477 static const uint16_t s_pattern = 0x5000;
478
479 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterOffsetT1, thisObj);
480
481 protected:
482 const char* format();
483
484 const char* opName() { return s_opNames[opB()]; }
485
486 unsigned opB() { return (m_opcode >> 9) & 0x7; }
487 unsigned rm() { return (m_opcode >> 6) & 0x7; }
488 unsigned rn() { return (m_opcode >> 3) & 0x7; }
489 unsigned rt() { return m_opcode & 0x7; }
490 };
491
492 class ARMv7DOpcodeLoadStoreRegisterSPRelative : public ARMv7D16BitOpcode {
493 private:
494 static const char* const s_opNames[8];
495
496 public:
497 static const uint16_t s_mask = 0xf000;
498 static const uint16_t s_pattern = 0x9000;
499
500 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterSPRelative, thisObj);
501
502 protected:
503 const char* format();
504
505 const char* opName() { return op() ? "ldr" : "str"; }
506
507 unsigned op() { return (m_opcode >> 11) & 0x1; }
508 unsigned rt() { return (m_opcode >> 8) & 0x7; }
509 unsigned immediate8() { return m_opcode & 0xff; }
510 };
511
512 class ARMv7DOpcodeLogicalImmediateT1 : public ARMv7D16BitOpcode {
513 public:
514 static const uint16_t s_mask = 0xe000;
515 static const uint16_t s_pattern = 0x0000;
516
517 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLogicalImmediateT1, thisObj);
518
519 protected:
520 const char* format();
521
522 const char* opName() { return shiftName(op()); }
523
524 unsigned op() { return (m_opcode >> 12) & 0x3; }
525 unsigned immediate5() { return (m_opcode >> 6) & 0x1f; }
526 };
527
528 class ARMv7DOpcodeMiscAddSubSP : public ARMv7D16BitOpcode {
529 public:
530 static const uint16_t s_mask = 0xff00;
531 static const uint16_t s_pattern = 0xb000;
532
533 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscAddSubSP, thisObj);
534
535 protected:
536 const char* format();
537
538 const char* opName() { return op() ? "sub" : "add"; }
539 unsigned op() { return (m_opcode >> 7) & 0x1; }
540 unsigned immediate7() { return m_opcode & 0x7f; }
541 };
542
543 class ARMv7DOpcodeMiscByteHalfwordOps : public ARMv7D16BitOpcode {
544 private:
545 static const char* const s_opNames[8];
546
547 public:
548 static const uint16_t s_mask = 0xf700;
549 static const uint16_t s_pattern = 0xb200;
550
551 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscByteHalfwordOps, thisObj);
552
553 protected:
554 const char* format();
555
556 const char* opName() { return s_opNames[op()]; }
557 unsigned op() { return ((m_opcode >> 9) & 0x4) || ((m_opcode >> 6) & 0x3); }
558 };
559
560 class ARMv7DOpcodeMiscBreakpointT1 : public ARMv7D16BitOpcode {
561 public:
562 static const uint16_t s_mask = 0xff00;
563 static const uint16_t s_pattern = 0xbe00;
564
565 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscBreakpointT1, thisObj);
566
567 protected:
568 const char* format();
569
570 unsigned immediate8() { return m_opcode & 0xff; }
571 };
572
573 class ARMv7DOpcodeMiscCompareAndBranch : public ARMv7D16BitOpcode {
574 public:
575 static const uint16_t s_mask = 0xf500;
576 static const uint16_t s_pattern = 0xb100;
577
578 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscCompareAndBranch, thisObj);
579
580 protected:
581 const char* format();
582
583 const char* opName() { return op() ? "cbnz" : "cbz"; }
584 unsigned op() { return (m_opcode >> 11) & 0x1; }
585 int32_t immediate6() { return ((m_opcode >> 4) & 0x20) | ((m_opcode >> 3) & 0x1f); }
586 unsigned rn() { return m_opcode & 0x7; }
587 };
588
589 class ARMv7DOpcodeMiscHint16 : public ARMv7D16BitOpcode {
590 private:
591 static const char* const s_opNames[16];
592
593 public:
594 static const uint16_t s_mask = 0xff0f;
595 static const uint16_t s_pattern = 0xbf00;
596
597 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscHint16, thisObj);
598
599 protected:
600 const char* format();
601
602 const char* opName() { return s_opNames[opA()]; }
603 unsigned opA() { return (m_opcode >> 4) & 0xf; }
604 };
605
606 class ARMv7DOpcodeMiscIfThenT1 : public ARMv7D16BitOpcode {
607 public:
608 static const uint16_t s_mask = 0xff00;
609 static const uint16_t s_pattern = 0xbf00;
610
611 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscIfThenT1, thisObj);
612
613 protected:
614 const char* format();
615
616 unsigned firstCondition() { return (m_opcode >> 4) & 0xf; }
617 unsigned mask() { return m_opcode & 0xf; }
618 };
619
620 class ARMv7DOpcodeMiscPushPop : public ARMv7D16BitOpcode {
621 public:
622 static const uint16_t s_mask = 0xf600;
623 static const uint16_t s_pattern = 0xb400;
624
625 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscPushPop, thisObj);
626
627 protected:
628 const char* format();
629
630 const char* opName() { return op() ? "pop" : "push"; }
631 unsigned op() { return (m_opcode >> 11) & 0x1; }
632 unsigned registerMask() { return ((m_opcode << 6) & 0x4000) | (m_opcode & 0xff); }
633 };
634
635 class ARMv7DOpcodeMoveImmediateT1 : public ARMv7D16BitOpcode {
636 public:
637 static const uint16_t s_mask = 0xf800;
638 static const uint16_t s_pattern = 0x2000;
639
640 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveImmediateT1, thisObj);
641
642 protected:
643 const char* format();
644
645 unsigned rd() { return (m_opcode >> 8) & 0x3; }
646 unsigned immediate8() { return m_opcode & 0xff; }
647 };
648
649 class ARMv7DOpcodeMoveRegisterT1 : public ARMv7D16BitOpcode {
650 public:
651 static const uint16_t s_mask = 0xff00;
652 static const uint16_t s_pattern = 0x4600;
653
654 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveRegisterT1, thisObj);
655
656 protected:
657 const char* format();
658
659 unsigned rd() { return ((m_opcode >> 4) & 0x8) | (m_opcode & 0x7); }
660 unsigned rm() { return ((m_opcode >> 3) & 0xf); }
661 };
662
663 // 32 Bit instructions
664
665 #define DEFINE_STATIC_FORMAT32(klass, thisObj) \
666 static const char* format(ARMv7D32BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
667
668 class ARMv7D32BitOpcode : public ARMv7DOpcode {
669 private:
670 class OpcodeGroup {
671 public:
672 OpcodeGroup(uint32_t opcodeMask, uint32_t opcodePattern, const char* (*format)(ARMv7D32BitOpcode*))
673 : m_opcodeMask(opcodeMask)
674 , m_opcodePattern(opcodePattern)
675 , m_format(format)
676 , m_next(0)
677 {
678 }
679
680 void setNext(OpcodeGroup* next)
681 {
682 m_next = next;
683 }
684
685 OpcodeGroup* next()
686 {
687 return m_next;
688 }
689
690 bool matches(uint32_t opcode)
691 {
692 return (opcode & m_opcodeMask) == m_opcodePattern;
693 }
694
695 const char* format(ARMv7D32BitOpcode* thisObj)
696 {
697 return m_format(thisObj);
698 }
699
700 public:
701 static const unsigned opcodeTableSize = 16;
702 static const unsigned opcodeTableMask = opcodeTableSize-1;
703
704 private:
705 uint32_t m_opcodeMask;
706 uint32_t m_opcodePattern;
707 const char* (*m_format)(ARMv7D32BitOpcode*);
708 OpcodeGroup* m_next;
709 };
710
711 public:
712 static void init();
713
714 const char* defaultFormat();
715 const char* doDisassemble();
716
717 protected:
718 unsigned rd() { return (m_opcode >> 8) & 0xf; }
719 unsigned rm() { return m_opcode & 0xf; }
720 unsigned rn() { return (m_opcode >> 16) & 0xf; }
721 unsigned rt() { return (m_opcode >> 12) & 0xf; }
722
723 unsigned opcodeGroupNumber(unsigned opcode) { return (opcode >> 25) & OpcodeGroup::opcodeTableMask; }
724
725 private:
726 static OpcodeGroup* opcodeTable[OpcodeGroup::opcodeTableSize];
727 };
728
729 class ARMv7DOpcodeBranchRelative : public ARMv7D32BitOpcode {
730 protected:
731 unsigned sBit() { return (m_opcode >> 26) & 0x1; }
732 unsigned j1() { return (m_opcode >> 13) & 0x1; }
733 unsigned j2() { return (m_opcode >> 11) & 0x1; }
734 unsigned immediate11() { return m_opcode & 0x7ff; }
735 };
736
737 class ARMv7DOpcodeConditionalBranchT3 : public ARMv7DOpcodeBranchRelative {
738 public:
739 static const uint32_t s_mask = 0xf800d000;
740 static const uint32_t s_pattern = 0xf0008000;
741
742 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeConditionalBranchT3, thisObj);
743
744 protected:
745 const char* format();
746
747 int32_t offset() { return ((static_cast<int32_t>(sBit() << 31)) >> 12) | static_cast<int32_t>((j1() << 18) | (j2() << 17) | (immediate6() << 11) | immediate11()); }
748 unsigned condition() { return (m_opcode >> 22) & 0xf; }
749 unsigned immediate6() { return (m_opcode >> 16) & 0x3f; }
750 };
751
752 class ARMv7DOpcodeBranchOrBranchLink : public ARMv7DOpcodeBranchRelative {
753 public:
754 static const uint32_t s_mask = 0xf8009000;
755 static const uint32_t s_pattern = 0xf0009000;
756
757 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeBranchOrBranchLink, thisObj);
758
759 protected:
760 const char* format();
761
762 int32_t offset() { return ((static_cast<int32_t>(sBit() << 31)) >> 8) | static_cast<int32_t>((~(j1() ^ sBit()) << 22) | (~(j2() ^ sBit()) << 21) | (immediate10() << 11) | immediate11()); }
763 unsigned immediate10() { return (m_opcode >> 16) & 0x3ff; }
764 bool isBL() { return !!((m_opcode >> 14) & 0x1); }
765 };
766
767 class ARMv7DOpcodeDataProcessingLogicalAndRithmetic : public ARMv7D32BitOpcode {
768 protected:
769 static const char* const s_opNames[16];
770 };
771
772 class ARMv7DOpcodeDataProcessingModifiedImmediate : public ARMv7DOpcodeDataProcessingLogicalAndRithmetic {
773 private:
774 void appendImmShift(unsigned, unsigned);
775
776 public:
777 static const uint32_t s_mask = 0xfa008000;
778 static const uint32_t s_pattern = 0xf0000000;
779
780 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingModifiedImmediate, thisObj);
781
782 protected:
783 const char* format();
784 void appendModifiedImmediate(unsigned);
785
786 const char* opName() { return s_opNames[op()]; }
787
788 unsigned op() { return (m_opcode >> 21) & 0xf; }
789 unsigned sBit() { return (m_opcode >> 20) & 0x1; }
790 unsigned immediate12() { return ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
791 };
792
793 class ARMv7DOpcodeDataProcessingShiftedReg : public ARMv7DOpcodeDataProcessingLogicalAndRithmetic {
794 private:
795 void appendImmShift(unsigned, unsigned);
796
797 public:
798 static const uint32_t s_mask = 0xfe000000;
799 static const uint32_t s_pattern = 0xea000000;
800
801 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingShiftedReg, thisObj);
802
803 protected:
804 const char* format();
805
806 const char* opName() { return s_opNames[op()]; }
807
808 unsigned sBit() { return (m_opcode >> 20) & 0x1; }
809 unsigned op() { return (m_opcode >> 21) & 0xf; }
810 unsigned immediate5() { return ((m_opcode >> 10) & 0x1c) | ((m_opcode >> 6) & 0x3); }
811 unsigned type() { return (m_opcode >> 4) & 0x3; }
812 unsigned tbBit() { return (m_opcode >> 5) & 0x1; }
813 unsigned tBit() { return (m_opcode >> 4) & 0x1; }
814 };
815
816 class ARMv7DOpcodeDataProcessingReg : public ARMv7D32BitOpcode {
817 protected:
818 unsigned op1() { return (m_opcode >> 20) & 0xf; }
819 unsigned op2() { return (m_opcode >> 4) & 0xf; }
820 };
821
822 class ARMv7DOpcodeDataProcessingRegShift : public ARMv7DOpcodeDataProcessingReg {
823 public:
824 static const uint32_t s_mask = 0xffe0f0f0;
825 static const uint32_t s_pattern = 0xfa00f000;
826
827 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegShift, thisObj);
828
829 protected:
830 const char* format();
831
832 const char* opName() { return shiftName((op1() >> 1) & 0x3); }
833 };
834
835 class ARMv7DOpcodeDataProcessingRegExtend : public ARMv7DOpcodeDataProcessingReg {
836 private:
837 static const char* const s_opExtendNames[8];
838 static const char* const s_opExtendAndAddNames[8];
839
840 public:
841 static const uint32_t s_mask = 0xff80f0c0;
842 static const uint32_t s_pattern = 0xfa00f080;
843
844 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegExtend, thisObj);
845
846 protected:
847 const char* format();
848
849 const char* opExtendName() { return s_opExtendNames[op1()]; }
850 const char* opExtendAndAddName() { return s_opExtendAndAddNames[op1()]; }
851 unsigned rotate() { return (m_opcode >> 4) & 0x3; }
852 };
853
854 class ARMv7DOpcodeDataProcessingRegParallel : public ARMv7DOpcodeDataProcessingReg {
855 private:
856 static const char* const s_opNames[16];
857
858 public:
859 static const uint32_t s_mask = 0xff80f0e0;
860 static const uint32_t s_pattern = 0xfa00f000;
861
862 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegParallel, thisObj);
863
864 protected:
865 const char* format();
866
867 const char* opName() { return s_opNames[((op1() & 0x7) << 1) | (op2() & 0x1)]; }
868 };
869
870 class ARMv7DOpcodeDataProcessingRegMisc : public ARMv7DOpcodeDataProcessingReg {
871 private:
872 static const char* const s_opNames[16];
873
874 public:
875 static const uint32_t s_mask = 0xffc0f0c0;
876 static const uint32_t s_pattern = 0xfa80f080;
877
878 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegMisc, thisObj);
879
880 protected:
881 const char* format();
882
883 const char* opName() { return s_opNames[((op1() & 0x3) << 2) | (op2() & 0x3)]; }
884 };
885
886 class ARMv7DOpcodeHint32 : public ARMv7D32BitOpcode {
887 private:
888 static const char* const s_opNames[8];
889
890 public:
891 static const uint32_t s_mask = 0xfff0d000;
892 static const uint32_t s_pattern = 0xf3a08000;
893
894 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeHint32, thisObj);
895
896 protected:
897 const char* format();
898
899 const char* opName() { return s_opNames[op()]; }
900
901 bool isDebugHint() { return (m_opcode & 0xf0) == 0xf0; }
902 unsigned debugOption() { return m_opcode & 0xf; }
903 unsigned op() { return m_opcode & 0x7; }
904 };
905
906 class ARMv7DOpcodeFPTransfer : public ARMv7D32BitOpcode {
907 public:
908 static const uint32_t s_mask = 0xffc00e7f;
909 static const uint32_t s_pattern = 0xee000a10;
910
911 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeFPTransfer, thisObj);
912
913 protected:
914 const char* format();
915
916 void appendFPRegister();
917
918 unsigned opH() { return (m_opcode >> 21) & 0x1; }
919 unsigned opL() { return (m_opcode >> 20) & 0x1; }
920 unsigned rt() { return (m_opcode >> 12) & 0xf; }
921 unsigned opC() { return (m_opcode >> 8) & 0x1; }
922 unsigned opB() { return (m_opcode >> 5) & 0x3; }
923 unsigned vd() { return ((m_opcode >> 3) & 0x10) | ((m_opcode >> 16) & 0xf); }
924 unsigned vn() { return ((m_opcode >> 7) & 0x1) | ((m_opcode >> 15) & 0x1e); }
925 };
926
927 class ARMv7DOpcodeDataLoad : public ARMv7D32BitOpcode {
928 protected:
929 static const char* const s_opNames[8];
930
931 protected:
932 const char* opName() { return s_opNames[op()]; }
933
934 unsigned op() { return ((m_opcode >> 22) & 0x4) | ((m_opcode >> 21) & 0x3); }
935 };
936
937 class ARMv7DOpcodeLoadRegister : public ARMv7DOpcodeDataLoad {
938 public:
939 static const uint32_t s_mask = 0xfe900800;
940 static const uint32_t s_pattern = 0xf8100000;
941
942 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadRegister, thisObj);
943
944 protected:
945 const char* format();
946
947 unsigned immediate2() { return (m_opcode >> 4) & 0x3; }
948 };
949
950 class ARMv7DOpcodeLoadSignedImmediate : public ARMv7DOpcodeDataLoad {
951 public:
952 static const uint32_t s_mask = 0xfe900800;
953 static const uint32_t s_pattern = 0xf8100800;
954
955 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadSignedImmediate, thisObj);
956
957 protected:
958 const char* format();
959
960 unsigned pBit() { return (m_opcode >> 10) & 0x1; }
961 unsigned uBit() { return (m_opcode >> 9) & 0x1; }
962 unsigned wBit() { return (m_opcode >> 8) & 0x1; }
963 unsigned immediate8() { return m_opcode & 0xff; }
964 };
965
966 class ARMv7DOpcodeLoadUnsignedImmediate : public ARMv7DOpcodeDataLoad {
967 public:
968 static const uint32_t s_mask = 0xfe900000;
969 static const uint32_t s_pattern = 0xf8900000;
970
971 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadUnsignedImmediate, thisObj);
972
973 protected:
974 const char* format();
975
976 unsigned immediate12() { return m_opcode & 0xfff; }
977 };
978
979 class ARMv7DOpcodeLongMultipleDivide : public ARMv7D32BitOpcode {
980 protected:
981 static const char* const s_opNames[8];
982 static const char* const s_smlalOpNames[4];
983 static const char* const s_smlaldOpNames[2];
984 static const char* const s_smlsldOpNames[2];
985
986 public:
987 static const uint32_t s_mask = 0xff800000;
988 static const uint32_t s_pattern = 0xfb800000;
989
990 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLongMultipleDivide, thisObj);
991
992 protected:
993 const char* format();
994
995 const char* opName() { return s_opNames[op1()]; }
996 const char* smlalOpName() { return s_smlalOpNames[(nBit() << 1) | mBit()]; }
997 const char* smlaldOpName() { return s_smlaldOpNames[mBit()]; }
998 const char* smlsldOpName() { return s_smlsldOpNames[mBit()]; }
999
1000 unsigned rdLo() { return rt(); }
1001 unsigned rdHi() { return rd(); }
1002 unsigned op1() { return (m_opcode >> 20) & 0x7; }
1003 unsigned op2() { return (m_opcode >> 4) & 0xf; }
1004 unsigned nBit() { return (m_opcode >> 5) & 0x1; }
1005 unsigned mBit() { return (m_opcode >> 4) & 0x1; }
1006 };
1007
1008 class ARMv7DOpcodeDataPushPopSingle : public ARMv7D32BitOpcode {
1009 public:
1010 static const uint32_t s_mask = 0xffef0fff;
1011 static const uint32_t s_pattern = 0xf84d0d04;
1012
1013 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushPopSingle, thisObj);
1014
1015 protected:
1016 const char* format();
1017
1018 const char* opName() { return op() ? "pop" : "push"; }
1019 unsigned op() { return (m_opcode >> 20) & 0x1; }
1020 };
1021
1022 class ARMv7DOpcodeDataPushPopMultiple : public ARMv7D32BitOpcode {
1023 protected:
1024 void appendRegisterList();
1025
1026 unsigned registerList() { return m_opcode & 0xffff; }
1027 unsigned condition() { return m_opcode >> 28; }
1028 };
1029
1030 class ARMv7DOpcodeDataPopMultiple : public ARMv7DOpcodeDataPushPopMultiple {
1031 public:
1032 static const uint32_t s_mask = 0x0fff0000;
1033 static const uint32_t s_pattern = 0x08bd0000;
1034
1035 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPopMultiple, thisObj);
1036
1037 protected:
1038 const char* format();
1039 };
1040
1041 class ARMv7DOpcodeDataPushMultiple : public ARMv7DOpcodeDataPushPopMultiple {
1042 public:
1043 static const uint32_t s_mask = 0xfe7f0000;
1044 static const uint32_t s_pattern = 0xe82d0000;
1045
1046 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushMultiple, thisObj);
1047
1048 protected:
1049 const char* format();
1050 };
1051
1052 class ARMv7DOpcodeDataStoreSingle : public ARMv7D32BitOpcode {
1053 protected:
1054 static const char* const s_opNames[4];
1055
1056 protected:
1057 const char* opName() { return s_opNames[op()]; }
1058
1059 unsigned op() { return (m_opcode >> 21) & 0x3; }
1060 };
1061
1062 class ARMv7DOpcodeStoreSingleImmediate12 : public ARMv7DOpcodeDataStoreSingle {
1063 public:
1064 static const uint32_t s_mask = 0xfff00000;
1065 static const uint32_t s_pattern = 0xf8c00000;
1066
1067 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate12, thisObj);
1068
1069 const char* format();
1070
1071 protected:
1072 unsigned immediate12() { return m_opcode & 0xfff; }
1073 };
1074
1075 class ARMv7DOpcodeStoreSingleImmediate8 : public ARMv7DOpcodeDataStoreSingle {
1076 public:
1077 static const uint32_t s_mask = 0xfff00800;
1078 static const uint32_t s_pattern = 0xf8400800;
1079
1080 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate8, thisObj);
1081
1082 const char* format();
1083
1084 protected:
1085 unsigned pBit() { return (m_opcode >> 10) & 0x1; }
1086 unsigned uBit() { return (m_opcode >> 9) & 0x1; }
1087 unsigned wBit() { return (m_opcode >> 8) & 0x1; }
1088 unsigned immediate8() { return m_opcode & 0xff; }
1089 };
1090
1091 class ARMv7DOpcodeStoreSingleRegister : public ARMv7DOpcodeDataStoreSingle {
1092 public:
1093 static const uint32_t s_mask = 0xfff00fc0;
1094 static const uint32_t s_pattern = 0xf8400000;
1095
1096 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleRegister, thisObj);
1097
1098 protected:
1099 const char* format();
1100
1101 unsigned immediate2() { return (m_opcode >> 4) & 0x3; }
1102 };
1103
1104 class ARMv7DOpcodeUnmodifiedImmediate : public ARMv7D32BitOpcode {
1105 protected:
1106 static const char* const s_opNames[16];
1107
1108 public:
1109 static const uint32_t s_mask = 0xfa008000;
1110 static const uint32_t s_pattern = 0xf2000000;
1111
1112 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeUnmodifiedImmediate, thisObj);
1113
1114 protected:
1115 const char* format();
1116
1117 const char* opName() { return s_opNames[op() >> 1]; }
1118
1119 unsigned op() { return (m_opcode >> 20) & 0x1f; }
1120 unsigned shBit() { return (m_opcode >> 21) & 0x1; }
1121 unsigned bitNumOrSatImmediate() { return m_opcode & 0x1f; }
1122 unsigned immediate5() { return ((m_opcode >> 9) & 0x1c) | ((m_opcode >> 6) & 0x3); }
1123 unsigned immediate12() { return ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
1124 unsigned immediate16() { return ((m_opcode >> 4) & 0xf000) | ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
1125 };
1126
1127 class ARMv7DOpcodeVCMP : public ARMv7D32BitOpcode {
1128 public:
1129 static const uint32_t s_mask = 0x0fbf0e50;
1130 static const uint32_t s_pattern = 0x0eb40a40;
1131
1132 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCMP, thisObj);
1133
1134 protected:
1135 const char* format();
1136
1137 unsigned condition() { return m_opcode >> 28; }
1138 unsigned dBit() { return (m_opcode >> 22) & 0x1; }
1139 unsigned vd() { return (m_opcode >> 12) & 0xf; }
1140 unsigned szBit() { return (m_opcode >> 8) & 0x1; }
1141 unsigned eBit() { return (m_opcode >> 7) & 0x1; }
1142 unsigned mBit() { return (m_opcode >> 5) & 0x1; }
1143 unsigned vm() { return m_opcode & 0xf; }
1144 };
1145
1146 class ARMv7DOpcodeVCVTBetweenFPAndInt : public ARMv7D32BitOpcode {
1147 public:
1148 static const uint32_t s_mask = 0x0fb80e50;
1149 static const uint32_t s_pattern = 0x0eb80a40;
1150
1151 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCVTBetweenFPAndInt, thisObj);
1152
1153 protected:
1154 const char* format();
1155
1156 unsigned condition() { return m_opcode >> 28; }
1157 unsigned dBit() { return (m_opcode >> 22) & 0x1; }
1158 unsigned op2() { return (m_opcode >> 16) & 0x7; }
1159 unsigned vd() { return (m_opcode >> 12) & 0xf; }
1160 unsigned szBit() { return (m_opcode >> 8) & 0x1; }
1161 unsigned op() { return (m_opcode >> 7) & 0x1; }
1162 unsigned mBit() { return (m_opcode >> 5) & 0x1; }
1163 unsigned vm() { return m_opcode & 0xf; }
1164 };
1165
1166 class ARMv7DOpcodeVLDR : public ARMv7D32BitOpcode {
1167 public:
1168 static const uint32_t s_mask = 0x0f300e00;
1169 static const uint32_t s_pattern = 0x0d100a00;
1170
1171 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVLDR, thisObj);
1172
1173 protected:
1174 const char* format();
1175
1176 unsigned condition() { return m_opcode >> 28; }
1177 unsigned uBit() { return (m_opcode >> 23) & 0x1; }
1178 unsigned rn() { return (m_opcode >> 16) & 0xf; }
1179 unsigned vd() { return ((m_opcode >> 18) & 0x10) | ((m_opcode >> 12) & 0xf); }
1180 bool doubleReg() { return !!(m_opcode & 0x100); }
1181 unsigned immediate8() { return m_opcode & 0xff; }
1182 };
1183
1184 class ARMv7DOpcodeVMOVDoublePrecision : public ARMv7D32BitOpcode {
1185 public:
1186 static const uint32_t s_mask = 0xffe00fd0;
1187 static const uint32_t s_pattern = 0xec400b10;
1188
1189 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVDoublePrecision, thisObj);
1190
1191 protected:
1192 const char* format();
1193
1194 unsigned op() { return (m_opcode >> 20) & 0x1; }
1195 unsigned rt2() { return (m_opcode >> 16) & 0xf; }
1196 unsigned rt() { return (m_opcode >> 16) & 0xf; }
1197 unsigned vm() { return (m_opcode & 0xf) | ((m_opcode >> 1) & 0x10); }
1198 };
1199
1200 class ARMv7DOpcodeVMOVSinglePrecision : public ARMv7D32BitOpcode {
1201 public:
1202 static const uint32_t s_mask = 0xffe00fd0;
1203 static const uint32_t s_pattern = 0xec400a10;
1204
1205 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVSinglePrecision, thisObj);
1206
1207 protected:
1208 const char* format();
1209
1210 unsigned op() { return (m_opcode >> 20) & 0x1; }
1211 unsigned rt2() { return (m_opcode >> 16) & 0xf; }
1212 unsigned rt() { return (m_opcode >> 16) & 0xf; }
1213 unsigned vm() { return ((m_opcode << 1) & 0x1e) | ((m_opcode >> 5) & 0x1); }
1214 };
1215
1216 class ARMv7DOpcodeVMSR : public ARMv7D32BitOpcode {
1217 public:
1218 static const uint32_t s_mask = 0xffef0fff;
1219 static const uint32_t s_pattern = 0xeee10a10;
1220
1221 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMSR, thisObj);
1222
1223 protected:
1224 const char* format();
1225
1226 unsigned opL() { return (m_opcode >> 20) & 0x1; }
1227 unsigned rt() { return (m_opcode >> 12) & 0xf; }
1228 };
1229
1230
1231 } } // namespace JSC::ARMv7Disassembler
1232
1233 using JSC::ARMv7Disassembler::ARMv7DOpcode;
1234
1235 #endif // #if USE(ARMV7_DISASSEMBLER)
1236
1237 #endif // ARMv7DOpcode_h