2 * Copyright (C) 2012 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.
29 #include <wtf/Assertions.h>
32 namespace JSC
{ namespace ARM64Disassembler
{
38 OpcodeGroup(uint32_t opcodeMask
, uint32_t opcodePattern
, const char* (*format
)(A64DOpcode
*))
39 : m_opcodeMask(opcodeMask
)
40 , m_opcodePattern(opcodePattern
)
46 void setNext(OpcodeGroup
* next
)
56 bool matches(uint32_t opcode
)
58 return (opcode
& m_opcodeMask
) == m_opcodePattern
;
61 const char* format(A64DOpcode
* thisObj
)
63 return m_format(thisObj
);
67 uint32_t m_opcodeMask
;
68 uint32_t m_opcodePattern
;
69 const char* (*m_format
)(A64DOpcode
*);
81 m_formatBuffer
[0] = '\0';
84 const char* disassemble(uint32_t* currentPC
);
87 void setPCAndOpcode(uint32_t*, uint32_t);
90 static const char* const s_conditionNames
[16];
91 static const char* const s_shiftNames
[4];
92 static const char* const s_optionName
[8];
93 static const char s_FPRegisterPrefix
[5];
95 static const char* conditionName(unsigned condition
) { return s_conditionNames
[condition
& 0xf]; }
96 static const char* shiftName(unsigned shiftValue
) { return s_shiftNames
[shiftValue
& 0x3]; }
97 const char* optionName() { return s_optionName
[option()]; }
98 static char FPRegisterPrefix(unsigned FPRegisterSize
)
100 if (FPRegisterSize
> 4)
102 return s_FPRegisterPrefix
[FPRegisterSize
];
105 unsigned opcodeGroupNumber(uint32_t opcode
) { return (opcode
>> 24) & 0x1f; }
107 bool is64Bit() { return m_opcode
& 0x80000000; }
108 unsigned size() { return m_opcode
>> 30; }
109 unsigned option() { return (m_opcode
>> 13) & 0x7; }
110 unsigned rd() { return m_opcode
& 0x1f; }
111 unsigned rt() { return m_opcode
& 0x1f; }
112 unsigned rn() { return (m_opcode
>> 5) & 0x1f; }
113 unsigned rm() { return (m_opcode
>> 16) & 0x1f; }
115 void bufferPrintf(const char* format
, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
117 void appendInstructionName(const char* instructionName
)
119 bufferPrintf(" %-7.7s", instructionName
);
122 void appendRegisterName(unsigned registerNumber
, bool is64Bit
= true);
123 void appendSPOrRegisterName(unsigned registerNumber
, bool is64Bit
= true)
125 if (registerNumber
== 31) {
126 bufferPrintf(is64Bit
? "sp" : "wsp");
129 appendRegisterName(registerNumber
, is64Bit
);
132 void appendZROrRegisterName(unsigned registerNumber
, bool is64Bit
= true)
134 if (registerNumber
== 31) {
135 bufferPrintf(is64Bit
? "xzr" : "wzr");
138 appendRegisterName(registerNumber
, is64Bit
);
141 void appendFPRegisterName(unsigned registerNumber
, unsigned registerSize
);
143 void appendSeparator()
148 void appendCharacter(const char c
)
150 bufferPrintf("%c", c
);
153 void appendString(const char* string
)
155 bufferPrintf("%s", string
);
158 void appendShiftType(unsigned shiftValue
)
160 bufferPrintf("%s ", shiftName(shiftValue
));
163 void appendSignedImmediate(int immediate
)
165 bufferPrintf("#%d", immediate
);
168 void appendUnsignedImmediate(unsigned immediate
)
170 bufferPrintf("#%u", immediate
);
173 void appendUnsignedImmediate64(uint64_t immediate
)
175 bufferPrintf("#0x%llx", immediate
);
178 void appendPCRelativeOffset(uint32_t* pc
, int32_t immediate
)
180 bufferPrintf("0x%llx", reinterpret_cast<uint64_t>(pc
+ immediate
));
183 void appendShiftAmount(unsigned amount
)
185 bufferPrintf("lsl #%u", 16 * amount
);
188 static const int bufferSize
= 81;
190 char m_formatBuffer
[bufferSize
];
191 uint32_t* m_currentPC
;
196 static OpcodeGroup
* opcodeTable
[32];
198 static bool s_initialized
;
201 #define DEFINE_STATIC_FORMAT(klass, thisObj) \
202 static const char* format(A64DOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
204 class A64DOpcodeAddSubtract
: public A64DOpcode
{
206 static const char* const s_opNames
[4];
209 const char* opName() { return s_opNames
[opAndS()]; }
210 const char* cmpName() { return op() ? "cmp" : "cmn"; }
212 bool isCMP() { return (sBit() && rd() == 31); }
213 unsigned op() { return (m_opcode
>> 30) & 0x1; }
214 unsigned sBit() { return (m_opcode
>> 29) & 0x1; }
215 unsigned opAndS() { return (m_opcode
>> 29) & 0x3; }
218 class A64DOpcodeAddSubtractImmediate
: public A64DOpcodeAddSubtract
{
220 static const uint32_t mask
= 0x1f000000;
221 static const uint32_t pattern
= 0x11000000;
223 DEFINE_STATIC_FORMAT(A64DOpcodeAddSubtractImmediate
, thisObj
);
225 const char* format();
227 bool isMovSP() { return (!opAndS() && !immed12() && ((rd() == 31) || rn() == 31)); }
228 unsigned shift() { return (m_opcode
>> 22) & 0x3; }
229 unsigned immed12() { return (m_opcode
>> 10) & 0xfff; }
232 class A64DOpcodeAddSubtractExtendedRegister
: public A64DOpcodeAddSubtract
{
234 static const uint32_t mask
= 0x1fe00000;
235 static const uint32_t pattern
= 0x0b200000;
237 DEFINE_STATIC_FORMAT(A64DOpcodeAddSubtractExtendedRegister
, thisObj
);
239 const char* format();
241 unsigned immediate3() { return (m_opcode
>> 10) & 0x7; }
244 class A64DOpcodeAddSubtractShiftedRegister
: public A64DOpcodeAddSubtract
{
246 static const uint32_t mask
= 0x1f200000;
247 static const uint32_t pattern
= 0x0b000000;
249 DEFINE_STATIC_FORMAT(A64DOpcodeAddSubtractShiftedRegister
, thisObj
);
251 const char* format();
253 bool isNeg() { return (op() && rn() == 31); }
254 const char* negName() { return sBit() ? "negs" : "neg"; }
255 unsigned shift() { return (m_opcode
>> 22) & 0x3; }
256 int immediate6() { return (static_cast<int>((m_opcode
>> 10) & 0x3f) << 26) >> 26; }
259 class A64DOpcodeBitfield
: public A64DOpcode
{
261 static const char* const s_opNames
[3];
262 static const char* const s_extendPseudoOpNames
[3][3];
263 static const char* const s_insertOpNames
[3];
264 static const char* const s_extractOpNames
[3];
267 static const uint32_t mask
= 0x1f800000;
268 static const uint32_t pattern
= 0x13000000;
270 DEFINE_STATIC_FORMAT(A64DOpcodeBitfield
, thisObj
);
272 const char* format();
274 const char* opName() { return s_opNames
[opc()]; }
275 const char* extendPseudoOpNames(unsigned opSize
) { return s_extendPseudoOpNames
[opc()][opSize
]; }
276 const char* insertOpNames() { return s_insertOpNames
[opc()]; }
277 const char* extractOpNames() { return s_extractOpNames
[opc()]; }
279 unsigned opc() { return (m_opcode
>> 29) & 0x3; }
280 unsigned nBit() { return (m_opcode
>> 22) & 0x1; }
281 unsigned immediateR() { return (m_opcode
>> 16) & 0x3f; }
282 unsigned immediateS() { return (m_opcode
>> 10) & 0x3f; }
285 class A64DOpcodeCompareAndBranchImmediate
: public A64DOpcode
{
287 static const uint32_t mask
= 0x7e000000;
288 static const uint32_t pattern
= 0x34000000;
290 DEFINE_STATIC_FORMAT(A64DOpcodeCompareAndBranchImmediate
, thisObj
);
292 const char* format();
294 unsigned opBit() { return (m_opcode
>> 24) & 0x1; }
295 int immediate19() { return (static_cast<int>((m_opcode
>> 5) & 0x7ffff) << 13) >> 13; }
298 class A64DOpcodeConditionalBranchImmediate
: public A64DOpcode
{
300 static const uint32_t mask
= 0xff000010;
301 static const uint32_t pattern
= 0x54000000;
303 DEFINE_STATIC_FORMAT(A64DOpcodeConditionalBranchImmediate
, thisObj
);
305 const char* format();
307 unsigned condition() { return m_opcode
& 0xf; }
308 int immediate19() { return (static_cast<int>((m_opcode
>> 5) & 0x7ffff) << 13) >> 13; }
311 class A64DOpcodeConditionalSelect
: public A64DOpcode
{
313 static const char* const s_opNames
[4];
316 static const uint32_t mask
= 0x1fe00010;
317 static const uint32_t pattern
= 0x1a800000;
319 DEFINE_STATIC_FORMAT(A64DOpcodeConditionalSelect
, thisObj
);
321 const char* format();
323 const char* opName() { return s_opNames
[opNum()]; }
324 unsigned opNum() { return (op() << 1 | (op2() & 0x1)); }
325 unsigned op() { return (m_opcode
>> 30) & 0x1; }
326 unsigned sBit() { return (m_opcode
>> 29) & 0x1; }
327 unsigned condition() { return (m_opcode
>> 12) & 0xf; }
328 unsigned op2() { return (m_opcode
>> 10) & 0x3; }
331 class A64DOpcodeDataProcessing2Source
: public A64DOpcode
{
333 static const char* const s_opNames
[8];
336 static const uint32_t mask
= 0x5fe00000;
337 static const uint32_t pattern
= 0x1ac00000;
339 DEFINE_STATIC_FORMAT(A64DOpcodeDataProcessing2Source
, thisObj
);
341 const char* format();
343 const char* opName() { return s_opNames
[opNameIndex()]; }
344 unsigned sBit() { return (m_opcode
>> 29) & 0x1; }
345 unsigned opCode() { return (m_opcode
>> 10) & 0x3f; }
346 unsigned opNameIndex() { return ((m_opcode
>> 11) & 0x4) | ((m_opcode
>> 10) & 0x3); }
349 class A64DOpcodeDataProcessing3Source
: public A64DOpcode
{
351 static const char* const s_opNames
[16];
352 static const char* const s_pseudoOpNames
[16];
355 static const uint32_t mask
= 0x1f000000;
356 static const uint32_t pattern
= 0x1b000000;
358 DEFINE_STATIC_FORMAT(A64DOpcodeDataProcessing3Source
, thisObj
);
360 const char* format();
362 const char* opName() { return ra() == 31 ? s_opNames
[opNum() & 0xf] : s_pseudoOpNames
[opNum() & 0xf]; }
363 unsigned ra() { return (m_opcode
>> 10) & 0x1f; }
364 unsigned op54() { return (m_opcode
>> 29) & 0x3; }
365 unsigned op31() { return (m_opcode
>> 21) & 0x7; }
366 unsigned op0() { return (m_opcode
>> 15) & 0x1; }
367 unsigned opNum() { return ((m_opcode
>> 25) & 0x30) | ((m_opcode
>> 20) & 0xe) | ((m_opcode
>> 15) & 0x1); }
370 class A64OpcodeExceptionGeneration
: public A64DOpcode
{
372 static const uint32_t mask
= 0xff000010;
373 static const uint32_t pattern
= 0xd4000000;
375 DEFINE_STATIC_FORMAT(A64OpcodeExceptionGeneration
, thisObj
);
377 const char* format();
379 unsigned opc() { return (m_opcode
>>21) & 0x7; }
380 unsigned op2() { return (m_opcode
>>2) & 0x7; }
381 unsigned ll() { return m_opcode
& 0x3; }
382 int immediate16() { return (static_cast<int>((m_opcode
>> 5) & 0xffff) << 16) >> 16; }
385 class A64DOpcodeExtract
: public A64DOpcode
{
387 static const uint32_t mask
= 0x1f800000;
388 static const uint32_t pattern
= 0x13800000;
390 DEFINE_STATIC_FORMAT(A64DOpcodeExtract
, thisObj
);
392 const char* format();
394 unsigned op21() { return (m_opcode
>> 29) & 0x3; }
395 unsigned nBit() { return (m_opcode
>> 22) & 0x1; }
396 unsigned o0Bit() { return (m_opcode
>> 21) & 0x1; }
397 unsigned immediateS() { return (m_opcode
>> 10) & 0x3f; }
400 class A64DOpcodeFloatingPointOps
: public A64DOpcode
{
402 unsigned mBit() { return (m_opcode
>> 31) & 0x1; }
403 unsigned sBit() { return (m_opcode
>> 29) & 0x1; }
404 unsigned type() { return (m_opcode
>> 22) & 0x3; }
407 class A64DOpcodeFloatingPointCompare
: public A64DOpcodeFloatingPointOps
{
409 static const char* const s_opNames
[16];
412 static const uint32_t mask
= 0x5f203c00;
413 static const uint32_t pattern
= 0x1e202000;
415 DEFINE_STATIC_FORMAT(A64DOpcodeFloatingPointCompare
, thisObj
);
417 const char* format();
419 const char* opName() { return (opNum() & 0x2) ? "fcmpe" : "fcmp"; }
421 unsigned op() { return (m_opcode
>> 14) & 0x3; }
422 unsigned opCode2() { return m_opcode
& 0x1f; }
423 unsigned opNum() { return (m_opcode
>> 3) & 0x3; }
426 class A64DOpcodeFloatingPointDataProcessing1Source
: public A64DOpcodeFloatingPointOps
{
428 static const char* const s_opNames
[16];
431 static const uint32_t mask
= 0x5f207c00;
432 static const uint32_t pattern
= 0x1e204000;
434 DEFINE_STATIC_FORMAT(A64DOpcodeFloatingPointDataProcessing1Source
, thisObj
);
436 const char* format();
438 const char* opName() { return s_opNames
[opNum()]; }
440 unsigned opNum() { return (m_opcode
>> 15) & 0x3f; }
443 class A64DOpcodeFloatingPointDataProcessing2Source
: public A64DOpcodeFloatingPointOps
{
445 static const char* const s_opNames
[16];
448 static const uint32_t mask
= 0x5f200800;
449 static const uint32_t pattern
= 0x1e200800;
451 DEFINE_STATIC_FORMAT(A64DOpcodeFloatingPointDataProcessing2Source
, thisObj
);
453 const char* format();
455 const char* opName() { return s_opNames
[opNum()]; }
457 unsigned opNum() { return (m_opcode
>> 12) & 0xf; }
460 class A64DOpcodeFloatingFixedPointConversions
: public A64DOpcodeFloatingPointOps
{
462 static const char* const s_opNames
[4];
465 static const uint32_t mask
= 0x5f200000;
466 static const uint32_t pattern
= 0x1e000000;
468 DEFINE_STATIC_FORMAT(A64DOpcodeFloatingFixedPointConversions
, thisObj
);
470 const char* format();
472 const char* opName() { return s_opNames
[opNum()]; }
473 unsigned rmode() { return (m_opcode
>> 19) & 0x3; }
474 unsigned opcode() { return (m_opcode
>> 16) & 0x7; }
475 unsigned scale() { return (m_opcode
>> 10) & 0x3f; }
476 unsigned opNum() { return (m_opcode
>> 16) & 0x3; }
479 class A64DOpcodeFloatingPointIntegerConversions
: public A64DOpcodeFloatingPointOps
{
481 static const char* const s_opNames
[32];
484 static const uint32_t mask
= 0x5f20fc00;
485 static const uint32_t pattern
= 0x1e200000;
487 DEFINE_STATIC_FORMAT(A64DOpcodeFloatingPointIntegerConversions
, thisObj
);
489 const char* format();
491 const char* opName() { return s_opNames
[opNum()]; }
492 unsigned rmode() { return (m_opcode
>> 19) & 0x3; }
493 unsigned opcode() { return (m_opcode
>> 16) & 0x7; }
494 unsigned opNum() { return (m_opcode
>> 16) & 0x1f; }
497 class A64DOpcodeHint
: public A64DOpcode
{
499 static const char* const s_opNames
[6];
502 static const uint32_t mask
= 0xfffff01f;
503 static const uint32_t pattern
= 0xd503201f;
505 DEFINE_STATIC_FORMAT(A64DOpcodeHint
, thisObj
);
507 const char* format();
509 const char* opName() { return immediate7() <= 5 ? s_opNames
[immediate7()] : "hint"; }
510 unsigned immediate7() { return (m_opcode
>> 5) & 0x7f; }
513 class A64DOpcodeLoadStore
: public A64DOpcode
{
515 static const char* const s_opNames
[32];
520 return s_opNames
[opNumber()];
523 unsigned size() { return (m_opcode
>> 30) & 0x3; }
524 unsigned vBit() { return (m_opcode
>> 26) & 0x1; }
525 unsigned opc() { return (m_opcode
>> 22) & 0x3; }
526 unsigned opNumber() { return (size() <<3 ) | (vBit() << 2) | opc(); }
527 bool is64BitRT() { return ((opNumber() & 0x17) == 0x02) || ((opNumber() & 0x1e) == 0x18); }
530 class A64DOpcodeLoadStoreImmediate
: public A64DOpcodeLoadStore
{
532 static const char* const s_unprivilegedOpNames
[32];
533 static const char* const s_unscaledOpNames
[32];
536 static const uint32_t mask
= 0x3b200000;
537 static const uint32_t pattern
= 0x38000000;
539 DEFINE_STATIC_FORMAT(A64DOpcodeLoadStoreImmediate
, thisObj
);
541 const char* format();
543 const char* unprivilegedOpName()
545 return s_unprivilegedOpNames
[opNumber()];
547 const char* unscaledOpName()
549 return s_unscaledOpNames
[opNumber()];
551 unsigned type() { return (m_opcode
>> 10) & 0x3; }
552 int immediate9() { return (static_cast<int>((m_opcode
>> 12) & 0x1ff) << 23) >> 23; }
555 class A64DOpcodeLoadStoreRegisterOffset
: public A64DOpcodeLoadStore
{
557 static const uint32_t mask
= 0x3b200c00;
558 static const uint32_t pattern
= 0x38200800;
560 DEFINE_STATIC_FORMAT(A64DOpcodeLoadStoreRegisterOffset
, thisObj
);
562 const char* format();
564 unsigned option() { return (m_opcode
>> 13) & 0x7; }
565 int sBit() { return (m_opcode
>> 12) & 0x1; }
568 class A64DOpcodeLoadStoreUnsignedImmediate
: public A64DOpcodeLoadStore
{
570 static const uint32_t mask
= 0x3b000000;
571 static const uint32_t pattern
= 0x39000000;
573 DEFINE_STATIC_FORMAT(A64DOpcodeLoadStoreUnsignedImmediate
, thisObj
);
575 const char* format();
577 unsigned immediate12() { return (m_opcode
>> 10) & 0xfff; }
580 class A64DOpcodeLogical
: public A64DOpcode
{
582 static const char* const s_opNames
[8];
585 const char* opName(unsigned opNumber
)
587 return s_opNames
[opNumber
& 0x7];
590 unsigned opc() { return (m_opcode
>> 29) & 0x3; }
591 unsigned nBit() { return (m_opcode
>> 21) & 0x1; }
594 class A64DOpcodeLogicalImmediate
: public A64DOpcodeLogical
{
596 static const uint32_t mask
= 0x1f800000;
597 static const uint32_t pattern
= 0x12000000;
599 DEFINE_STATIC_FORMAT(A64DOpcodeLogicalImmediate
, thisObj
);
601 const char* format();
603 bool isTst() { return ((opNumber() == 6) && (rd() == 31)); }
604 bool isMov() { return ((opNumber() == 2) && (rn() == 31)); }
605 unsigned opNumber() { return opc() << 1; }
606 unsigned nBit() { return (m_opcode
>> 22) & 0x1; }
607 unsigned immediateR() { return (m_opcode
>> 16) & 0x3f; }
608 unsigned immediateS() { return (m_opcode
>> 10) & 0x3f; }
611 class A64DOpcodeLogicalShiftedRegister
: public A64DOpcodeLogical
{
613 static const uint32_t mask
= 0x1f000000;
614 static const uint32_t pattern
= 0x0a000000;
616 DEFINE_STATIC_FORMAT(A64DOpcodeLogicalShiftedRegister
, thisObj
);
618 const char* format();
620 bool isTst() { return ((opNumber() == 6) && (rd() == 31)); }
621 bool isMov() { return ((opNumber() == 2) && (rn() == 31)); }
622 unsigned opNumber() { return (opc() << 1) | nBit(); }
623 unsigned shift() { return (m_opcode
>> 22) & 0x3; }
624 int immediate6() { return (static_cast<int>((m_opcode
>> 10) & 0x3f) << 26) >> 26; }
627 class A64DOpcodeMoveWide
: public A64DOpcode
{
629 static const char* const s_opNames
[4];
632 static const uint32_t mask
= 0x1f800000;
633 static const uint32_t pattern
= 0x12800000;
635 DEFINE_STATIC_FORMAT(A64DOpcodeMoveWide
, thisObj
);
637 const char* format();
639 const char* opName() { return s_opNames
[opc()]; }
640 unsigned opc() { return (m_opcode
>> 29) & 0x3; }
641 unsigned hw() { return (m_opcode
>> 21) & 0x3; }
642 unsigned immediate16() { return (m_opcode
>> 5) & 0xffff; }
645 class A64DOpcodeTestAndBranchImmediate
: public A64DOpcode
{
647 static const uint32_t mask
= 0x7e000000;
648 static const uint32_t pattern
= 0x36000000;
650 DEFINE_STATIC_FORMAT(A64DOpcodeTestAndBranchImmediate
, thisObj
);
652 const char* format();
654 unsigned bitNumber() { return ((m_opcode
>> 26) & 0x20) | ((m_opcode
>> 19) & 0x1f); }
655 unsigned opBit() { return (m_opcode
>> 24) & 0x1; }
656 int immediate14() { return (static_cast<int>((m_opcode
>> 5) & 0x3fff) << 18) >> 18; }
659 class A64DOpcodeUnconditionalBranchImmediate
: public A64DOpcode
{
661 static const uint32_t mask
= 0x7c000000;
662 static const uint32_t pattern
= 0x14000000;
664 DEFINE_STATIC_FORMAT(A64DOpcodeUnconditionalBranchImmediate
, thisObj
);
666 const char* format();
668 unsigned op() { return (m_opcode
>> 31) & 0x1; }
669 int immediate26() { return (static_cast<int>(m_opcode
& 0x3ffffff) << 6) >> 6; }
672 class A64DOpcodeUnconditionalBranchRegister
: public A64DOpcode
{
674 static const char* const s_opNames
[8];
677 static const uint32_t mask
= 0xfe1ffc1f;
678 static const uint32_t pattern
= 0xd61f0000;
680 DEFINE_STATIC_FORMAT(A64DOpcodeUnconditionalBranchRegister
, thisObj
);
682 const char* format();
684 const char* opName() { return s_opNames
[opc()]; }
685 unsigned opc() { return (m_opcode
>> 21) & 0xf; }
688 } } // namespace JSC::ARM64Disassembler
690 using JSC::ARM64Disassembler::A64DOpcode
;
692 #endif // A64DOpcode_h