VirtualBox

source: vbox/trunk/src/VBox/Disassembler/DisasmTables-armv8-a64.cpp@ 106004

Last change on this file since 106004 was 106004, checked in by vboxsync, 3 months ago

Disassembler/ArmV8: Updates and start on floating point and SIMD instructions, bugref:10394

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.7 KB
Line 
1/* $Id: DisasmTables-armv8-a64.cpp 106004 2024-09-10 11:51:08Z vboxsync $ */
2/** @file
3 * VBox disassembler - Tables for ARMv8 A64.
4 */
5
6/*
7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <VBox/dis.h>
33#include <VBox/disopcode-armv8.h>
34#include "DisasmInternal-armv8.h"
35
36
37/*********************************************************************************************************************************
38* Global Variables *
39*********************************************************************************************************************************/
40
41#define DIS_ARMV8_OP(a_fValue, a_szOpcode, a_uOpcode, a_fOpType) \
42 { a_fValue, 0, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
43#define DIS_ARMV8_OP_EX(a_fValue, a_szOpcode, a_uOpcode, a_fOpType, a_fFlags) \
44 { a_fValue, a_fFlags, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
45
46#ifndef DIS_CORE_ONLY
47static char g_szInvalidOpcode[] = "Invalid Opcode";
48#endif
49
50#define INVALID_OPCODE \
51 DIS_ARMV8_OP(0, g_szInvalidOpcode, OP_ARMV8_INVALID, DISOPTYPE_INVALID)
52
53
54/* Invalid opcode */
55DECL_HIDDEN_CONST(DISOPCODE) g_ArmV8A64InvalidOpcode[1] =
56{
57 OP(g_szInvalidOpcode, 0, 0, 0, 0, 0, 0, 0, DISOPTYPE_INVALID)
58};
59
60
61/* Include the secondary tables. */
62#include "DisasmTables-armv8-a64-simd-fp.cpp.h"
63
64/* UDF */
65DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Rsvd)
66 DIS_ARMV8_OP(0x00000000, "udf" , OP_ARMV8_A64_UDF, DISOPTYPE_INVALID)
67DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Rsvd)
68 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 0, 16, 0 /*idxParam*/),
69DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(Rsvd, 0xffff0000 /*fFixedInsn*/, 0 /*fClass*/,
70 kDisArmV8OpcDecodeNop, 0xffff0000, 16,
71 kDisArmv8OpParmImm);
72
73/* ADR/ADRP */
74DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Adr)
75 DIS_ARMV8_OP(0x10000000, "adr" , OP_ARMV8_A64_ADR, DISOPTYPE_HARMLESS),
76 DIS_ARMV8_OP(0x90000000, "adrp" , OP_ARMV8_A64_ADRP, DISOPTYPE_HARMLESS)
77DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Adr)
78 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
79 DIS_ARMV8_INSN_DECODE(kDisParmParseImmAdr, 0, 0, 1 /*idxParam*/),
80DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(Adr, 0x9f000000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
81 kDisArmV8OpcDecodeNop, RT_BIT_32(31), 31,
82 kDisArmv8OpParmReg, kDisArmv8OpParmImmRel);
83
84
85/* ADD/ADDS/SUB/SUBS - shifted immediate variant */
86DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(AddSubImm)
87 DIS_ARMV8_OP(0x11000000, "add" , OP_ARMV8_A64_ADD, DISOPTYPE_HARMLESS),
88 DIS_ARMV8_OP(0x31000000, "adds" , OP_ARMV8_A64_ADDS, DISOPTYPE_HARMLESS),
89 DIS_ARMV8_OP(0x51000000, "sub" , OP_ARMV8_A64_SUB, DISOPTYPE_HARMLESS),
90 DIS_ARMV8_OP(0x71000000, "subs" , OP_ARMV8_A64_SUBS, DISOPTYPE_HARMLESS),
91DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(AddSubImm)
92 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
93 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
94 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 10, 12, 2 /*idxParam*/),
95 DIS_ARMV8_INSN_DECODE(kDisParmParseSh12, 22, 1, 2 /*idxParam*/),
96DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(AddSubImm, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
97 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
98 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm);
99
100
101/* ADD/ADDS/SUB/SUBS - shifted register variant */
102DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(AddSubShiftReg)
103 DIS_ARMV8_OP(0x0b000000, "add" , OP_ARMV8_A64_ADD, DISOPTYPE_HARMLESS),
104 DIS_ARMV8_OP(0x2b000000, "adds" , OP_ARMV8_A64_ADDS, DISOPTYPE_HARMLESS),
105 DIS_ARMV8_OP(0x4b000000, "sub" , OP_ARMV8_A64_SUB, DISOPTYPE_HARMLESS),
106 DIS_ARMV8_OP(0x6b000000, "subs" , OP_ARMV8_A64_SUBS, DISOPTYPE_HARMLESS),
107DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(AddSubShiftReg)
108 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
109 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
110 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 16, 5, 2 /*idxParam*/),
111 DIS_ARMV8_INSN_DECODE(kDisParmParseShift, 22, 2, 2 /*idxParam*/),
112 DIS_ARMV8_INSN_DECODE(kDisParmParseShiftAmount, 10, 6, 2 /*idxParam*/),
113DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(AddSubShiftReg, 0x7f200000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
114 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
115 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmReg);
116
117
118/* AND/ORR/EOR/ANDS */
119DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LogicalImm)
120 DIS_ARMV8_OP(0x12000000, "and" , OP_ARMV8_A64_AND, DISOPTYPE_HARMLESS),
121 DIS_ARMV8_OP(0x32000000, "orr" , OP_ARMV8_A64_ORR, DISOPTYPE_HARMLESS),
122 DIS_ARMV8_OP(0x52000000, "eor" , OP_ARMV8_A64_EOR, DISOPTYPE_HARMLESS),
123 DIS_ARMV8_OP(0x72000000, "ands" , OP_ARMV8_A64_ANDS, DISOPTYPE_HARMLESS),
124DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LogicalImm)
125 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
126 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
127 DIS_ARMV8_INSN_DECODE(kDisParmParseImmsImmrN, 10, 13, 2 /*idxParam*/),
128DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LogicalImm, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
129 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
130 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm);
131
132
133/* MOVN/MOVZ/MOVK */
134DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(MoveWide)
135 DIS_ARMV8_OP(0x12800000, "movn", OP_ARMV8_A64_MOVN, DISOPTYPE_HARMLESS),
136 INVALID_OPCODE,
137 DIS_ARMV8_OP(0x52800000, "movz" , OP_ARMV8_A64_MOVZ, DISOPTYPE_HARMLESS),
138 DIS_ARMV8_OP(0x72800000, "movk" , OP_ARMV8_A64_MOVK, DISOPTYPE_HARMLESS),
139DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(MoveWide)
140 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
141 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 5, 16, 1 /*idxParam*/),
142 DIS_ARMV8_INSN_DECODE(kDisParmParseHw, 21, 2, 1 /*idxParam*/),
143DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(MoveWide, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
144 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
145 kDisArmv8OpParmReg, kDisArmv8OpParmImm);
146
147
148/* SBFM/BFM/UBFM */
149DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Bitfield)
150 DIS_ARMV8_OP(0x13000000, "sbfm", OP_ARMV8_A64_SBFM, DISOPTYPE_HARMLESS),
151 DIS_ARMV8_OP(0x33000000, "bfm", OP_ARMV8_A64_BFM, DISOPTYPE_HARMLESS),
152 DIS_ARMV8_OP(0x53000000, "ubfm", OP_ARMV8_A64_UBFM, DISOPTYPE_HARMLESS),
153 INVALID_OPCODE,
154DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Bitfield)
155 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
156 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
157 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 16, 6, 2 /*idxParam*/),
158 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 10, 6, 3 /*idxParam*/),
159DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_4(Bitfield, 0x7f800000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF | DISARMV8INSNCLASS_F_N_FORCED_1_ON_64BIT,
160 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
161 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm, kDisArmv8OpParmImm);
162
163
164/*
165 * C4.1.65 of the ARMv8 architecture reference manual has the following table for the
166 * data processing (immediate) instruction classes:
167 *
168 * Bit 25 24 23
169 * +-------------------------------------------
170 * 0 0 x PC-rel. addressing.
171 * 0 1 0 Add/subtract (immediate)
172 * 0 1 1 Add/subtract (immediate, with tags)
173 * 1 0 0 Logical (immediate)
174 * 1 0 1 Move wide (immediate)
175 * 1 1 0 Bitfield
176 * 1 1 1 Extract
177 */
178DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(DataProcessingImm)
179 DIS_ARMV8_DECODE_MAP_ENTRY(Adr),
180 DIS_ARMV8_DECODE_MAP_ENTRY(Adr),
181 DIS_ARMV8_DECODE_MAP_ENTRY(AddSubImm),
182 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Add/subtract immediate with tags. */
183 DIS_ARMV8_DECODE_MAP_ENTRY(LogicalImm),
184 DIS_ARMV8_DECODE_MAP_ENTRY(MoveWide),
185 DIS_ARMV8_DECODE_MAP_ENTRY(Bitfield),
186 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY /** @todo Extract */
187DIS_ARMV8_DECODE_MAP_DEFINE_END(DataProcessingImm, RT_BIT_32(23) | RT_BIT_32(24) | RT_BIT_32(25), 23);
188
189
190/* B.cond/BC.cond */
191DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(CondBr)
192 DIS_ARMV8_OP(0x54000000, "b", OP_ARMV8_A64_B, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW | DISOPTYPE_RELATIVE_CONTROLFLOW | DISOPTYPE_COND_CONTROLFLOW),
193 DIS_ARMV8_OP(0x54000010, "bc" , OP_ARMV8_A64_BC, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW | DISOPTYPE_RELATIVE_CONTROLFLOW | DISOPTYPE_COND_CONTROLFLOW),
194DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(CondBr)
195 DIS_ARMV8_INSN_DECODE(kDisParmParseCond, 0, 4, DIS_ARMV8_INSN_PARAM_UNSET),
196 DIS_ARMV8_INSN_DECODE(kDisParmParseImmRel, 5, 19, 0 /*idxParam*/),
197DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(CondBr, 0xff000010 /*fFixedInsn*/, 0 /*fClass*/,
198 kDisArmV8OpcDecodeNop, RT_BIT_32(4), 4,
199 kDisArmv8OpParmImmRel);
200
201
202/* SVC/HVC/SMC/BRK/HLT/TCANCEL/DCPS1/DCPS2/DCPS3 */
203DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Excp)
204 DIS_ARMV8_OP(0xd4000001, "svc", OP_ARMV8_A64_SVC, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
205 DIS_ARMV8_OP(0xd4000002, "hvc", OP_ARMV8_A64_HVC, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT | DISOPTYPE_PRIVILEGED),
206 DIS_ARMV8_OP(0xd4000003, "smc", OP_ARMV8_A64_SMC, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT | DISOPTYPE_PRIVILEGED),
207 DIS_ARMV8_OP(0xd4200000, "brk", OP_ARMV8_A64_BRK, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
208 DIS_ARMV8_OP(0xd4400000, "hlt", OP_ARMV8_A64_HLT, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
209 DIS_ARMV8_OP(0xd4600000, "tcancel", OP_ARMV8_A64_TCANCEL, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT), /* FEAT_TME */
210 DIS_ARMV8_OP(0xd4a00001, "dcps1", OP_ARMV8_A64_DCPS1, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
211 DIS_ARMV8_OP(0xd4a00002, "dcps2", OP_ARMV8_A64_DCPS2, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
212 DIS_ARMV8_OP(0xd4a00003, "dcps3", OP_ARMV8_A64_DCPS3, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
213DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Excp)
214 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 5, 16, 0 /*idxParam*/),
215DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(Excp, 0xffe0001f /*fFixedInsn*/, 0 /*fClass*/,
216 kDisArmV8OpcDecodeLookup, 0xffe0001f, 0,
217 kDisArmv8OpParmImm);
218
219
220/* WFET/WFIT */
221DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(SysReg)
222 DIS_ARMV8_OP(0xd5031000, "wfet", OP_ARMV8_A64_WFET, DISOPTYPE_HARMLESS), /* FEAT_WFxT */
223 DIS_ARMV8_OP(0x54000010, "wfit" , OP_ARMV8_A64_WFIT, DISOPTYPE_HARMLESS), /* FEAT_WFxT */
224DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(SysReg)
225 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
226DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(SysReg, 0xffffffe0 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
227 kDisArmV8OpcDecodeNop, 0xfe0, 5,
228 kDisArmv8OpParmReg);
229
230
231/* Various hint instructions */
232DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Hints)
233 DIS_ARMV8_OP(0xd503201f, "nop", OP_ARMV8_A64_NOP, DISOPTYPE_HARMLESS),
234 DIS_ARMV8_OP(0xd503203f, "yield", OP_ARMV8_A64_YIELD, DISOPTYPE_HARMLESS),
235 DIS_ARMV8_OP(0xd503205f, "wfe", OP_ARMV8_A64_WFE, DISOPTYPE_HARMLESS),
236 DIS_ARMV8_OP(0xd503207f, "wfi", OP_ARMV8_A64_WFI, DISOPTYPE_HARMLESS),
237 DIS_ARMV8_OP(0xd503209f, "sev", OP_ARMV8_A64_SEV, DISOPTYPE_HARMLESS),
238 DIS_ARMV8_OP(0xd50320bf, "sevl", OP_ARMV8_A64_SEVL, DISOPTYPE_HARMLESS),
239 DIS_ARMV8_OP(0xd50320df, "dgh", OP_ARMV8_A64_DGH, DISOPTYPE_HARMLESS), /* FEAT_DGH */
240 DIS_ARMV8_OP(0xd50320ff, "xpaclri", OP_ARMV8_A64_XPACLRI, DISOPTYPE_HARMLESS), /* FEAT_PAuth */
241 /** @todo */
242DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Hints)
243DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_0(Hints, 0xffffffff /*fFixedInsn*/, 0 /*fClass*/,
244 kDisArmV8OpcDecodeNop, 0xfe0, 5);
245
246
247/* CLREX */
248DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(DecBarriers)
249 DIS_ARMV8_OP(0xd503304f, "clrex", OP_ARMV8_A64_CLREX, DISOPTYPE_HARMLESS),
250 DIS_ARMV8_OP(0xd50330bf, "dmb", OP_ARMV8_A64_DMB, DISOPTYPE_HARMLESS),
251DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(DecBarriers)
252 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 8, 4, 0 /*idxParam*/),
253DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(DecBarriers, 0xfffff0ff /*fFixedInsn*/, 0 /*fClass*/,
254 kDisArmV8OpcDecodeNop, RT_BIT_32(5), 5,
255 kDisArmv8OpParmImm);
256
257
258/* Barrier instructions, we divide these instructions further based on the op2 field. */
259DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(DecodeBarriers)
260 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
261 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo DSB - Encoding */
262 DIS_ARMV8_DECODE_MAP_ENTRY(DecBarriers), /* CLREX */
263 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo TCOMMIT */
264 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo DSB - Encoding */
265 DIS_ARMV8_DECODE_MAP_ENTRY(DecBarriers), /* DMB */
266 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo ISB */
267 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY /** @todo SB */
268DIS_ARMV8_DECODE_MAP_DEFINE_END(DecodeBarriers, RT_BIT_32(5) | RT_BIT_32(6) | RT_BIT_32(7), 5);
269
270
271/* MSR (and potentially CFINV,XAFLAG,AXFLAG) */
272DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(PState)
273 DIS_ARMV8_OP(0xd500401f, "msr", OP_ARMV8_A64_MSR, DISOPTYPE_HARMLESS),
274DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(PState)
275 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 8, 4, 1 /*idxParam*/), /* CRm field encodes the immediate value, gets validated by the next decoder stage. */
276 DIS_ARMV8_INSN_DECODE(kDisParmParsePState, 0, 0, 0 /*idxParam*/), /* This is special for the MSR instruction. */
277DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(PState, 0xfff8f01f /*fFixedInsn*/, 0 /*fClass*/,
278 kDisArmV8OpcDecodeNop, 0, 0,
279 kDisArmv8OpParmPState, kDisArmv8OpParmImm);
280
281
282/* TSTART/TTEST */
283DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(SysResult)
284 DIS_ARMV8_OP(0xd5233060, "tstart", OP_ARMV8_A64_TSTART, DISOPTYPE_HARMLESS | DISOPTYPE_PRIVILEGED), /* FEAT_TME */
285 DIS_ARMV8_OP(0xd5233160, "ttest", OP_ARMV8_A64_TTEST, DISOPTYPE_HARMLESS), /* FEAT_TME */
286DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(SysResult)
287 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
288DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(SysResult, 0xfffffffe /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
289 kDisArmV8OpcDecodeNop, RT_BIT_32(8) | RT_BIT_32(9) | RT_BIT_32(10) | RT_BIT_32(11), 8,
290 kDisArmv8OpParmReg);
291
292
293/* SYS */
294DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Sys)
295 DIS_ARMV8_OP(0xd5080000, "sys", OP_ARMV8_A64_SYS, DISOPTYPE_HARMLESS),
296DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Sys)
297 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 16, 3, 0 /*idxParam*/),
298 DIS_ARMV8_INSN_DECODE(kDisParmParseCRnCRm, 8, 8, 1 /*idxParam*/),
299 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 5, 3, 2 /*idxParam*/),
300 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 3 /*idxParam*/),
301DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_0(Sys, 0xfff80000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
302 kDisArmV8OpcDecodeNop, 0, 0); /** @todo */
303
304
305/* SYSL */
306DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(SysL)
307 DIS_ARMV8_OP(0xd5280000, "sysl", OP_ARMV8_A64_SYSL, DISOPTYPE_HARMLESS),
308DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(SysL)
309 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
310 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 16, 3, 1 /*idxParam*/),
311 DIS_ARMV8_INSN_DECODE(kDisParmParseCRnCRm, 8, 8, 2 /*idxParam*/),
312 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 5, 3, 3 /*idxParam*/),
313DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_0(SysL, 0xfff80000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
314 kDisArmV8OpcDecodeNop, 0, 0); /** @todo */
315
316
317/* MSR */
318DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Msr)
319 DIS_ARMV8_OP(0xd5100000, "msr", OP_ARMV8_A64_MSR, DISOPTYPE_HARMLESS | DISOPTYPE_PRIVILEGED),
320DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Msr)
321 DIS_ARMV8_INSN_DECODE(kDisParmParseSysReg, 5, 15, 0 /*idxParam*/),
322 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 1 /*idxParam*/),
323DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(Msr, 0xfff00000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
324 kDisArmV8OpcDecodeNop, 0, 0,
325 kDisArmv8OpParmSysReg, kDisArmv8OpParmReg);
326
327
328/* MRS */
329DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(Mrs)
330 DIS_ARMV8_OP(0xd5300000, "mrs", OP_ARMV8_A64_MRS, DISOPTYPE_HARMLESS | DISOPTYPE_PRIVILEGED),
331DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(Mrs)
332 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
333 DIS_ARMV8_INSN_DECODE(kDisParmParseSysReg, 5, 15, 1 /*idxParam*/),
334DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(Mrs, 0xfff00000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
335 kDisArmV8OpcDecodeNop, 0, 0,
336 kDisArmv8OpParmReg, kDisArmv8OpParmSysReg);
337
338
339/* BR/BRAA/BRAAZ/BRAB/BRABZ/BLR/BLRAA/BLRAAZ/BLRAB/BLRABZ/RET/RETAA/RETAB */
340DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(BrBlrRet)
341 DIS_ARMV8_OP(0xd61f0000, "br", OP_ARMV8_A64_BR, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
342 DIS_ARMV8_OP(0xd63f0000, "blr", OP_ARMV8_A64_BLR, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
343 /** @todo All the FEAT_PAuth related branch instructions. */
344 DIS_ARMV8_OP(0xd65f0000, "ret", OP_ARMV8_A64_RET, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
345 DIS_ARMV8_OP(0xd65f0800, "retaa", OP_ARMV8_A64_RETAA, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
346 DIS_ARMV8_OP(0xd65f0c00, "retab", OP_ARMV8_A64_RETAB, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
347DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(BrBlrRet)
348 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 0 /*idxParam*/),
349DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(BrBlrRet, 0xfffffc1f /*fFixedInsn*/, DISARMV8INSNCLASS_F_FORCED_64BIT,
350 kDisArmV8OpcDecodeLookup, 0xfffffc1f, 0,
351 kDisArmv8OpParmReg);
352
353
354/* Unconditional branch (register) instructions, we divide these instructions further based on the opc field. */
355DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(UncondBrReg)
356 DIS_ARMV8_DECODE_MAP_ENTRY(BrBlrRet), /* BR/BRAA/BRAAZ/BRAB/BRABZ */
357 DIS_ARMV8_DECODE_MAP_ENTRY(BrBlrRet), /* BLR/BLRAA/BLRAAZ/BLRAB/BLRABZ */
358 DIS_ARMV8_DECODE_MAP_ENTRY(BrBlrRet), /* RET/RETAA/RETAB */
359 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
360 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
361 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
362 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
363 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
364 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
365 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
366 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
367 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
368 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
369 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
370 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
371 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY
372DIS_ARMV8_DECODE_MAP_DEFINE_END(UncondBrReg, RT_BIT_32(21) | RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(24), 21);
373
374
375/* B/BL */
376DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(UncondBrImm)
377 DIS_ARMV8_OP(0x14000000, "b", OP_ARMV8_A64_B, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
378 DIS_ARMV8_OP(0x94000000, "bl", OP_ARMV8_A64_BL, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
379DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(UncondBrImm)
380 DIS_ARMV8_INSN_DECODE(kDisParmParseImmRel, 0, 26, 0 /*idxParam*/),
381DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_1(UncondBrImm, 0xfc000000 /*fFixedInsn*/, 0 /*fClass*/,
382 kDisArmV8OpcDecodeNop, RT_BIT_32(31), 31,
383 kDisArmv8OpParmImmRel);
384
385
386/* CBZ/CBNZ */
387DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(CmpBrImm)
388 DIS_ARMV8_OP(0x34000000, "cbz", OP_ARMV8_A64_CBZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
389 DIS_ARMV8_OP(0x35000000, "cbnz", OP_ARMV8_A64_CBNZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
390DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(CmpBrImm)
391 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
392 DIS_ARMV8_INSN_DECODE(kDisParmParseImmRel, 5, 19, 1 /*idxParam*/),
393DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(CmpBrImm, 0x7f000000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
394 kDisArmV8OpcDecodeNop, RT_BIT_32(24), 24,
395 kDisArmv8OpParmReg, kDisArmv8OpParmImmRel);
396
397
398/* TBZ/TBNZ */
399DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(TestBrImm)
400 DIS_ARMV8_OP(0x36000000, "tbz", OP_ARMV8_A64_TBZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
401 DIS_ARMV8_OP(0x37000000, "tbnz", OP_ARMV8_A64_TBNZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
402DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(TestBrImm)
403 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
404 DIS_ARMV8_INSN_DECODE(kDisParmParseImmTbz, 0, 0, 1 /*idxParam*/), /* Hardcoded bit offsets in parser. */
405 DIS_ARMV8_INSN_DECODE(kDisParmParseImmRel, 5, 14, 2 /*idxParam*/),
406DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(TestBrImm, 0x7f000000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF, /* Not an SF bit but has the same meaning. */
407 kDisArmV8OpcDecodeNop, RT_BIT_32(24), 24,
408 kDisArmv8OpParmReg, kDisArmv8OpParmImm, kDisArmv8OpParmImmRel);
409
410
411DIS_ARMV8_DECODE_TBL_DEFINE_BEGIN(BrExcpSys)
412 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfe000000, RT_BIT_32(26) | RT_BIT_32(28) | RT_BIT_32(30), CondBr), /* op0: 010, op1: 0xxxxxxxxxxxxx, op2: - (including o1 from the conditional branch (immediate) class to save us one layer). */
413 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xff000000, RT_BIT_32(26) | RT_BIT_32(28) | RT_BIT_32(30) | RT_BIT_32(31), Excp), /* op0: 110, op1: 00xxxxxxxxxxxx, op2: -. */
414 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff000, 0xd5031000, SysReg), /* op0: 110, op1: 01000000110001, op2: -. */
415 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff01f, 0xd503201f, Hints), /* op0: 110, op1: 01000000110010, op2: 11111. */
416 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff01f, 0xd503301f, DecodeBarriers), /* op0: 110, op1: 01000000110011, op2: - (we include Rt: 11111 from the next stage here). */
417 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff8f01f, 0xd500401f, PState), /* op0: 110, op1: 0100000xxx0100, op2: - (we include Rt: 11111 from the next stage here). */
418 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff0e0, 0xd5233060, SysResult), /* op0: 110, op1: 0100100xxxxxxx, op2: - (we include op1, CRn and op2 from the next stage here). */
419 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff80000, 0xd5080000, Sys), /* op0: 110, op1: 0100x01xxxxxxx, op2: - (we include the L field of the next stage here to differentiate between SYS/SYSL as they have a different string representation). */
420 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff80000, 0xd5280000, SysL), /* op0: 110, op1: 0100x01xxxxxxx, op2: - (we include the L field of the next stage here to differentiate between SYS/SYSL as they have a different string representation). */
421 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff00000, 0xd5100000, Msr), /* op0: 110, op1: 0100x1xxxxxxxx, op2: - (we include the L field of the next stage here to differentiate between MSR/MRS as they have a different string representation). */
422 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff00000, 0xd5300000, Mrs), /* op0: 110, op1: 0100x1xxxxxxxx, op2: - (we include the L field of the next stage here to differentiate between MSR/MRS as they have a different string representation). */
423 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfe1f0000, 0xd61f0000, UncondBrReg), /* op0: 110, op1: 1xxxxxxxxxxxxx, op2: - (we include the op2 field from the next stage here as it should be always 11111). */
424 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0x7c000000, 0x14000000, UncondBrImm), /* op0: x00, op1: xxxxxxxxxxxxxx, op2: -. */
425 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0x7e000000, 0x34000000, CmpBrImm), /* op0: x01, op1: 0xxxxxxxxxxxxx, op2: -. */
426 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0x7e000000, 0x36000000, TestBrImm), /* op0: x01, op1: 1xxxxxxxxxxxxx, op2: -. */
427DIS_ARMV8_DECODE_TBL_DEFINE_END(BrExcpSys);
428
429
430/* AND/ORR/EOR/ANDS */
431DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LogShiftRegN0)
432 DIS_ARMV8_OP(0x0a000000, "and", OP_ARMV8_A64_AND, DISOPTYPE_HARMLESS),
433 DIS_ARMV8_OP(0x2a000000, "orr", OP_ARMV8_A64_ORR, DISOPTYPE_HARMLESS),
434 DIS_ARMV8_OP(0x4a000000, "eor", OP_ARMV8_A64_EOR, DISOPTYPE_HARMLESS),
435 DIS_ARMV8_OP(0x6a000000, "ands", OP_ARMV8_A64_ANDS, DISOPTYPE_HARMLESS)
436DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LogShiftRegN0)
437 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
438 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
439 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 16, 5, 2 /*idxParam*/),
440 DIS_ARMV8_INSN_DECODE(kDisParmParseShift, 22, 2, 2 /*idxParam*/),
441 DIS_ARMV8_INSN_DECODE(kDisParmParseShiftAmount, 10, 6, 2 /*idxParam*/),
442DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LogShiftRegN0, 0x7f200000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
443 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
444 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmReg);
445
446
447/* AND/ORR/EOR/ANDS */
448DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LogShiftRegN1)
449 DIS_ARMV8_OP(0x0a200000, "bic", OP_ARMV8_A64_BIC, DISOPTYPE_HARMLESS),
450 DIS_ARMV8_OP(0x2a200000, "orn", OP_ARMV8_A64_ORN, DISOPTYPE_HARMLESS),
451 DIS_ARMV8_OP(0x4a200000, "eon", OP_ARMV8_A64_EON, DISOPTYPE_HARMLESS),
452 DIS_ARMV8_OP(0x6a200000, "bics", OP_ARMV8_A64_BICS, DISOPTYPE_HARMLESS)
453DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LogShiftRegN1)
454 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
455 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
456 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 16, 5, 2 /*idxParam*/),
457 DIS_ARMV8_INSN_DECODE(kDisParmParseShift, 22, 2, 2 /*idxParam*/),
458 DIS_ARMV8_INSN_DECODE(kDisParmParseShiftAmount, 10, 6, 2 /*idxParam*/),
459DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LogShiftRegN1, 0x7f200000 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
460 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
461 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmReg);
462
463
464DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LogShiftRegN)
465 DIS_ARMV8_DECODE_MAP_ENTRY(LogShiftRegN0), /* Logical (shifted register) - N = 0 */
466 DIS_ARMV8_DECODE_MAP_ENTRY(LogShiftRegN1), /* Logical (shifted register) - N = 1 */
467DIS_ARMV8_DECODE_MAP_DEFINE_END(LogShiftRegN, RT_BIT_32(21), 21);
468
469
470DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(AddSubExtReg)
471 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
472DIS_ARMV8_DECODE_MAP_DEFINE_END(AddSubExtReg, RT_BIT_32(24), 24);
473
474
475DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(AddSubShiftExtReg)
476 DIS_ARMV8_DECODE_MAP_ENTRY(AddSubShiftReg), /* Add/Subtract (shifted register) */
477 DIS_ARMV8_DECODE_MAP_ENTRY(AddSubExtReg), /* Add/Subtract (extended register) */
478DIS_ARMV8_DECODE_MAP_DEFINE_END(AddSubShiftExtReg, RT_BIT_32(21), 21);
479
480
481DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LogicalAddSubReg)
482 DIS_ARMV8_DECODE_MAP_ENTRY(LogShiftRegN), /* Logical (shifted register) */
483 DIS_ARMV8_DECODE_MAP_ENTRY(AddSubShiftExtReg), /* Add/subtract (shifted/extended register) */
484DIS_ARMV8_DECODE_MAP_DEFINE_END(LogicalAddSubReg, RT_BIT_32(24), 24);
485
486
487/* CCMN/CCMP */
488DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(CondCmpReg)
489 DIS_ARMV8_OP(0x3a400000, "ccmn", OP_ARMV8_A64_CCMN, DISOPTYPE_HARMLESS),
490 DIS_ARMV8_OP(0x7a400000, "ccmp", OP_ARMV8_A64_CCMP, DISOPTYPE_HARMLESS)
491DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(CondCmpReg)
492 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 0 /*idxParam*/),
493 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 16, 5, 1 /*idxParam*/),
494 DIS_ARMV8_INSN_DECODE(kDisParmParseImm, 0, 4, 2 /*idxParam*/),
495 DIS_ARMV8_INSN_DECODE(kDisParmParseCond, 12, 4, 3 /*idxParam*/),
496DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_4(CondCmpReg, 0x7fe00c10 /*fFixedInsn*/, DISARMV8INSNCLASS_F_SF,
497 kDisArmV8OpcDecodeNop, RT_BIT_32(30), 30,
498 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmImm, kDisArmv8OpParmCond);
499
500
501/**
502 * C4.1.95 - Data Processing - Register
503 *
504 * The conditional compare instructions differentiate between register and immediate
505 * variant based on the 11th bit (part of op3).
506 */
507DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(CondCmp)
508 DIS_ARMV8_DECODE_MAP_ENTRY(CondCmpReg), /* Conditional compare register */
509 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Conditional compare immediate */
510DIS_ARMV8_DECODE_MAP_DEFINE_END(CondCmp, RT_BIT_32(11), 11);
511
512
513/*
514 * C4.1.95 - Data Processing - Register
515 *
516 * The op1 field is already decoded in the previous step and is 1 when being here,
517 * leaving us with the following possible values:
518 *
519 * Bit 24 23 22 21
520 * +-------------------------------------------
521 * 0 0 0 0 Add/subtract with carry / Rotate right into flags / Evaluate into flags (depending on op3)
522 * 0 0 0 1 UNALLOC
523 * 0 0 1 0 Conditional compare (register / immediate)
524 * 0 0 1 1 UNALLOC
525 * 0 1 0 0 Conditional select
526 * 0 1 0 1 UNALLOC
527 * 0 1 1 0 Data processing (2-source or 1-source depending on op0).
528 * 0 1 1 1 UNALLOC
529 * 1 x x x Data processing 3-source
530 */
531DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(DataProcReg)
532 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Add/subtract with carry. */
533 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
534 DIS_ARMV8_DECODE_MAP_ENTRY(CondCmp), /** @todo Conditional compare. */
535 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
536 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Conditional select. */
537 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
538 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 2-source/1-source. */
539 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
540 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
541 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
542 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
543 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
544 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
545 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
546 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
547 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Data Processing 3-source. */
548DIS_ARMV8_DECODE_MAP_DEFINE_END(DataProcReg, RT_BIT_32(21) | RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(24), 21);
549
550
551/* STRB/LDRB/LDRSB/STR/LDR/STRH/LDRH/LDRSH/LDRSW/PRFM
552 *
553 * Note: The size,opc bitfields are concatenated to form an index.
554 */
555DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegUImmGpr)
556 DIS_ARMV8_OP(0x39000000, "strb", OP_ARMV8_A64_STRB, DISOPTYPE_HARMLESS),
557 DIS_ARMV8_OP(0x39400000, "ldrb", OP_ARMV8_A64_LDRB, DISOPTYPE_HARMLESS),
558 DIS_ARMV8_OP_EX(0x39800000, "ldrsb", OP_ARMV8_A64_LDRSB, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
559 DIS_ARMV8_OP(0x39c00000, "ldrsb", OP_ARMV8_A64_LDRSB, DISOPTYPE_HARMLESS),
560 DIS_ARMV8_OP(0x79000000, "strh", OP_ARMV8_A64_STRH, DISOPTYPE_HARMLESS),
561 DIS_ARMV8_OP(0x79400000, "ldrh", OP_ARMV8_A64_LDRH, DISOPTYPE_HARMLESS),
562 DIS_ARMV8_OP_EX(0x79800000, "ldrsh", OP_ARMV8_A64_LDRSH, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
563 DIS_ARMV8_OP(0x79c00000, "ldrsh", OP_ARMV8_A64_LDRSH, DISOPTYPE_HARMLESS),
564 DIS_ARMV8_OP(0xb9000000, "str", OP_ARMV8_A64_STR, DISOPTYPE_HARMLESS),
565 DIS_ARMV8_OP(0xb9400000, "ldr", OP_ARMV8_A64_LDR, DISOPTYPE_HARMLESS),
566 DIS_ARMV8_OP_EX(0xb9800000, "ldrsw", OP_ARMV8_A64_LDRSW, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
567 INVALID_OPCODE,
568 DIS_ARMV8_OP(0xf9000000, "str", OP_ARMV8_A64_STR, DISOPTYPE_HARMLESS),
569 DIS_ARMV8_OP(0xf9400000, "ldr", OP_ARMV8_A64_LDR, DISOPTYPE_HARMLESS),
570 INVALID_OPCODE, /** @todo PRFM */
571 INVALID_OPCODE,
572DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegUImmGpr)
573 DIS_ARMV8_INSN_DECODE(kDisParmParseSize, 30, 2, DIS_ARMV8_INSN_PARAM_UNSET),
574 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
575 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
576 DIS_ARMV8_INSN_DECODE(kDisParmParseImmMemOff, 10, 12, 1 /*idxParam*/),
577DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdStRegUImmGpr, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
578 kDisArmV8OpcDecodeCollate,
579 RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
580 kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
581
582
583/*
584 * C4.1.94 - Loads and Stores - Load/Store register variants
585 *
586 * Differentiate further based on the VR field.
587 *
588 * Bit 26
589 * +-------------------------------------------
590 * 0 GPR variants.
591 * 1 SIMD/FP variants
592 */
593DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegUImm)
594 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImmGpr),
595 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
596DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegUImm, RT_BIT_32(26), 26);
597
598
599/*
600 * STRB/LDRB/LDRSB/STR/LDR/STRH/LDRH/LDRSH/LDRSW/PRFM
601 *
602 * Note: The size,opc bitfields are concatenated to form an index.
603 */
604DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegOffGpr)
605 DIS_ARMV8_OP(0x38200800, "strb", OP_ARMV8_A64_STRB, DISOPTYPE_HARMLESS),
606 DIS_ARMV8_OP(0x38600800, "ldrb", OP_ARMV8_A64_LDRB, DISOPTYPE_HARMLESS),
607 DIS_ARMV8_OP_EX(0x38a00800, "ldrsb", OP_ARMV8_A64_LDRSB, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
608 DIS_ARMV8_OP(0x38e00800, "ldrsb", OP_ARMV8_A64_LDRSB, DISOPTYPE_HARMLESS),
609 DIS_ARMV8_OP(0x78200800, "strh", OP_ARMV8_A64_STRH, DISOPTYPE_HARMLESS),
610 DIS_ARMV8_OP(0x78600800, "ldrh", OP_ARMV8_A64_LDRH, DISOPTYPE_HARMLESS),
611 DIS_ARMV8_OP_EX(0x78a00800, "ldrsh", OP_ARMV8_A64_LDRSH, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
612 DIS_ARMV8_OP(0x78e00800, "ldrsh", OP_ARMV8_A64_LDRSH, DISOPTYPE_HARMLESS),
613 DIS_ARMV8_OP(0xb8200800, "str", OP_ARMV8_A64_STR, DISOPTYPE_HARMLESS),
614 DIS_ARMV8_OP(0xb8600800, "ldr", OP_ARMV8_A64_LDR, DISOPTYPE_HARMLESS),
615 DIS_ARMV8_OP_EX(0xb8a00800, "ldrsw", OP_ARMV8_A64_LDRSW, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
616 INVALID_OPCODE,
617 DIS_ARMV8_OP(0xf8200800, "str", OP_ARMV8_A64_STR, DISOPTYPE_HARMLESS),
618 DIS_ARMV8_OP(0xf8600800, "ldr", OP_ARMV8_A64_LDR, DISOPTYPE_HARMLESS),
619 INVALID_OPCODE, /** @todo PRFM */
620 INVALID_OPCODE,
621DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegOffGpr)
622 DIS_ARMV8_INSN_DECODE(kDisParmParseSize, 30, 2, DIS_ARMV8_INSN_PARAM_UNSET),
623 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
624 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
625 DIS_ARMV8_INSN_DECODE(kDisParmParseRegOff, 16, 5, 1 /*idxParam*/),
626 DIS_ARMV8_INSN_DECODE(kDisParmParseOption, 13, 3, 1 /*idxParam*/),
627 DIS_ARMV8_INSN_DECODE(kDisParmParseS, 12, 1, 1 /*idxParam*/),
628DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdStRegOffGpr, 0xffe00c00 /*fFixedInsn*/, 0 /*fClass*/,
629 kDisArmV8OpcDecodeCollate,
630 RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
631 kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
632
633
634/*
635 * C4.1.94 - Loads and Stores - Load/Store register (register offset) variants
636 *
637 * Differentiate further based on the VR field.
638 *
639 * Bit 26
640 * +-------------------------------------------
641 * 0 GPR variants.
642 * 1 SIMD/FP variants
643 */
644DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOff)
645 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOffGpr),
646 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
647DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOff, RT_BIT_32(26), 26);
648
649
650/*
651 * C4.1.94 - Loads and Stores - Load/Store register variants
652 *
653 * Differentiate further based on the op2<1:0> field.
654 *
655 * Bit 11 10
656 * +-------------------------------------------
657 * 0 0 Atomic memory operations
658 * 0 1 Load/store register (pac)
659 * 1 0 Load/store register (register offset)
660 * 1 1 Load/store register (pac)
661 */
662DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp2_11_1)
663 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
664 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
665 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOff),
666 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
667DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp2_11_1, RT_BIT_32(10) | RT_BIT_32(11), 10);
668
669
670/*
671 * STURB/LDURB/LDURSB/STURH/LDURH/LDURSH/STUR/LDUR/LDURSW/PRFUM
672 *
673 * Note: The size,opc bitfields are concatenated to form an index.
674 */
675DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegUnscaledImmGpr)
676 DIS_ARMV8_OP(0x38000000, "sturb", OP_ARMV8_A64_STURB, DISOPTYPE_HARMLESS),
677 DIS_ARMV8_OP(0x38400000, "ldurb", OP_ARMV8_A64_LDURB, DISOPTYPE_HARMLESS),
678 DIS_ARMV8_OP_EX(0x38800000, "ldursb", OP_ARMV8_A64_LDURSB, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
679 DIS_ARMV8_OP(0x38c00000, "ldursb", OP_ARMV8_A64_LDURSB, DISOPTYPE_HARMLESS),
680 DIS_ARMV8_OP(0x78000000, "sturh", OP_ARMV8_A64_STURH, DISOPTYPE_HARMLESS),
681 DIS_ARMV8_OP(0x78400000, "ldurh", OP_ARMV8_A64_LDURH, DISOPTYPE_HARMLESS),
682 DIS_ARMV8_OP_EX(0x78800000, "ldursh", OP_ARMV8_A64_LDURSH, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
683 DIS_ARMV8_OP(0x78c00000, "ldursh", OP_ARMV8_A64_LDURSH, DISOPTYPE_HARMLESS),
684 DIS_ARMV8_OP(0xb8000000, "stur", OP_ARMV8_A64_STUR, DISOPTYPE_HARMLESS),
685 DIS_ARMV8_OP(0xb8400000, "ldur", OP_ARMV8_A64_LDUR, DISOPTYPE_HARMLESS),
686 DIS_ARMV8_OP_EX(0xb8800000, "ldursw", OP_ARMV8_A64_LDURSW, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
687 INVALID_OPCODE,
688 DIS_ARMV8_OP(0xf8000000, "stur", OP_ARMV8_A64_STUR, DISOPTYPE_HARMLESS),
689 DIS_ARMV8_OP(0xf8400000, "ldur", OP_ARMV8_A64_LDUR, DISOPTYPE_HARMLESS),
690 INVALID_OPCODE, /** @todo PRFUM */
691 INVALID_OPCODE,
692DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegUnscaledImmGpr)
693 DIS_ARMV8_INSN_DECODE(kDisParmParseSize, 30, 2, DIS_ARMV8_INSN_PARAM_UNSET),
694 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
695 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
696 DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOffUnscaled, 12, 9, 1 /*idxParam*/),
697DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_2(LdStRegUnscaledImmGpr, 0xffe00c00 /*fFixedInsn*/, 0 /*fClass*/,
698 kDisArmV8OpcDecodeCollate,
699 RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(30) | RT_BIT_32(31), 22,
700 kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
701
702
703/*
704 * C4.1.94 - Loads and Stores - Load/Store register (register offset) variants
705 *
706 * Differentiate further based on the VR field.
707 *
708 * Bit 26
709 * +-------------------------------------------
710 * 0 GPR variants.
711 * 1 SIMD/FP variants
712 */
713DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegUnscaledImm)
714 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUnscaledImmGpr),
715 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
716DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegUnscaledImm, RT_BIT_32(26), 26);
717
718
719/*
720 * C4.1.94 - Loads and Stores - Load/Store register variants
721 *
722 * Differentiate further based on the op2<1:0> field.
723 *
724 * Bit 11 10
725 * +-------------------------------------------
726 * 0 0 Load/store register (unscaled immediate)
727 * 0 1 Load/store register (immediate post-indexed)
728 * 1 0 Load/store register (unprivileged)
729 * 1 1 Load/store register (immediate pre-indexed)
730 */
731DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp2_11_0)
732 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUnscaledImm),
733 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
734 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
735 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
736DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp2_11_0, RT_BIT_32(10) | RT_BIT_32(11), 10);
737
738
739/*
740 * C4.1.94 - Loads and Stores - Load/Store register variants
741 *
742 * Differentiate further based on the op2<11> field.
743 *
744 * Bit 21
745 * +-------------------------------------------
746 * 0 Load/store register (unscaled immediate) / Load/store register (immediate post-indexed) / Load/store register (unprivileged) / Load/store register (immediate pre-indexed)
747 * 1 Atomic memory operations / Load/store register (register offset) / Load/store register (pac).
748 */
749DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegOp2_11)
750 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp2_11_0),
751 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp2_11_1),
752DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegOp2_11, RT_BIT_32(21), 21);
753
754
755/*
756 * C4.1.94 - Loads and Stores - Load/Store register variants
757 *
758 * Differentiate further based on the op2<14> field.
759 *
760 * Bit 24
761 * +-------------------------------------------
762 * 0 All the other Load/store register variants and Atomic memory operations.
763 * 1 Load/store register (unsigned immediate).
764 */
765DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStReg)
766 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegOp2_11),
767 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegUImm),
768DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStReg, RT_BIT_32(24), 24);
769
770
771/*
772 * STP/LDP/STGP/LDPSW
773 *
774 * Note: The opc,L bitfields are concatenated to form an index.
775 */
776DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegPairOff)
777 DIS_ARMV8_OP_EX(0x29000000, "stp", OP_ARMV8_A64_STP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
778 DIS_ARMV8_OP_EX(0x29400000, "ldp", OP_ARMV8_A64_LDP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
779 INVALID_OPCODE,
780 INVALID_OPCODE,
781 DIS_ARMV8_OP_EX(0xa9000000, "stp", OP_ARMV8_A64_STP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
782 DIS_ARMV8_OP_EX(0xa9400000, "ldp", OP_ARMV8_A64_LDP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
783 INVALID_OPCODE,
784 INVALID_OPCODE,
785DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegPairOff)
786 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
787 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 10, 5, 1 /*idxParam*/),
788 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 2 /*idxParam*/),
789 DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOff, 15, 7, 2 /*idxParam*/),
790DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LdStRegPairOff, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
791 kDisArmV8OpcDecodeCollate,
792 RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
793 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
794
795
796/*
797 * STP/LDP/STGP/LDPSW - pre-indexed variant.
798 *
799 * Note: The opc,L bitfields are concatenated to form an index.
800 */
801DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegPairPreIndex)
802 DIS_ARMV8_OP_EX(0x29800000, "stp", OP_ARMV8_A64_STP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
803 DIS_ARMV8_OP_EX(0x29c00000, "ldp", OP_ARMV8_A64_LDP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
804 INVALID_OPCODE,
805 INVALID_OPCODE,
806 DIS_ARMV8_OP_EX(0xa9800000, "stp", OP_ARMV8_A64_STP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
807 DIS_ARMV8_OP_EX(0xa9c00000, "ldp", OP_ARMV8_A64_LDP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
808 INVALID_OPCODE,
809 INVALID_OPCODE,
810DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegPairPreIndex)
811 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
812 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 10, 5, 1 /*idxParam*/),
813 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 2 /*idxParam*/),
814 DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOff, 15, 7, 2 /*idxParam*/),
815 DIS_ARMV8_INSN_DECODE(kDisParmParseSetPreIndexed, 0, 0, 2 /*idxParam*/),
816DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LdStRegPairPreIndex, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
817 kDisArmV8OpcDecodeCollate,
818 RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
819 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
820
821
822/*
823 * STP/LDP/STGP/LDPSW - post-indexed variant.
824 *
825 * Note: The opc,L bitfields are concatenated to form an index.
826 */
827DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(LdStRegPairPostIndex)
828 DIS_ARMV8_OP_EX(0x28800000, "stp", OP_ARMV8_A64_STP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
829 DIS_ARMV8_OP_EX(0x28c00000, "ldp", OP_ARMV8_A64_LDP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_32BIT),
830 INVALID_OPCODE,
831 INVALID_OPCODE,
832 DIS_ARMV8_OP_EX(0xa8800000, "stp", OP_ARMV8_A64_STP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
833 DIS_ARMV8_OP_EX(0xa8c00000, "ldp", OP_ARMV8_A64_LDP, DISOPTYPE_HARMLESS, DISARMV8INSNCLASS_F_FORCED_64BIT),
834 INVALID_OPCODE,
835 INVALID_OPCODE,
836DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_DECODER(LdStRegPairPostIndex)
837 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
838 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 10, 5, 1 /*idxParam*/),
839 DIS_ARMV8_INSN_DECODE(kDisParmParseReg, 5, 5, 2 /*idxParam*/),
840 DIS_ARMV8_INSN_DECODE(kDisParmParseSImmMemOff, 15, 7, 2 /*idxParam*/),
841 DIS_ARMV8_INSN_DECODE(kDisParmParseSetPostIndexed, 0, 0, 2 /*idxParam*/),
842DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END_PARAMS_3(LdStRegPairPostIndex, 0xffc00000 /*fFixedInsn*/, 0 /*fClass*/,
843 kDisArmV8OpcDecodeCollate,
844 RT_BIT_32(22) | RT_BIT_32(30) | RT_BIT_32(31), 22,
845 kDisArmv8OpParmReg, kDisArmv8OpParmReg, kDisArmv8OpParmAddrInGpr);
846
847
848/*
849 * C4.1.94 - Loads and Stores - Load/Store register pair variants
850 *
851 * Differentiate further based on the op2<14:13> field.
852 *
853 * Bit 24 23
854 * +-------------------------------------------
855 * 0 0 Load/store no-allocate pair (offset)
856 * 0 1 Load/store register pair (post-indexed)
857 * 1 0 Load/store register pair (offset).
858 * 1 1 Load/store register pair (pre-indexed).
859 */
860DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStRegPair)
861 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
862 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairPostIndex),
863 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairOff),
864 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPairPreIndex),
865DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStRegPair, RT_BIT_32(23) | RT_BIT_32(24), 23);
866
867
868/*
869 * C4.1.94 - Loads and Stores
870 *
871 * Differentiate further based on the op0<1:0> field.
872 * Splitting this up because the decoding would get insane otherwise with tables doing cross referencing...
873 *
874 * Bit 29 28
875 * +-------------------------------------------
876 * 0 0 Compare and swap pair / Advanced SIMD loads/stores / Load/store exclusive pair / Load/store exclusive register
877 * Load/store ordered / Compare and swap
878 * 0 1 RCW compare and swap / 128-bit atomic memory instructions / GCS load/store / Load/store memory tags /
879 * LDIAPP/STILP / LDAPR/STLR / Load register (literal) / Memory Copy and Set
880 * 1 0 Load/store no-allocate pair / Load/store register pair /
881 * 1 1 Load/store register / Atomic memory operations
882 */
883DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(LdStOp0Lo)
884 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
885 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo */
886 DIS_ARMV8_DECODE_MAP_ENTRY(LdStRegPair),
887 DIS_ARMV8_DECODE_MAP_ENTRY(LdStReg),
888DIS_ARMV8_DECODE_MAP_DEFINE_END(LdStOp0Lo, RT_BIT_32(28) | RT_BIT_32(29), 28);
889
890
891/*
892 * C4.1 of the ARMv8 architecture reference manual has the following table for the
893 * topmost decoding level (Level 0 in our terms), x means don't care:
894 *
895 * Bit 28 27 26 25
896 * +-------------------------------------------
897 * 0 0 0 0 Reserved or SME encoding (depends on bit 31).
898 * 0 0 0 1 UNALLOC
899 * 0 0 1 0 SVE encodings
900 * 0 0 1 1 UNALLOC
901 * 1 0 0 x Data processing immediate
902 * 1 0 1 x Branch, exception generation and system instructions
903 * x 1 x 0 Loads and stores
904 * x 1 0 1 Data processing - register
905 * x 1 1 1 Data processing - SIMD and floating point
906 *
907 * In order to save us some fiddling with the don't care bits we blow up the lookup table
908 * which gives us 16 possible values (4 bits) we can use as an index into the decoder
909 * lookup table for the next level:
910 * Bit 28 27 26 25
911 * +-------------------------------------------
912 * 0 0 0 0 0 Reserved or SME encoding (depends on bit 31).
913 * 1 0 0 0 1 UNALLOC
914 * 2 0 0 1 0 SVE encodings
915 * 3 0 0 1 1 UNALLOC
916 * 4 0 1 0 0 Loads and stores
917 * 5 0 1 0 1 Data processing - register (using op1 (bit 28) from the next stage to differentiate further already)
918 * 6 0 1 1 0 Loads and stores
919 * 7 0 1 1 1 Data processing - SIMD and floating point
920 * 8 1 0 0 0 Data processing immediate
921 * 9 1 0 0 1 Data processing immediate
922 * 10 1 0 1 0 Branch, exception generation and system instructions
923 * 11 1 0 1 1 Branch, exception generation and system instructions
924 * 12 1 1 0 0 Loads and stores
925 * 13 1 1 0 1 Data processing - register (using op1 (bit 28) from the next stage to differentiate further already)
926 * 14 1 1 1 0 Loads and stores
927 * 15 1 1 1 1 Data processing - SIMD and floating point
928 */
929DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(DecodeL0)
930 DIS_ARMV8_DECODE_MAP_ENTRY(Rsvd), /* Reserved class or SME encoding (@todo). */
931 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Unallocated */
932 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo SVE */
933 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Unallocated */
934 DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo), /* Load/Stores. */
935 DIS_ARMV8_DECODE_MAP_ENTRY(LogicalAddSubReg), /* Data processing (register) (see op1 in C4.1.68). */
936 DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo), /* Load/Stores. */
937 DIS_ARMV8_DECODE_MAP_ENTRY(DataProcSimdFpBit28_0), /* Data processing (SIMD & FP) (op0<0> 0) */
938 DIS_ARMV8_DECODE_MAP_ENTRY(DataProcessingImm), /* Data processing (immediate). */
939 DIS_ARMV8_DECODE_MAP_ENTRY(DataProcessingImm), /* Data processing (immediate). */
940 DIS_ARMV8_DECODE_MAP_ENTRY(BrExcpSys), /* Branches / Exception generation and system instructions. */
941 DIS_ARMV8_DECODE_MAP_ENTRY(BrExcpSys), /* Branches / Exception generation and system instructions. */
942 DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo), /* Load/Stores. */
943 DIS_ARMV8_DECODE_MAP_ENTRY(DataProcReg), /* Data processing (register) (see op1 in C4.1.68). */
944 DIS_ARMV8_DECODE_MAP_ENTRY(LdStOp0Lo), /* Load/Stores. */
945 DIS_ARMV8_DECODE_MAP_ENTRY(DataProcSimdFpBit28_1) /* Data processing (SIMD & FP) (op0<0> 1). */
946DIS_ARMV8_DECODE_MAP_DEFINE_END_NON_STATIC(DecodeL0, RT_BIT_32(25) | RT_BIT_32(26) | RT_BIT_32(27) | RT_BIT_32(28), 25);
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette