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) & 0x3; }
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; }
444 unsigned scale() { return 2 - (op() >> 1); }
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 ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord
: 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 ARMv7DOpcodeLoadStoreRegisterOffsetT1
: public ARMv7D16BitOpcode
{
465 static const char* const s_opNames
[8];
468 static const uint16_t s_mask
= 0xf000;
469 static const uint16_t s_pattern
= 0x5000;
471 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterOffsetT1
, thisObj
);
474 const char* format();
476 const char* opName() { return s_opNames
[opB()]; }
478 unsigned opB() { return (m_opcode
>> 9) & 0x7; }
479 unsigned rm() { return (m_opcode
>> 6) & 0x7; }
480 unsigned rn() { return (m_opcode
>> 3) & 0x7; }
481 unsigned rt() { return m_opcode
& 0x7; }
484 class ARMv7DOpcodeLoadStoreRegisterSPRelative
: public ARMv7D16BitOpcode
{
486 static const char* const s_opNames
[8];
489 static const uint16_t s_mask
= 0xf000;
490 static const uint16_t s_pattern
= 0x9000;
492 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterSPRelative
, thisObj
);
495 const char* format();
497 const char* opName() { return op() ? "ldr" : "str"; }
499 unsigned op() { return (m_opcode
>> 11) & 0x1; }
500 unsigned rt() { return (m_opcode
>> 8) & 0x7; }
501 unsigned immediate8() { return m_opcode
& 0xff; }
504 class ARMv7DOpcodeLogicalImmediateT1
: public ARMv7D16BitOpcode
{
506 static const uint16_t s_mask
= 0xe000;
507 static const uint16_t s_pattern
= 0x0000;
509 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLogicalImmediateT1
, thisObj
);
512 const char* format();
514 const char* opName() { return shiftName(op()); }
516 unsigned op() { return (m_opcode
>> 12) & 0x3; }
517 unsigned immediate5() { return (m_opcode
>> 6) & 0x1f; }
520 class ARMv7DOpcodeMiscAddSubSP
: public ARMv7D16BitOpcode
{
522 static const uint16_t s_mask
= 0xff00;
523 static const uint16_t s_pattern
= 0xb000;
525 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscAddSubSP
, thisObj
);
528 const char* format();
530 const char* opName() { return op() ? "sub" : "add"; }
531 unsigned op() { return (m_opcode
>> 7) & 0x1; }
532 unsigned immediate7() { return m_opcode
& 0x7f; }
535 class ARMv7DOpcodeMiscByteHalfwordOps
: public ARMv7D16BitOpcode
{
537 static const char* const s_opNames
[8];
540 static const uint16_t s_mask
= 0xf700;
541 static const uint16_t s_pattern
= 0xb200;
543 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscByteHalfwordOps
, thisObj
);
546 const char* format();
548 const char* opName() { return s_opNames
[op()]; }
549 unsigned op() { return ((m_opcode
>> 9) & 0x4) || ((m_opcode
>> 6) & 0x3); }
552 class ARMv7DOpcodeMiscBreakpointT1
: public ARMv7D16BitOpcode
{
554 static const uint16_t s_mask
= 0xff00;
555 static const uint16_t s_pattern
= 0xbe00;
557 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscBreakpointT1
, thisObj
);
560 const char* format();
562 unsigned immediate8() { return m_opcode
& 0xff; }
565 class ARMv7DOpcodeMiscCompareAndBranch
: public ARMv7D16BitOpcode
{
567 static const uint16_t s_mask
= 0xf500;
568 static const uint16_t s_pattern
= 0xb100;
570 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscCompareAndBranch
, thisObj
);
573 const char* format();
575 const char* opName() { return op() ? "cbnz" : "cbz"; }
576 unsigned op() { return (m_opcode
>> 11) & 0x1; }
577 int32_t immediate6() { return ((m_opcode
>> 4) & 0x20) | ((m_opcode
>> 3) & 0x1f); }
578 unsigned rn() { return m_opcode
& 0x7; }
581 class ARMv7DOpcodeMiscHint16
: public ARMv7D16BitOpcode
{
583 static const char* const s_opNames
[16];
586 static const uint16_t s_mask
= 0xff0f;
587 static const uint16_t s_pattern
= 0xbf00;
589 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscHint16
, thisObj
);
592 const char* format();
594 const char* opName() { return s_opNames
[opA()]; }
595 unsigned opA() { return (m_opcode
>> 4) & 0xf; }
598 class ARMv7DOpcodeMiscIfThenT1
: public ARMv7D16BitOpcode
{
600 static const uint16_t s_mask
= 0xff00;
601 static const uint16_t s_pattern
= 0xbf00;
603 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscIfThenT1
, thisObj
);
606 const char* format();
608 unsigned firstCondition() { return (m_opcode
>> 4) & 0xf; }
609 unsigned mask() { return m_opcode
& 0xf; }
612 class ARMv7DOpcodeMiscPushPop
: public ARMv7D16BitOpcode
{
614 static const uint16_t s_mask
= 0xf600;
615 static const uint16_t s_pattern
= 0xb400;
617 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscPushPop
, thisObj
);
620 const char* format();
622 const char* opName() { return op() ? "pop" : "push"; }
623 unsigned op() { return (m_opcode
>> 11) & 0x1; }
624 unsigned registerMask() { return ((m_opcode
<< 6) & 0x4000) | (m_opcode
& 0x7f); }
627 class ARMv7DOpcodeMoveImmediateT1
: public ARMv7D16BitOpcode
{
629 static const uint16_t s_mask
= 0xf800;
630 static const uint16_t s_pattern
= 0x2000;
632 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveImmediateT1
, thisObj
);
635 const char* format();
637 unsigned rd() { return (m_opcode
>> 8) & 0x3; }
638 unsigned immediate8() { return m_opcode
& 0xff; }
641 class ARMv7DOpcodeMoveRegisterT1
: public ARMv7D16BitOpcode
{
643 static const uint16_t s_mask
= 0xff00;
644 static const uint16_t s_pattern
= 0x4600;
646 DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveRegisterT1
, thisObj
);
649 const char* format();
651 unsigned rd() { return ((m_opcode
>> 4) & 0x8) | (m_opcode
& 0x7); }
652 unsigned rm() { return ((m_opcode
>> 3) & 0xf); }
655 // 32 Bit instructions
657 #define DEFINE_STATIC_FORMAT32(klass, thisObj) \
658 static const char* format(ARMv7D32BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
660 class ARMv7D32BitOpcode
: public ARMv7DOpcode
{
664 OpcodeGroup(uint32_t opcodeMask
, uint32_t opcodePattern
, const char* (*format
)(ARMv7D32BitOpcode
*))
665 : m_opcodeMask(opcodeMask
)
666 , m_opcodePattern(opcodePattern
)
672 void setNext(OpcodeGroup
* next
)
682 bool matches(uint32_t opcode
)
684 return (opcode
& m_opcodeMask
) == m_opcodePattern
;
687 const char* format(ARMv7D32BitOpcode
* thisObj
)
689 return m_format(thisObj
);
693 static const unsigned opcodeTableSize
= 16;
694 static const unsigned opcodeTableMask
= opcodeTableSize
-1;
697 uint32_t m_opcodeMask
;
698 uint32_t m_opcodePattern
;
699 const char* (*m_format
)(ARMv7D32BitOpcode
*);
706 const char* defaultFormat();
707 const char* doDisassemble();
710 unsigned rd() { return (m_opcode
>> 8) & 0xf; }
711 unsigned rm() { return m_opcode
& 0xf; }
712 unsigned rn() { return (m_opcode
>> 16) & 0xf; }
713 unsigned rt() { return (m_opcode
>> 12) & 0xf; }
715 unsigned opcodeGroupNumber(unsigned opcode
) { return (opcode
>> 25) & OpcodeGroup::opcodeTableMask
; }
718 static OpcodeGroup
* opcodeTable
[OpcodeGroup::opcodeTableSize
];
721 class ARMv7DOpcodeBranchRelative
: public ARMv7D32BitOpcode
{
723 unsigned sBit() { return (m_opcode
>> 26) & 0x1; }
724 unsigned j1() { return (m_opcode
>> 13) & 0x1; }
725 unsigned j2() { return (m_opcode
>> 11) & 0x1; }
726 unsigned immediate11() { return m_opcode
& 0x7ff; }
729 class ARMv7DOpcodeConditionalBranchT3
: public ARMv7DOpcodeBranchRelative
{
731 static const uint32_t s_mask
= 0xf800d000;
732 static const uint32_t s_pattern
= 0xf0008000;
734 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeConditionalBranchT3
, thisObj
);
737 const char* format();
739 int32_t offset() { return ((static_cast<int32_t>(sBit() << 31)) >> 12) | static_cast<int32_t>((j1() << 18) | (j2() << 17) | (immediate6() << 11) | immediate11()); }
740 unsigned condition() { return (m_opcode
>> 22) & 0xf; }
741 unsigned immediate6() { return (m_opcode
>> 16) & 0x3f; }
744 class ARMv7DOpcodeBranchOrBranchLink
: public ARMv7DOpcodeBranchRelative
{
746 static const uint32_t s_mask
= 0xf8009000;
747 static const uint32_t s_pattern
= 0xf0009000;
749 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeBranchOrBranchLink
, thisObj
);
752 const char* format();
754 int32_t offset() { return ((static_cast<int32_t>(sBit() << 31)) >> 8) | static_cast<int32_t>((~(j1() ^ sBit()) << 22) | (~(j2() ^ sBit()) << 21) | (immediate10() << 11) | immediate11()); }
755 unsigned immediate10() { return (m_opcode
>> 16) & 0x3ff; }
756 bool isBL() { return !!((m_opcode
>> 14) & 0x1); }
759 class ARMv7DOpcodeDataProcessingLogicalAndRithmetic
: public ARMv7D32BitOpcode
{
761 static const char* const s_opNames
[16];
764 class ARMv7DOpcodeDataProcessingModifiedImmediate
: public ARMv7DOpcodeDataProcessingLogicalAndRithmetic
{
766 void appendImmShift(unsigned, unsigned);
769 static const uint32_t s_mask
= 0xfa008000;
770 static const uint32_t s_pattern
= 0xf0000000;
772 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingModifiedImmediate
, thisObj
);
775 const char* format();
776 void appendModifiedImmediate(unsigned);
778 const char* opName() { return s_opNames
[op()]; }
780 unsigned op() { return (m_opcode
>> 21) & 0xf; }
781 unsigned sBit() { return (m_opcode
>> 20) & 0x1; }
782 unsigned immediate12() { return ((m_opcode
>> 15) & 0x0800) | ((m_opcode
>> 4) & 0x0700) | (m_opcode
& 0x00ff); }
785 class ARMv7DOpcodeDataProcessingShiftedReg
: public ARMv7DOpcodeDataProcessingLogicalAndRithmetic
{
787 void appendImmShift(unsigned, unsigned);
790 static const uint32_t s_mask
= 0xfe000000;
791 static const uint32_t s_pattern
= 0xea000000;
793 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingShiftedReg
, thisObj
);
796 const char* format();
798 const char* opName() { return s_opNames
[op()]; }
800 unsigned sBit() { return (m_opcode
>> 20) & 0x1; }
801 unsigned op() { return (m_opcode
>> 21) & 0xf; }
802 unsigned immediate5() { return ((m_opcode
>> 10) & 0x1c) | ((m_opcode
>> 6) & 0x3); }
803 unsigned type() { return (m_opcode
>> 4) & 0x3; }
804 unsigned tbBit() { return (m_opcode
>> 5) & 0x1; }
805 unsigned tBit() { return (m_opcode
>> 4) & 0x1; }
808 class ARMv7DOpcodeDataProcessingReg
: public ARMv7D32BitOpcode
{
810 unsigned op1() { return (m_opcode
>> 20) & 0xf; }
811 unsigned op2() { return (m_opcode
>> 4) & 0xf; }
814 class ARMv7DOpcodeDataProcessingRegShift
: public ARMv7DOpcodeDataProcessingReg
{
816 static const uint32_t s_mask
= 0xffe0f0f0;
817 static const uint32_t s_pattern
= 0xfa00f000;
819 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegShift
, thisObj
);
822 const char* format();
824 const char* opName() { return shiftName((op1() >> 1) & 0x3); }
827 class ARMv7DOpcodeDataProcessingRegExtend
: public ARMv7DOpcodeDataProcessingReg
{
829 static const char* const s_opExtendNames
[8];
830 static const char* const s_opExtendAndAddNames
[8];
833 static const uint32_t s_mask
= 0xff80f0c0;
834 static const uint32_t s_pattern
= 0xfa00f080;
836 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegExtend
, thisObj
);
839 const char* format();
841 const char* opExtendName() { return s_opExtendNames
[op1()]; }
842 const char* opExtendAndAddName() { return s_opExtendAndAddNames
[op1()]; }
843 unsigned rotate() { return (m_opcode
>> 4) & 0x3; }
846 class ARMv7DOpcodeDataProcessingRegParallel
: public ARMv7DOpcodeDataProcessingReg
{
848 static const char* const s_opNames
[16];
851 static const uint32_t s_mask
= 0xff80f0e0;
852 static const uint32_t s_pattern
= 0xfa00f000;
854 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegParallel
, thisObj
);
857 const char* format();
859 const char* opName() { return s_opNames
[((op1() & 0x7) << 1) | (op2() & 0x1)]; }
862 class ARMv7DOpcodeDataProcessingRegMisc
: public ARMv7DOpcodeDataProcessingReg
{
864 static const char* const s_opNames
[16];
867 static const uint32_t s_mask
= 0xffc0f0c0;
868 static const uint32_t s_pattern
= 0xfa80f080;
870 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegMisc
, thisObj
);
873 const char* format();
875 const char* opName() { return s_opNames
[((op1() & 0x3) << 2) | (op2() & 0x3)]; }
878 class ARMv7DOpcodeHint32
: public ARMv7D32BitOpcode
{
880 static const char* const s_opNames
[8];
883 static const uint32_t s_mask
= 0xfff0d000;
884 static const uint32_t s_pattern
= 0xf3a08000;
886 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeHint32
, thisObj
);
889 const char* format();
891 const char* opName() { return s_opNames
[op()]; }
893 bool isDebugHint() { return (m_opcode
& 0xf0) == 0xf0; }
894 unsigned debugOption() { return m_opcode
& 0xf; }
895 unsigned op() { return m_opcode
& 0x7; }
898 class ARMv7DOpcodeFPTransfer
: public ARMv7D32BitOpcode
{
900 static const uint32_t s_mask
= 0xffc00e7f;
901 static const uint32_t s_pattern
= 0xee000a10;
903 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeFPTransfer
, thisObj
);
906 const char* format();
908 void appendFPRegister();
910 unsigned opH() { return (m_opcode
>> 21) & 0x1; }
911 unsigned opL() { return (m_opcode
>> 20) & 0x1; }
912 unsigned rt() { return (m_opcode
>> 12) & 0xf; }
913 unsigned opC() { return (m_opcode
>> 8) & 0x1; }
914 unsigned opB() { return (m_opcode
>> 5) & 0x3; }
915 unsigned vd() { return ((m_opcode
>> 3) & 0x10) | ((m_opcode
>> 16) & 0xf); }
916 unsigned vn() { return ((m_opcode
>> 7) & 0x1) | ((m_opcode
>> 15) & 0x1e); }
919 class ARMv7DOpcodeDataLoad
: public ARMv7D32BitOpcode
{
921 static const char* const s_opNames
[8];
924 const char* opName() { return s_opNames
[op()]; }
926 unsigned op() { return ((m_opcode
>> 22) & 0x4) | ((m_opcode
>> 21) & 0x3); }
929 class ARMv7DOpcodeLoadRegister
: public ARMv7DOpcodeDataLoad
{
931 static const uint32_t s_mask
= 0xfe900800;
932 static const uint32_t s_pattern
= 0xf8100000;
934 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadRegister
, thisObj
);
937 const char* format();
939 unsigned immediate2() { return (m_opcode
>> 4) & 0x3; }
942 class ARMv7DOpcodeLoadSignedImmediate
: public ARMv7DOpcodeDataLoad
{
944 static const uint32_t s_mask
= 0xfe900800;
945 static const uint32_t s_pattern
= 0xf8100800;
947 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadSignedImmediate
, thisObj
);
950 const char* format();
952 unsigned pBit() { return (m_opcode
>> 10) & 0x1; }
953 unsigned uBit() { return (m_opcode
>> 9) & 0x1; }
954 unsigned wBit() { return (m_opcode
>> 8) & 0x1; }
955 unsigned immediate8() { return m_opcode
& 0xff; }
958 class ARMv7DOpcodeLoadUnsignedImmediate
: public ARMv7DOpcodeDataLoad
{
960 static const uint32_t s_mask
= 0xfe900000;
961 static const uint32_t s_pattern
= 0xf8900000;
963 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadUnsignedImmediate
, thisObj
);
966 const char* format();
968 unsigned immediate12() { return m_opcode
& 0xfff; }
971 class ARMv7DOpcodeLongMultipleDivide
: public ARMv7D32BitOpcode
{
973 static const char* const s_opNames
[8];
974 static const char* const s_smlalOpNames
[4];
975 static const char* const s_smlaldOpNames
[2];
976 static const char* const s_smlsldOpNames
[2];
979 static const uint32_t s_mask
= 0xff800000;
980 static const uint32_t s_pattern
= 0xfb800000;
982 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLongMultipleDivide
, thisObj
);
985 const char* format();
987 const char* opName() { return s_opNames
[op1()]; }
988 const char* smlalOpName() { return s_smlalOpNames
[(nBit() << 1) | mBit()]; }
989 const char* smlaldOpName() { return s_smlaldOpNames
[mBit()]; }
990 const char* smlsldOpName() { return s_smlsldOpNames
[mBit()]; }
992 unsigned rdLo() { return rt(); }
993 unsigned rdHi() { return rd(); }
994 unsigned op1() { return (m_opcode
>> 20) & 0x7; }
995 unsigned op2() { return (m_opcode
>> 4) & 0xf; }
996 unsigned nBit() { return (m_opcode
>> 5) & 0x1; }
997 unsigned mBit() { return (m_opcode
>> 4) & 0x1; }
1000 class ARMv7DOpcodeDataPushPopSingle
: public ARMv7D32BitOpcode
{
1002 static const uint32_t s_mask
= 0xffef0fff;
1003 static const uint32_t s_pattern
= 0xf84d0d04;
1005 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushPopSingle
, thisObj
);
1008 const char* format();
1010 const char* opName() { return op() ? "pop" : "push"; }
1011 unsigned op() { return (m_opcode
>> 20) & 0x1; }
1014 class ARMv7DOpcodeDataStoreSingle
: public ARMv7D32BitOpcode
{
1016 static const char* const s_opNames
[4];
1019 const char* opName() { return s_opNames
[op()]; }
1021 unsigned op() { return (m_opcode
>> 21) & 0x3; }
1024 class ARMv7DOpcodeStoreSingleImmediate12
: public ARMv7DOpcodeDataStoreSingle
{
1026 static const uint32_t s_mask
= 0xfff00000;
1027 static const uint32_t s_pattern
= 0xf8c00000;
1029 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate12
, thisObj
);
1031 const char* format();
1034 unsigned immediate12() { return m_opcode
& 0xfff; }
1037 class ARMv7DOpcodeStoreSingleImmediate8
: public ARMv7DOpcodeDataStoreSingle
{
1039 static const uint32_t s_mask
= 0xfff00800;
1040 static const uint32_t s_pattern
= 0xf8400800;
1042 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate8
, thisObj
);
1044 const char* format();
1047 unsigned pBit() { return (m_opcode
>> 10) & 0x1; }
1048 unsigned uBit() { return (m_opcode
>> 9) & 0x1; }
1049 unsigned wBit() { return (m_opcode
>> 8) & 0x1; }
1050 unsigned immediate8() { return m_opcode
& 0xff; }
1053 class ARMv7DOpcodeStoreSingleRegister
: public ARMv7DOpcodeDataStoreSingle
{
1055 static const uint32_t s_mask
= 0xfff00fc0;
1056 static const uint32_t s_pattern
= 0xf8400000;
1058 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleRegister
, thisObj
);
1061 const char* format();
1063 unsigned immediate2() { return (m_opcode
>> 4) & 0x3; }
1066 class ARMv7DOpcodeUnmodifiedImmediate
: public ARMv7D32BitOpcode
{
1068 static const char* const s_opNames
[16];
1071 static const uint32_t s_mask
= 0xfa008000;
1072 static const uint32_t s_pattern
= 0xf2000000;
1074 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeUnmodifiedImmediate
, thisObj
);
1077 const char* format();
1079 const char* opName() { return s_opNames
[op() >> 1]; }
1081 unsigned op() { return (m_opcode
>> 20) & 0x1f; }
1082 unsigned shBit() { return (m_opcode
>> 21) & 0x1; }
1083 unsigned bitNumOrSatImmediate() { return m_opcode
& 0x1f; }
1084 unsigned immediate5() { return ((m_opcode
>> 9) & 0x1c) | ((m_opcode
>> 6) & 0x3); }
1085 unsigned immediate12() { return ((m_opcode
>> 15) & 0x0800) | ((m_opcode
>> 4) & 0x0700) | (m_opcode
& 0x00ff); }
1086 unsigned immediate16() { return ((m_opcode
>> 4) & 0xf000) | ((m_opcode
>> 15) & 0x0800) | ((m_opcode
>> 4) & 0x0700) | (m_opcode
& 0x00ff); }
1089 class ARMv7DOpcodeVMOVDoublePrecision
: public ARMv7D32BitOpcode
{
1091 static const uint32_t s_mask
= 0xffe00fd0;
1092 static const uint32_t s_pattern
= 0xec400b10;
1094 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVDoublePrecision
, thisObj
);
1097 const char* format();
1099 unsigned op() { return (m_opcode
>> 20) & 0x1; }
1100 unsigned rt2() { return (m_opcode
>> 16) & 0xf; }
1101 unsigned rt() { return (m_opcode
>> 16) & 0xf; }
1102 unsigned vm() { return (m_opcode
& 0xf) | ((m_opcode
>> 1) & 0x10); }
1105 class ARMv7DOpcodeVMOVSinglePrecision
: public ARMv7D32BitOpcode
{
1107 static const uint32_t s_mask
= 0xffe00fd0;
1108 static const uint32_t s_pattern
= 0xec400a10;
1110 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVSinglePrecision
, thisObj
);
1113 const char* format();
1115 unsigned op() { return (m_opcode
>> 20) & 0x1; }
1116 unsigned rt2() { return (m_opcode
>> 16) & 0xf; }
1117 unsigned rt() { return (m_opcode
>> 16) & 0xf; }
1118 unsigned vm() { return ((m_opcode
<< 1) & 0x1e) | ((m_opcode
>> 5) & 0x1); }
1121 class ARMv7DOpcodeVMSR
: public ARMv7D32BitOpcode
{
1123 static const uint32_t s_mask
= 0xffef0fff;
1124 static const uint32_t s_pattern
= 0xeee10a10;
1126 DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMSR
, thisObj
);
1129 const char* format();
1131 unsigned opL() { return (m_opcode
>> 20) & 0x1; }
1132 unsigned rt() { return (m_opcode
>> 12) & 0xf; }
1136 } } // namespace JSC::ARMv7Disassembler
1138 using JSC::ARMv7Disassembler::ARMv7DOpcode
;
1140 #endif // #if USE(ARMV7_DISASSEMBLER)
1142 #endif // ARMv7DOpcode_h