2 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef ARMv7DOpcode_h
27 #define ARMv7DOpcode_h
29 #if USE(ARMV7_DISASSEMBLER)
32 #include <wtf/Assertions.h>
34 namespace JSC
{ namespace ARMv7Disassembler
{
46 for (unsigned i
= 0; i
< 4; i
++)
47 m_ifThenConditions
[i
] = CondNone
;
51 m_formatBuffer
[0] = '\0';
54 const char* disassemble(uint16_t*& currentPC
);
57 const unsigned RegSP
= 0xd;
58 const unsigned RegLR
= 0xe;
59 const unsigned RegPC
= 0xf;
61 void fetchOpcode(uint16_t*&);
62 bool is32BitInstruction() { return (m_opcode
& 0xfffff800) > 0xe000; }
63 bool isFPInstruction() { return (m_opcode
& 0xfc000e00) == 0xec000a00; }
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];
70 static const char* conditionName(unsigned condition
) { return s_conditionNames
[condition
& 0xf]; }
71 static const char* shiftName(unsigned shiftValue
) { return s_shiftNames
[shiftValue
& 0x3]; }
73 bool inITBlock() { return m_ITConditionIndex
< m_ITBlocksize
; }
74 bool startingITBlock() { return m_ITConditionIndex
== m_ITBlocksize
+ 1; }
76 void startITBlock(unsigned, unsigned);
77 void saveITConditionAt(unsigned, unsigned);
80 m_currentITCondition
= CondNone
;
81 m_ITConditionIndex
= 0;
85 void bufferPrintf(const char* format
, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
86 void appendInstructionName(const char*, bool addS
= false);
88 void appendInstructionNameNoITBlock(const char* instructionName
)
90 bufferPrintf(" %-7.7s", instructionName
);
93 void appendRegisterName(unsigned);
94 void appendRegisterList(unsigned);
95 void appendFPRegisterName(char, unsigned);
97 void appendSeparator()
102 void appendCharacter(const char c
)
104 bufferPrintf("%c", c
);
107 void appendString(const char* string
)
109 bufferPrintf("%s", string
);
112 void appendShiftType(unsigned shiftValue
)
114 bufferPrintf("%s ", shiftName(shiftValue
));
117 void appendSignedImmediate(int immediate
)
119 bufferPrintf("#%d", immediate
);
122 void appendUnsignedImmediate(unsigned immediate
)
124 bufferPrintf("#%u", immediate
);
127 void appendPCRelativeOffset(int32_t immediate
)
129 bufferPrintf("0x%x", reinterpret_cast<uint32_t>(m_currentPC
+ immediate
));
132 void appendShiftAmount(unsigned amount
)
134 bufferPrintf("lsl #%u", 16 * amount
);
137 static const int bufferSize
= 81;
138 static const unsigned char CondNone
= 0xe;
139 static const unsigned MaxITBlockSize
= 4;
141 char m_formatBuffer
[bufferSize
];
142 unsigned char m_ifThenConditions
[MaxITBlockSize
];
143 uint16_t* m_currentPC
;
146 int m_currentITCondition
;
147 unsigned m_ITConditionIndex
;
148 unsigned m_ITBlocksize
;
151 static bool s_initialized
;
154 #define DEFINE_STATIC_FORMAT16(klass, thisObj) \
155 static const char* format(ARMv7D16BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
157 class ARMv7D16BitOpcode
: public ARMv7DOpcode
{
161 OpcodeGroup(uint16_t opcodeMask
, uint16_t opcodePattern
, const char* (*format
)(ARMv7D16BitOpcode
*))
162 : m_opcodeMask(opcodeMask
)
163 , m_opcodePattern(opcodePattern
)
169 void setNext(OpcodeGroup
* next
)
179 bool matches(uint16_t opcode
)
181 return (opcode
& m_opcodeMask
) == m_opcodePattern
;
184 const char* format(ARMv7D16BitOpcode
* thisObj
)
186 return m_format(thisObj
);
190 static const unsigned opcodeTableSize
= 32;
191 static const unsigned opcodeTableMask
= opcodeTableSize
-1;
194 uint16_t m_opcodeMask
;
195 uint16_t m_opcodePattern
;
196 const char* (*m_format
)(ARMv7D16BitOpcode
*);
203 const char* defaultFormat();
204 const char* doDisassemble();
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
; }
212 static OpcodeGroup
* opcodeTable
[OpcodeGroup::opcodeTableSize
];
215 class ARMv7DOpcodeAddRegisterT2
: public ARMv7D16BitOpcode
{
217 static const uint16_t s_mask
= 0xff00;
218 static const uint16_t s_pattern
= 0x4400;
220 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddRegisterT2
, thisObj
);
223 const char* format();
225 unsigned rdn() { return ((m_opcode
>> 4) & 0x8) | (m_opcode
& 0x7); }
226 unsigned rm() { return ((m_opcode
>> 3) & 0xf); }
229 class ARMv7DOpcodeAddSPPlusImmediate
: public ARMv7D16BitOpcode
{
231 static const uint16_t s_mask
= 0xf800;
232 static const uint16_t s_pattern
= 0xc800;
234 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSPPlusImmediate
, thisObj
);
237 const char* format();
239 unsigned rd() { return (m_opcode
>> 8) & 0x7; }
240 unsigned immediate8() { return m_opcode
& 0x0ff; }
243 class ARMv7DOpcodeAddSubtract
: public ARMv7D16BitOpcode
{
245 static const char* const s_opNames
[2];
248 class ARMv7DOpcodeAddSubtractT1
: public ARMv7DOpcodeAddSubtract
{
250 static const uint16_t s_mask
= 0xfc00;
251 static const uint16_t s_pattern
= 0x1800;
253 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractT1
, thisObj
);
256 const char* format();
258 const char* opName() { return s_opNames
[op()]; }
260 unsigned op() { return (m_opcode
>> 9) & 0x1; }
261 unsigned rm() { return (m_opcode
>> 6) & 0x7; }
262 unsigned rn() { return (m_opcode
>> 3) & 0x7; }
265 class ARMv7DOpcodeAddSubtractImmediate3
: public ARMv7DOpcodeAddSubtract
{
267 static const uint16_t s_mask
= 0xfc00;
268 static const uint16_t s_pattern
= 0x1c00;
270 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractImmediate3
, thisObj
);
273 const char* format();
275 const char* opName() { return s_opNames
[op()]; }
277 unsigned op() { return (m_opcode
>> 9) & 0x1; }
278 unsigned immediate3() { return (m_opcode
>> 6) & 0x7; }
279 unsigned rn() { return (m_opcode
>> 3) & 0x7; }
282 class ARMv7DOpcodeAddSubtractImmediate8
: public ARMv7DOpcodeAddSubtract
{
284 static const uint16_t s_mask
= 0xf000;
285 static const uint16_t s_pattern
= 0x3000;
287 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractImmediate8
, thisObj
);
290 const char* format();
292 const char* opName() { return s_opNames
[op()]; }
294 unsigned op() { return (m_opcode
>> 11) & 0x1; }
295 unsigned rdn() { return (m_opcode
>> 8) & 0x7; }
296 unsigned immediate8() { return m_opcode
& 0xff; }
299 class ARMv7DOpcodeBranchConditionalT1
: public ARMv7D16BitOpcode
{
301 static const uint16_t s_mask
= 0xf000;
302 static const uint16_t s_pattern
= 0xd000;
304 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchConditionalT1
, thisObj
);
307 const char* format();
309 unsigned condition() { return (m_opcode
>> 8) & 0xf; }
310 int offset() { return static_cast<int>(m_opcode
& 0xff); }
313 class ARMv7DOpcodeBranchExchangeT1
: public ARMv7D16BitOpcode
{
315 static const uint16_t s_mask
= 0xff00;
316 static const uint16_t s_pattern
= 0x4700;
318 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchExchangeT1
, thisObj
);
321 const char* format();
323 const char* opName() { return (m_opcode
& 0x80) ? "blx" : "bx"; }
324 unsigned rm() { return ((m_opcode
>> 3) & 0xf); }
327 class ARMv7DOpcodeBranchT2
: public ARMv7D16BitOpcode
{
329 static const uint16_t s_mask
= 0xf800;
330 static const uint16_t s_pattern
= 0xe000;
332 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchT2
, thisObj
);
335 const char* format();
337 int immediate11() { return static_cast<int>(m_opcode
& 0x7ff); }
340 class ARMv7DOpcodeCompareImmediateT1
: public ARMv7D16BitOpcode
{
342 static const uint16_t s_mask
= 0xf800;
343 static const uint16_t s_pattern
= 0x2800;
345 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareImmediateT1
, thisObj
);
348 const char* format();
350 unsigned rn() { return (m_opcode
>> 8) & 0x3; }
351 unsigned immediate8() { return m_opcode
& 0xff; }
354 class ARMv7DOpcodeCompareRegisterT1
: public ARMv7D16BitOpcode
{
356 static const uint16_t s_mask
= 0xffc0;
357 static const uint16_t s_pattern
= 0x4280;
359 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareRegisterT1
, thisObj
);
362 const char* format();
364 unsigned rn() { return m_opcode
& 0x7; }
367 class ARMv7DOpcodeCompareRegisterT2
: public ARMv7D16BitOpcode
{
369 static const uint16_t s_mask
= 0xff00;
370 static const uint16_t s_pattern
= 0x4500;
372 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareRegisterT2
, thisObj
);
375 const char* format();
377 unsigned rn() { return ((m_opcode
>> 4) & 0x8) | (m_opcode
& 0x7); }
378 unsigned rm() { return ((m_opcode
>> 3) & 0xf); }
381 class ARMv7DOpcodeDataProcessingRegisterT1
: public ARMv7D16BitOpcode
{
383 static const char* const s_opNames
[16];
386 static const uint16_t s_mask
= 0xfc00;
387 static const uint16_t s_pattern
= 0x4000;
389 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeDataProcessingRegisterT1
, thisObj
);
392 const char* format();
394 const char* opName() { return s_opNames
[op()]; }
396 unsigned op() { return (m_opcode
>> 6) & 0xf; }
398 unsigned rm() { return (m_opcode
>> 3) & 0x7; }
399 unsigned rdn() { return m_opcode
& 0x7; }
402 class ARMv7DOpcodeGeneratePCRelativeAddress
: public ARMv7D16BitOpcode
{
404 static const uint16_t s_mask
= 0xf800;
405 static const uint16_t s_pattern
= 0xa000;
407 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeGeneratePCRelativeAddress
, thisObj
);
410 const char* format();
412 unsigned rd() { return (m_opcode
>> 8) & 0x7; }
413 unsigned immediate8() { return m_opcode
& 0x0ff; }
416 class ARMv7DOpcodeLoadFromLiteralPool
: public ARMv7D16BitOpcode
{
418 static const uint16_t s_mask
= 0xf800;
419 static const uint16_t s_pattern
= 0x4800;
421 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadFromLiteralPool
, thisObj
);
424 const char* format();
426 unsigned rt() { return (m_opcode
>> 8) & 0x7; }
427 unsigned immediate8() { return m_opcode
& 0x0ff; }
430 class ARMv7DOpcodeLoadStoreRegisterImmediate
: public ARMv7D16BitOpcode
{
432 static const char* const s_opNames
[6];
435 const char* format();
438 const char* opName() { return s_opNames
[op()]; }
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; }
447 class ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte
: public ARMv7DOpcodeLoadStoreRegisterImmediate
{
449 static const uint16_t s_mask
= 0xe000;
450 static const uint16_t s_pattern
= 0x6000;
452 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate
, thisObj
);
455 class ARMv7DOpcodeStoreRegisterImmediateHalfWord
: public ARMv7DOpcodeLoadStoreRegisterImmediate
{
457 static const uint16_t s_mask
= 0xf800;
458 static const uint16_t s_pattern
= 0x8000;
460 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate
, thisObj
);
463 class ARMv7DOpcodeLoadRegisterImmediateHalfWord
: public ARMv7DOpcodeLoadStoreRegisterImmediate
{
465 static const uint16_t s_mask
= 0xf800;
466 static const uint16_t s_pattern
= 0x8800;
468 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate
, thisObj
);
471 class ARMv7DOpcodeLoadStoreRegisterOffsetT1
: public ARMv7D16BitOpcode
{
473 static const char* const s_opNames
[8];
476 static const uint16_t s_mask
= 0xf000;
477 static const uint16_t s_pattern
= 0x5000;
479 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterOffsetT1
, thisObj
);
482 const char* format();
484 const char* opName() { return s_opNames
[opB()]; }
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; }
492 class ARMv7DOpcodeLoadStoreRegisterSPRelative
: public ARMv7D16BitOpcode
{
494 static const char* const s_opNames
[8];
497 static const uint16_t s_mask
= 0xf000;
498 static const uint16_t s_pattern
= 0x9000;
500 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterSPRelative
, thisObj
);
503 const char* format();
505 const char* opName() { return op() ? "ldr" : "str"; }
507 unsigned op() { return (m_opcode
>> 11) & 0x1; }
508 unsigned rt() { return (m_opcode
>> 8) & 0x7; }
509 unsigned immediate8() { return m_opcode
& 0xff; }
512 class ARMv7DOpcodeLogicalImmediateT1
: public ARMv7D16BitOpcode
{
514 static const uint16_t s_mask
= 0xe000;
515 static const uint16_t s_pattern
= 0x0000;
517 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLogicalImmediateT1
, thisObj
);
520 const char* format();
522 const char* opName() { return shiftName(op()); }
524 unsigned op() { return (m_opcode
>> 12) & 0x3; }
525 unsigned immediate5() { return (m_opcode
>> 6) & 0x1f; }
528 class ARMv7DOpcodeMiscAddSubSP
: public ARMv7D16BitOpcode
{
530 static const uint16_t s_mask
= 0xff00;
531 static const uint16_t s_pattern
= 0xb000;
533 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscAddSubSP
, thisObj
);
536 const char* format();
538 const char* opName() { return op() ? "sub" : "add"; }
539 unsigned op() { return (m_opcode
>> 7) & 0x1; }
540 unsigned immediate7() { return m_opcode
& 0x7f; }
543 class ARMv7DOpcodeMiscByteHalfwordOps
: public ARMv7D16BitOpcode
{
545 static const char* const s_opNames
[8];
548 static const uint16_t s_mask
= 0xf700;
549 static const uint16_t s_pattern
= 0xb200;
551 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscByteHalfwordOps
, thisObj
);
554 const char* format();
556 const char* opName() { return s_opNames
[op()]; }
557 unsigned op() { return ((m_opcode
>> 9) & 0x4) || ((m_opcode
>> 6) & 0x3); }
560 class ARMv7DOpcodeMiscBreakpointT1
: public ARMv7D16BitOpcode
{
562 static const uint16_t s_mask
= 0xff00;
563 static const uint16_t s_pattern
= 0xbe00;
565 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscBreakpointT1
, thisObj
);
568 const char* format();
570 unsigned immediate8() { return m_opcode
& 0xff; }
573 class ARMv7DOpcodeMiscCompareAndBranch
: public ARMv7D16BitOpcode
{
575 static const uint16_t s_mask
= 0xf500;
576 static const uint16_t s_pattern
= 0xb100;
578 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscCompareAndBranch
, thisObj
);
581 const char* format();
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; }
589 class ARMv7DOpcodeMiscHint16
: public ARMv7D16BitOpcode
{
591 static const char* const s_opNames
[16];
594 static const uint16_t s_mask
= 0xff0f;
595 static const uint16_t s_pattern
= 0xbf00;
597 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscHint16
, thisObj
);
600 const char* format();
602 const char* opName() { return s_opNames
[opA()]; }
603 unsigned opA() { return (m_opcode
>> 4) & 0xf; }
606 class ARMv7DOpcodeMiscIfThenT1
: public ARMv7D16BitOpcode
{
608 static const uint16_t s_mask
= 0xff00;
609 static const uint16_t s_pattern
= 0xbf00;
611 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscIfThenT1
, thisObj
);
614 const char* format();
616 unsigned firstCondition() { return (m_opcode
>> 4) & 0xf; }
617 unsigned mask() { return m_opcode
& 0xf; }
620 class ARMv7DOpcodeMiscPushPop
: public ARMv7D16BitOpcode
{
622 static const uint16_t s_mask
= 0xf600;
623 static const uint16_t s_pattern
= 0xb400;
625 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscPushPop
, thisObj
);
628 const char* format();
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); }
635 class ARMv7DOpcodeMoveImmediateT1
: public ARMv7D16BitOpcode
{
637 static const uint16_t s_mask
= 0xf800;
638 static const uint16_t s_pattern
= 0x2000;
640 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveImmediateT1
, thisObj
);
643 const char* format();
645 unsigned rd() { return (m_opcode
>> 8) & 0x3; }
646 unsigned immediate8() { return m_opcode
& 0xff; }
649 class ARMv7DOpcodeMoveRegisterT1
: public ARMv7D16BitOpcode
{
651 static const uint16_t s_mask
= 0xff00;
652 static const uint16_t s_pattern
= 0x4600;
654 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveRegisterT1
, thisObj
);
657 const char* format();
659 unsigned rd() { return ((m_opcode
>> 4) & 0x8) | (m_opcode
& 0x7); }
660 unsigned rm() { return ((m_opcode
>> 3) & 0xf); }
663 // 32 Bit instructions
665 #define DEFINE_STATIC_FORMAT32(klass, thisObj) \
666 static const char* format(ARMv7D32BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
668 class ARMv7D32BitOpcode
: public ARMv7DOpcode
{
672 OpcodeGroup(uint32_t opcodeMask
, uint32_t opcodePattern
, const char* (*format
)(ARMv7D32BitOpcode
*))
673 : m_opcodeMask(opcodeMask
)
674 , m_opcodePattern(opcodePattern
)
680 void setNext(OpcodeGroup
* next
)
690 bool matches(uint32_t opcode
)
692 return (opcode
& m_opcodeMask
) == m_opcodePattern
;
695 const char* format(ARMv7D32BitOpcode
* thisObj
)
697 return m_format(thisObj
);
701 static const unsigned opcodeTableSize
= 16;
702 static const unsigned opcodeTableMask
= opcodeTableSize
-1;
705 uint32_t m_opcodeMask
;
706 uint32_t m_opcodePattern
;
707 const char* (*m_format
)(ARMv7D32BitOpcode
*);
714 const char* defaultFormat();
715 const char* doDisassemble();
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; }
723 unsigned opcodeGroupNumber(unsigned opcode
) { return (opcode
>> 25) & OpcodeGroup::opcodeTableMask
; }
726 static OpcodeGroup
* opcodeTable
[OpcodeGroup::opcodeTableSize
];
729 class ARMv7DOpcodeBranchRelative
: public ARMv7D32BitOpcode
{
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; }
737 class ARMv7DOpcodeConditionalBranchT3
: public ARMv7DOpcodeBranchRelative
{
739 static const uint32_t s_mask
= 0xf800d000;
740 static const uint32_t s_pattern
= 0xf0008000;
742 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeConditionalBranchT3
, thisObj
);
745 const char* format();
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; }
752 class ARMv7DOpcodeBranchOrBranchLink
: public ARMv7DOpcodeBranchRelative
{
754 static const uint32_t s_mask
= 0xf8009000;
755 static const uint32_t s_pattern
= 0xf0009000;
757 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeBranchOrBranchLink
, thisObj
);
760 const char* format();
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); }
767 class ARMv7DOpcodeDataProcessingLogicalAndRithmetic
: public ARMv7D32BitOpcode
{
769 static const char* const s_opNames
[16];
772 class ARMv7DOpcodeDataProcessingModifiedImmediate
: public ARMv7DOpcodeDataProcessingLogicalAndRithmetic
{
774 void appendImmShift(unsigned, unsigned);
777 static const uint32_t s_mask
= 0xfa008000;
778 static const uint32_t s_pattern
= 0xf0000000;
780 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingModifiedImmediate
, thisObj
);
783 const char* format();
784 void appendModifiedImmediate(unsigned);
786 const char* opName() { return s_opNames
[op()]; }
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); }
793 class ARMv7DOpcodeDataProcessingShiftedReg
: public ARMv7DOpcodeDataProcessingLogicalAndRithmetic
{
795 void appendImmShift(unsigned, unsigned);
798 static const uint32_t s_mask
= 0xfe000000;
799 static const uint32_t s_pattern
= 0xea000000;
801 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingShiftedReg
, thisObj
);
804 const char* format();
806 const char* opName() { return s_opNames
[op()]; }
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; }
816 class ARMv7DOpcodeDataProcessingReg
: public ARMv7D32BitOpcode
{
818 unsigned op1() { return (m_opcode
>> 20) & 0xf; }
819 unsigned op2() { return (m_opcode
>> 4) & 0xf; }
822 class ARMv7DOpcodeDataProcessingRegShift
: public ARMv7DOpcodeDataProcessingReg
{
824 static const uint32_t s_mask
= 0xffe0f0f0;
825 static const uint32_t s_pattern
= 0xfa00f000;
827 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegShift
, thisObj
);
830 const char* format();
832 const char* opName() { return shiftName((op1() >> 1) & 0x3); }
835 class ARMv7DOpcodeDataProcessingRegExtend
: public ARMv7DOpcodeDataProcessingReg
{
837 static const char* const s_opExtendNames
[8];
838 static const char* const s_opExtendAndAddNames
[8];
841 static const uint32_t s_mask
= 0xff80f0c0;
842 static const uint32_t s_pattern
= 0xfa00f080;
844 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegExtend
, thisObj
);
847 const char* format();
849 const char* opExtendName() { return s_opExtendNames
[op1()]; }
850 const char* opExtendAndAddName() { return s_opExtendAndAddNames
[op1()]; }
851 unsigned rotate() { return (m_opcode
>> 4) & 0x3; }
854 class ARMv7DOpcodeDataProcessingRegParallel
: public ARMv7DOpcodeDataProcessingReg
{
856 static const char* const s_opNames
[16];
859 static const uint32_t s_mask
= 0xff80f0e0;
860 static const uint32_t s_pattern
= 0xfa00f000;
862 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegParallel
, thisObj
);
865 const char* format();
867 const char* opName() { return s_opNames
[((op1() & 0x7) << 1) | (op2() & 0x1)]; }
870 class ARMv7DOpcodeDataProcessingRegMisc
: public ARMv7DOpcodeDataProcessingReg
{
872 static const char* const s_opNames
[16];
875 static const uint32_t s_mask
= 0xffc0f0c0;
876 static const uint32_t s_pattern
= 0xfa80f080;
878 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegMisc
, thisObj
);
881 const char* format();
883 const char* opName() { return s_opNames
[((op1() & 0x3) << 2) | (op2() & 0x3)]; }
886 class ARMv7DOpcodeHint32
: public ARMv7D32BitOpcode
{
888 static const char* const s_opNames
[8];
891 static const uint32_t s_mask
= 0xfff0d000;
892 static const uint32_t s_pattern
= 0xf3a08000;
894 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeHint32
, thisObj
);
897 const char* format();
899 const char* opName() { return s_opNames
[op()]; }
901 bool isDebugHint() { return (m_opcode
& 0xf0) == 0xf0; }
902 unsigned debugOption() { return m_opcode
& 0xf; }
903 unsigned op() { return m_opcode
& 0x7; }
906 class ARMv7DOpcodeFPTransfer
: public ARMv7D32BitOpcode
{
908 static const uint32_t s_mask
= 0xffc00e7f;
909 static const uint32_t s_pattern
= 0xee000a10;
911 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeFPTransfer
, thisObj
);
914 const char* format();
916 void appendFPRegister();
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); }
927 class ARMv7DOpcodeDataLoad
: public ARMv7D32BitOpcode
{
929 static const char* const s_opNames
[8];
932 const char* opName() { return s_opNames
[op()]; }
934 unsigned op() { return ((m_opcode
>> 22) & 0x4) | ((m_opcode
>> 21) & 0x3); }
937 class ARMv7DOpcodeLoadRegister
: public ARMv7DOpcodeDataLoad
{
939 static const uint32_t s_mask
= 0xfe900800;
940 static const uint32_t s_pattern
= 0xf8100000;
942 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadRegister
, thisObj
);
945 const char* format();
947 unsigned immediate2() { return (m_opcode
>> 4) & 0x3; }
950 class ARMv7DOpcodeLoadSignedImmediate
: public ARMv7DOpcodeDataLoad
{
952 static const uint32_t s_mask
= 0xfe900800;
953 static const uint32_t s_pattern
= 0xf8100800;
955 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadSignedImmediate
, thisObj
);
958 const char* format();
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; }
966 class ARMv7DOpcodeLoadUnsignedImmediate
: public ARMv7DOpcodeDataLoad
{
968 static const uint32_t s_mask
= 0xfe900000;
969 static const uint32_t s_pattern
= 0xf8900000;
971 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadUnsignedImmediate
, thisObj
);
974 const char* format();
976 unsigned immediate12() { return m_opcode
& 0xfff; }
979 class ARMv7DOpcodeLongMultipleDivide
: public ARMv7D32BitOpcode
{
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];
987 static const uint32_t s_mask
= 0xff800000;
988 static const uint32_t s_pattern
= 0xfb800000;
990 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLongMultipleDivide
, thisObj
);
993 const char* format();
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()]; }
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; }
1008 class ARMv7DOpcodeDataPushPopSingle
: public ARMv7D32BitOpcode
{
1010 static const uint32_t s_mask
= 0xffef0fff;
1011 static const uint32_t s_pattern
= 0xf84d0d04;
1013 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushPopSingle
, thisObj
);
1016 const char* format();
1018 const char* opName() { return op() ? "pop" : "push"; }
1019 unsigned op() { return (m_opcode
>> 20) & 0x1; }
1022 class ARMv7DOpcodeDataPushPopMultiple
: public ARMv7D32BitOpcode
{
1024 void appendRegisterList();
1026 unsigned registerList() { return m_opcode
& 0xffff; }
1027 unsigned condition() { return m_opcode
>> 28; }
1030 class ARMv7DOpcodeDataPopMultiple
: public ARMv7DOpcodeDataPushPopMultiple
{
1032 static const uint32_t s_mask
= 0x0fff0000;
1033 static const uint32_t s_pattern
= 0x08bd0000;
1035 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPopMultiple
, thisObj
);
1038 const char* format();
1041 class ARMv7DOpcodeDataPushMultiple
: public ARMv7DOpcodeDataPushPopMultiple
{
1043 static const uint32_t s_mask
= 0xfe7f0000;
1044 static const uint32_t s_pattern
= 0xe82d0000;
1046 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushMultiple
, thisObj
);
1049 const char* format();
1052 class ARMv7DOpcodeDataStoreSingle
: public ARMv7D32BitOpcode
{
1054 static const char* const s_opNames
[4];
1057 const char* opName() { return s_opNames
[op()]; }
1059 unsigned op() { return (m_opcode
>> 21) & 0x3; }
1062 class ARMv7DOpcodeStoreSingleImmediate12
: public ARMv7DOpcodeDataStoreSingle
{
1064 static const uint32_t s_mask
= 0xfff00000;
1065 static const uint32_t s_pattern
= 0xf8c00000;
1067 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate12
, thisObj
);
1069 const char* format();
1072 unsigned immediate12() { return m_opcode
& 0xfff; }
1075 class ARMv7DOpcodeStoreSingleImmediate8
: public ARMv7DOpcodeDataStoreSingle
{
1077 static const uint32_t s_mask
= 0xfff00800;
1078 static const uint32_t s_pattern
= 0xf8400800;
1080 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate8
, thisObj
);
1082 const char* format();
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; }
1091 class ARMv7DOpcodeStoreSingleRegister
: public ARMv7DOpcodeDataStoreSingle
{
1093 static const uint32_t s_mask
= 0xfff00fc0;
1094 static const uint32_t s_pattern
= 0xf8400000;
1096 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleRegister
, thisObj
);
1099 const char* format();
1101 unsigned immediate2() { return (m_opcode
>> 4) & 0x3; }
1104 class ARMv7DOpcodeUnmodifiedImmediate
: public ARMv7D32BitOpcode
{
1106 static const char* const s_opNames
[16];
1109 static const uint32_t s_mask
= 0xfa008000;
1110 static const uint32_t s_pattern
= 0xf2000000;
1112 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeUnmodifiedImmediate
, thisObj
);
1115 const char* format();
1117 const char* opName() { return s_opNames
[op() >> 1]; }
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); }
1127 class ARMv7DOpcodeVCMP
: public ARMv7D32BitOpcode
{
1129 static const uint32_t s_mask
= 0x0fbf0e50;
1130 static const uint32_t s_pattern
= 0x0eb40a40;
1132 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCMP
, thisObj
);
1135 const char* format();
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; }
1146 class ARMv7DOpcodeVCVTBetweenFPAndInt
: public ARMv7D32BitOpcode
{
1148 static const uint32_t s_mask
= 0x0fb80e50;
1149 static const uint32_t s_pattern
= 0x0eb80a40;
1151 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCVTBetweenFPAndInt
, thisObj
);
1154 const char* format();
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; }
1166 class ARMv7DOpcodeVLDR
: public ARMv7D32BitOpcode
{
1168 static const uint32_t s_mask
= 0x0f300e00;
1169 static const uint32_t s_pattern
= 0x0d100a00;
1171 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVLDR
, thisObj
);
1174 const char* format();
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; }
1184 class ARMv7DOpcodeVMOVDoublePrecision
: public ARMv7D32BitOpcode
{
1186 static const uint32_t s_mask
= 0xffe00fd0;
1187 static const uint32_t s_pattern
= 0xec400b10;
1189 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVDoublePrecision
, thisObj
);
1192 const char* format();
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); }
1200 class ARMv7DOpcodeVMOVSinglePrecision
: public ARMv7D32BitOpcode
{
1202 static const uint32_t s_mask
= 0xffe00fd0;
1203 static const uint32_t s_pattern
= 0xec400a10;
1205 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVSinglePrecision
, thisObj
);
1208 const char* format();
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); }
1216 class ARMv7DOpcodeVMSR
: public ARMv7D32BitOpcode
{
1218 static const uint32_t s_mask
= 0xffef0fff;
1219 static const uint32_t s_pattern
= 0xeee10a10;
1221 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMSR
, thisObj
);
1224 const char* format();
1226 unsigned opL() { return (m_opcode
>> 20) & 0x1; }
1227 unsigned rt() { return (m_opcode
>> 12) & 0xf; }
1231 } } // namespace JSC::ARMv7Disassembler
1233 using JSC::ARMv7Disassembler::ARMv7DOpcode
;
1235 #endif // #if USE(ARMV7_DISASSEMBLER)
1237 #endif // ARMv7DOpcode_h