VirtualBox

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

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

Disassembler/ARMv8: Updates, decode more instructions, add them to the testcase, bugref:10394

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.6 KB
Line 
1/* $Id: DisasmTables-armv8-a64.cpp 105779 2024-08-21 16:39:51Z vboxsync $ */
2/** @file
3 * VBox disassembler - Tables for ARMv8 A64.
4 */
5
6/*
7 * Copyright (C) 2023 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_fMask, a_fValue, a_szOpcode, a_uOpcode, a_fOpType) \
42 { a_fMask, a_fValue, OP(a_szOpcode, 0, 0, 0, a_uOpcode, 0, 0, 0, a_fOpType) }
43
44#ifndef DIS_CORE_ONLY
45static char g_szInvalidOpcode[] = "Invalid Opcode";
46#endif
47
48#define INVALID_OPCODE \
49 DIS_ARMV8_OP(0xffffffff, 0, g_szInvalidOpcode, OP_ARMV8_INVALID, DISOPTYPE_INVALID)
50
51
52/* Invalid opcode */
53DECL_HIDDEN_CONST(DISOPCODE) g_ArmV8A64InvalidOpcode[1] =
54{
55 OP(g_szInvalidOpcode, 0, 0, 0, 0, 0, 0, 0, DISOPTYPE_INVALID)
56};
57
58
59/* UDF */
60DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_aArmV8A64InsnRsvd)
61 DIS_ARMV8_OP(0xffff0000, 0x00000000, "udf" , OP_ARMV8_A64_UDF, DISOPTYPE_INVALID)
62DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_aArmV8A64InsnRsvd, 0 /*fClass*/,
63 kDisArmV8OpcDecodeNop, 0xffff0000, 16,
64 kDisArmv8OpParmImm)
65 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 0, 16, 0 /*idxParam*/),
66 DIS_ARMV8_INSN_PARAM_NONE,
67 DIS_ARMV8_INSN_PARAM_NONE,
68 DIS_ARMV8_INSN_PARAM_NONE,
69 DIS_ARMV8_INSN_PARAM_NONE
70DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
71
72
73/* ADR/ADRP */
74DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Adr)
75 DIS_ARMV8_OP(0x9f000000, 0x10000000, "adr" , OP_ARMV8_A64_ADR, DISOPTYPE_HARMLESS),
76 DIS_ARMV8_OP(0x9f000000, 0x90000000, "adrp" , OP_ARMV8_A64_ADRP, DISOPTYPE_HARMLESS)
77DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64Adr, DISARMV8INSNCLASS_F_FORCED_64BIT,
78 kDisArmV8OpcDecodeNop, RT_BIT_32(31), 31,
79 kDisArmv8OpParmGpr, kDisArmv8OpParmImmRel)
80 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
81 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmAdr, 0, 0, 1 /*idxParam*/),
82 DIS_ARMV8_INSN_PARAM_NONE,
83 DIS_ARMV8_INSN_PARAM_NONE,
84 DIS_ARMV8_INSN_PARAM_NONE
85DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
86
87
88/* ADD/ADDS/SUB/SUBS */
89DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64AddSubImm)
90 DIS_ARMV8_OP(0x7f800000, 0x11000000, "add" , OP_ARMV8_A64_ADD, DISOPTYPE_HARMLESS),
91 DIS_ARMV8_OP(0x7f800000, 0x31000000, "adds" , OP_ARMV8_A64_ADDS, DISOPTYPE_HARMLESS),
92 DIS_ARMV8_OP(0x7f800000, 0x51000000, "sub" , OP_ARMV8_A64_SUB, DISOPTYPE_HARMLESS),
93 DIS_ARMV8_OP(0x7f800000, 0x71000000, "subs" , OP_ARMV8_A64_SUBS, DISOPTYPE_HARMLESS),
94DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_3(g_ArmV8A64AddSubImm, DISARMV8INSNCLASS_F_SF,
95 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
96 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm)
97 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
98 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
99 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 10, 12, 2 /*idxParam*/),
100 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseSh12, 22, 1, 2 /*idxParam*/),
101 DIS_ARMV8_INSN_PARAM_NONE
102DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
103
104
105/* AND/ORR/EOR/ANDS */
106DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64LogicalImm)
107 DIS_ARMV8_OP(0x7f800000, 0x12000000, "and" , OP_ARMV8_A64_AND, DISOPTYPE_HARMLESS),
108 DIS_ARMV8_OP(0x7f800000, 0x32000000, "orr" , OP_ARMV8_A64_ORR, DISOPTYPE_HARMLESS),
109 DIS_ARMV8_OP(0x7f800000, 0x52000000, "eor" , OP_ARMV8_A64_EOR, DISOPTYPE_HARMLESS),
110 DIS_ARMV8_OP(0x7f800000, 0x72000000, "ands" , OP_ARMV8_A64_ANDS, DISOPTYPE_HARMLESS),
111DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_3(g_ArmV8A64LogicalImm, DISARMV8INSNCLASS_F_SF,
112 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
113 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm)
114 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
115 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
116 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmsImmrN, 10, 13, 2 /*idxParam*/),
117 DIS_ARMV8_INSN_PARAM_NONE,
118 DIS_ARMV8_INSN_PARAM_NONE
119DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
120
121
122/* MOVN/MOVZ/MOVK */
123DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64MoveWide)
124 DIS_ARMV8_OP(0x7f800000, 0x12800000, "movn", OP_ARMV8_A64_MOVN, DISOPTYPE_HARMLESS),
125 INVALID_OPCODE,
126 DIS_ARMV8_OP(0x7f800000, 0x52800000, "movz" , OP_ARMV8_A64_MOVZ, DISOPTYPE_HARMLESS),
127 DIS_ARMV8_OP(0x7f800000, 0x72800000, "movk" , OP_ARMV8_A64_MOVK, DISOPTYPE_HARMLESS),
128DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64MoveWide, DISARMV8INSNCLASS_F_SF,
129 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
130 kDisArmv8OpParmGpr, kDisArmv8OpParmImm)
131 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
132 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 5, 16, 1 /*idxParam*/),
133 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseHw, 21, 2, 1 /*idxParam*/),
134 DIS_ARMV8_INSN_PARAM_NONE,
135 DIS_ARMV8_INSN_PARAM_NONE
136DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
137
138
139/* SBFM/BFM/UBFM */
140DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Bitfield)
141 DIS_ARMV8_OP(0x7f800000, 0x13000000, "sbfm", OP_ARMV8_A64_SBFM, DISOPTYPE_HARMLESS),
142 DIS_ARMV8_OP(0x7f800000, 0x33000000, "bfm", OP_ARMV8_A64_BFM, DISOPTYPE_HARMLESS),
143 DIS_ARMV8_OP(0x7f800000, 0x53000000, "ubfm", OP_ARMV8_A64_UBFM, DISOPTYPE_HARMLESS),
144 INVALID_OPCODE,
145DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_4(g_ArmV8A64Bitfield, DISARMV8INSNCLASS_F_SF | DISARMV8INSNCLASS_F_N_FORCED_1_ON_64BIT,
146 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
147 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmImm, kDisArmv8OpParmImm)
148 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
149 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
150 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 16, 6, 2 /*idxParam*/),
151 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 10, 6, 3 /*idxParam*/),
152 DIS_ARMV8_INSN_PARAM_NONE
153DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
154
155
156/*
157 * C4.1.65 of the ARMv8 architecture reference manual has the following table for the
158 * data processing (immediate) instruction classes:
159 *
160 * Bit 25 24 23
161 * +-------------------------------------------
162 * 0 0 x PC-rel. addressing.
163 * 0 1 0 Add/subtract (immediate)
164 * 0 1 1 Add/subtract (immediate, with tags)
165 * 1 0 0 Logical (immediate)
166 * 1 0 1 Move wide (immediate)
167 * 1 1 0 Bitfield
168 * 1 1 1 Extract
169 */
170DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_aArmV8A64InsnDataProcessingImm)
171 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64Adr),
172 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64Adr),
173 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64AddSubImm),
174 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo Add/subtract immediate with tags. */
175 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64LogicalImm),
176 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64MoveWide),
177 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64Bitfield),
178 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY /** @todo Extract */
179DIS_ARMV8_DECODE_MAP_DEFINE_END(g_aArmV8A64InsnDataProcessingImm, RT_BIT_32(23) | RT_BIT_32(24) | RT_BIT_32(25), 23);
180
181
182/* B.cond/BC.cond */
183DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64CondBr)
184 DIS_ARMV8_OP(0xff000010, 0x54000000, "b", OP_ARMV8_A64_B, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW | DISOPTYPE_RELATIVE_CONTROLFLOW | DISOPTYPE_COND_CONTROLFLOW),
185 DIS_ARMV8_OP(0xff000010, 0x54000010, "bc" , OP_ARMV8_A64_BC, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW | DISOPTYPE_RELATIVE_CONTROLFLOW | DISOPTYPE_COND_CONTROLFLOW),
186DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64CondBr, 0 /*fClass*/,
187 kDisArmV8OpcDecodeNop, RT_BIT_32(4), 4,
188 kDisArmv8OpParmImmRel)
189 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseCond, 0, 4, DIS_ARMV8_INSN_PARAM_UNSET),
190 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmRel, 5, 19, 0 /*idxParam*/),
191 DIS_ARMV8_INSN_PARAM_NONE,
192 DIS_ARMV8_INSN_PARAM_NONE,
193 DIS_ARMV8_INSN_PARAM_NONE
194DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
195
196
197/* SVC/HVC/SMC/BRK/HLT/TCANCEL/DCPS1/DCPS2/DCPS3 */
198DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Excp)
199 DIS_ARMV8_OP(0xffe0001f, 0xd4000001, "svc", OP_ARMV8_A64_SVC, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
200 DIS_ARMV8_OP(0xffe0001f, 0xd4000002, "hvc", OP_ARMV8_A64_HVC, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT | DISOPTYPE_PRIVILEGED),
201 DIS_ARMV8_OP(0xffe0001f, 0xd4000003, "smc", OP_ARMV8_A64_SMC, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT | DISOPTYPE_PRIVILEGED),
202 DIS_ARMV8_OP(0xffe0001f, 0xd4200000, "brk", OP_ARMV8_A64_BRK, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
203 DIS_ARMV8_OP(0xffe0001f, 0xd4400000, "hlt", OP_ARMV8_A64_HLT, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
204 DIS_ARMV8_OP(0xffe0001f, 0xd4600000, "tcancel", OP_ARMV8_A64_TCANCEL, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT), /* FEAT_TME */
205 DIS_ARMV8_OP(0xffe0001f, 0xd4a00001, "dcps1", OP_ARMV8_A64_DCPS1, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
206 DIS_ARMV8_OP(0xffe0001f, 0xd4a00002, "dcps2", OP_ARMV8_A64_DCPS2, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
207 DIS_ARMV8_OP(0xffe0001f, 0xd4a00003, "dcps3", OP_ARMV8_A64_DCPS3, DISOPTYPE_CONTROLFLOW | DISOPTYPE_INTERRUPT),
208DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64Excp, 0 /*fClass*/,
209 kDisArmV8OpcDecodeLookup, 0xffe0001f, 0,
210 kDisArmv8OpParmImm)
211 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 5, 16, 0 /*idxParam*/),
212 DIS_ARMV8_INSN_PARAM_NONE,
213 DIS_ARMV8_INSN_PARAM_NONE,
214 DIS_ARMV8_INSN_PARAM_NONE,
215 DIS_ARMV8_INSN_PARAM_NONE
216DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
217
218
219/* WFET/WFIT */
220DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64SysReg)
221 DIS_ARMV8_OP(0xffffffe0, 0xd5031000, "wfet", OP_ARMV8_A64_WFET, DISOPTYPE_HARMLESS), /* FEAT_WFxT */
222 DIS_ARMV8_OP(0xffffffe0, 0x54000010, "wfit" , OP_ARMV8_A64_WFIT, DISOPTYPE_HARMLESS), /* FEAT_WFxT */
223DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64SysReg, DISARMV8INSNCLASS_F_FORCED_64BIT,
224 kDisArmV8OpcDecodeNop, 0xfe0, 5,
225 kDisArmv8OpParmGpr)
226 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
227 DIS_ARMV8_INSN_PARAM_NONE,
228 DIS_ARMV8_INSN_PARAM_NONE,
229 DIS_ARMV8_INSN_PARAM_NONE,
230 DIS_ARMV8_INSN_PARAM_NONE
231DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
232
233
234/* Various hint instructions */
235DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Hints)
236 DIS_ARMV8_OP(0xffffffff, 0xd503201f, "nop", OP_ARMV8_A64_NOP, DISOPTYPE_HARMLESS),
237 DIS_ARMV8_OP(0xffffffff, 0xd503203f, "yield", OP_ARMV8_A64_YIELD, DISOPTYPE_HARMLESS),
238 DIS_ARMV8_OP(0xffffffff, 0xd503205f, "wfe", OP_ARMV8_A64_WFE, DISOPTYPE_HARMLESS),
239 DIS_ARMV8_OP(0xffffffff, 0xd503207f, "wfi", OP_ARMV8_A64_WFI, DISOPTYPE_HARMLESS),
240 DIS_ARMV8_OP(0xffffffff, 0xd503209f, "sev", OP_ARMV8_A64_SEV, DISOPTYPE_HARMLESS),
241 DIS_ARMV8_OP(0xffffffff, 0xd50320bf, "sevl", OP_ARMV8_A64_SEVL, DISOPTYPE_HARMLESS),
242 DIS_ARMV8_OP(0xffffffff, 0xd50320df, "dgh", OP_ARMV8_A64_DGH, DISOPTYPE_HARMLESS), /* FEAT_DGH */
243 DIS_ARMV8_OP(0xffffffff, 0xd50320ff, "xpaclri", OP_ARMV8_A64_XPACLRI, DISOPTYPE_HARMLESS), /* FEAT_PAuth */
244 /** @todo */
245DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_0(g_ArmV8A64Hints, 0 /*fClass*/,
246 kDisArmV8OpcDecodeNop, 0xfe0, 5)
247 DIS_ARMV8_INSN_PARAM_NONE,
248 DIS_ARMV8_INSN_PARAM_NONE,
249 DIS_ARMV8_INSN_PARAM_NONE,
250 DIS_ARMV8_INSN_PARAM_NONE,
251 DIS_ARMV8_INSN_PARAM_NONE
252DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
253
254
255/* CLREX */
256DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64DecBarriers)
257 DIS_ARMV8_OP(0xfffff0ff, 0xd503304f, "clrex", OP_ARMV8_A64_CLREX, DISOPTYPE_HARMLESS),
258 DIS_ARMV8_OP(0xfffff0ff, 0xd50330bf, "dmb", OP_ARMV8_A64_DMB, DISOPTYPE_HARMLESS),
259DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64DecBarriers, 0 /*fClass*/,
260 kDisArmV8OpcDecodeNop, RT_BIT_32(5), 5,
261 kDisArmv8OpParmImm)
262 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 8, 4, 0 /*idxParam*/),
263 DIS_ARMV8_INSN_PARAM_NONE,
264 DIS_ARMV8_INSN_PARAM_NONE,
265 DIS_ARMV8_INSN_PARAM_NONE,
266 DIS_ARMV8_INSN_PARAM_NONE
267DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
268
269
270/* Barrier instructions, we divide these instructions further based on the op2 field. */
271DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_ArmV8A64DecodeBarriers)
272 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
273 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo DSB - Encoding */
274 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64DecBarriers), /* CLREX */
275 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo TCOMMIT */
276 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo DSB - Encoding */
277 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64DecBarriers), /* DMB */
278 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo ISB */
279 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY /** @todo SB */
280DIS_ARMV8_DECODE_MAP_DEFINE_END(g_ArmV8A64DecodeBarriers, RT_BIT_32(5) | RT_BIT_32(6) | RT_BIT_32(7), 5);
281
282
283/* MSR (and potentially CFINV,XAFLAG,AXFLAG) */
284DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64PState)
285 DIS_ARMV8_OP(0xfffff0ff, 0xd503305f, "msr", OP_ARMV8_A64_MSR, DISOPTYPE_PRIVILEGED),
286DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64PState, 0 /*fClass*/,
287 kDisArmV8OpcDecodeNop, 0, 0,
288 kDisArmv8OpParmImm, kDisArmv8OpParmNone) /** @todo */
289 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParsePState, 0, 0, 0 /*idxParam*/), /* This is special for the MSR instruction. */
290 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 8, 4, 1 /*idxParam*/), /* CRm field encodes the immediate value */
291 DIS_ARMV8_INSN_PARAM_NONE,
292 DIS_ARMV8_INSN_PARAM_NONE,
293 DIS_ARMV8_INSN_PARAM_NONE
294DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
295
296
297/* TSTART/TTEST */
298DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64SysResult)
299 DIS_ARMV8_OP(0xfffffffe, 0xd5233060, "tstart", OP_ARMV8_A64_TSTART, DISOPTYPE_HARMLESS | DISOPTYPE_PRIVILEGED), /* FEAT_TME */
300 DIS_ARMV8_OP(0xfffffffe, 0xd5233160, "ttest", OP_ARMV8_A64_TTEST, DISOPTYPE_HARMLESS), /* FEAT_TME */
301DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64SysResult, DISARMV8INSNCLASS_F_FORCED_64BIT,
302 kDisArmV8OpcDecodeNop, RT_BIT_32(8) | RT_BIT_32(9) | RT_BIT_32(10) | RT_BIT_32(11), 8,
303 kDisArmv8OpParmGpr)
304 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
305 DIS_ARMV8_INSN_PARAM_NONE,
306 DIS_ARMV8_INSN_PARAM_NONE,
307 DIS_ARMV8_INSN_PARAM_NONE,
308 DIS_ARMV8_INSN_PARAM_NONE
309DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
310
311
312/* SYS */
313DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Sys)
314 DIS_ARMV8_OP(0xfff80000, 0xd5080000, "sys", OP_ARMV8_A64_SYS, DISOPTYPE_HARMLESS),
315DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_0(g_ArmV8A64Sys, DISARMV8INSNCLASS_F_FORCED_64BIT,
316 kDisArmV8OpcDecodeNop, 0, 0) /** @todo */
317 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 16, 3, 0 /*idxParam*/),
318 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseCRnCRm, 8, 8, 1 /*idxParam*/),
319 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 5, 3, 2 /*idxParam*/),
320 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 3 /*idxParam*/),
321 DIS_ARMV8_INSN_PARAM_NONE
322DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
323
324
325/* SYSL */
326DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64SysL)
327 DIS_ARMV8_OP(0xfff80000, 0xd5280000, "sysl", OP_ARMV8_A64_SYSL, DISOPTYPE_HARMLESS),
328DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_0(g_ArmV8A64SysL, DISARMV8INSNCLASS_F_FORCED_64BIT,
329 kDisArmV8OpcDecodeNop, 0, 0) /** @todo */
330 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
331 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 16, 3, 1 /*idxParam*/),
332 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseCRnCRm, 8, 8, 2 /*idxParam*/),
333 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImm, 5, 3, 3 /*idxParam*/),
334 DIS_ARMV8_INSN_PARAM_NONE
335DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
336
337
338/* MSR */
339DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Msr)
340 DIS_ARMV8_OP(0xfff00000, 0xd5100000, "msr", OP_ARMV8_A64_MSR, DISOPTYPE_HARMLESS | DISOPTYPE_PRIVILEGED),
341DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64Msr, DISARMV8INSNCLASS_F_FORCED_64BIT,
342 kDisArmV8OpcDecodeNop, 0, 0,
343 kDisArmv8OpParmSysReg, kDisArmv8OpParmGpr)
344 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseSysReg, 5, 15, 0 /*idxParam*/),
345 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 1 /*idxParam*/),
346 DIS_ARMV8_INSN_PARAM_NONE,
347 DIS_ARMV8_INSN_PARAM_NONE,
348 DIS_ARMV8_INSN_PARAM_NONE
349DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
350
351
352/* MRS */
353DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Mrs)
354 DIS_ARMV8_OP(0xfff00000, 0xd5300000, "mrs", OP_ARMV8_A64_MRS, DISOPTYPE_HARMLESS | DISOPTYPE_PRIVILEGED),
355DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64Mrs, DISARMV8INSNCLASS_F_FORCED_64BIT,
356 kDisArmV8OpcDecodeNop, 0, 0,
357 kDisArmv8OpParmGpr, kDisArmv8OpParmSysReg)
358 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
359 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseSysReg, 5, 15, 1 /*idxParam*/),
360 DIS_ARMV8_INSN_PARAM_NONE,
361 DIS_ARMV8_INSN_PARAM_NONE,
362 DIS_ARMV8_INSN_PARAM_NONE
363DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
364
365
366/* RET/RETAA/RETAB */
367DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64Ret)
368 DIS_ARMV8_OP(0xfffffc1f, 0xd65f0000, "ret", OP_ARMV8_A64_RET, DISOPTYPE_HARMLESS),
369 DIS_ARMV8_OP(0xfffffc1f, 0xd65f0800, "retaa", OP_ARMV8_A64_RETAA, DISOPTYPE_HARMLESS),
370 DIS_ARMV8_OP(0xfffffc1f, 0xd65f0c00, "retab", OP_ARMV8_A64_RETAB, DISOPTYPE_HARMLESS),
371DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64Ret, DISARMV8INSNCLASS_F_FORCED_64BIT,
372 kDisArmV8OpcDecodeLookup, 0xfffffc1f, 0,
373 kDisArmv8OpParmGpr)
374 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 5, 5, 0 /*idxParam*/),
375 DIS_ARMV8_INSN_PARAM_NONE,
376 DIS_ARMV8_INSN_PARAM_NONE,
377 DIS_ARMV8_INSN_PARAM_NONE,
378 DIS_ARMV8_INSN_PARAM_NONE
379DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
380
381
382/* Unconditional branch (register) instructions, we divide these instructions further based on the opc field. */
383DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_ArmV8A64UncondBrReg)
384 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
385 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
386 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64Ret), /* RET/RETAA/RETAB */
387 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
388 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
389 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
390 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
391 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
392 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
393 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
394 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
395 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
396 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
397 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
398 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
399 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY
400DIS_ARMV8_DECODE_MAP_DEFINE_END(g_ArmV8A64UncondBrReg, RT_BIT_32(21) | RT_BIT_32(22) | RT_BIT_32(23) | RT_BIT_32(24), 21);
401
402
403/* B/BL */
404DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64UncondBrImm)
405 DIS_ARMV8_OP(0xfc000000, 0x14000000, "b", OP_ARMV8_A64_B, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
406 DIS_ARMV8_OP(0xfc000000, 0x94000000, "bl", OP_ARMV8_A64_BL, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
407DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_1(g_ArmV8A64UncondBrImm, 0 /*fClass*/,
408 kDisArmV8OpcDecodeNop, RT_BIT_32(31), 31,
409 kDisArmv8OpParmImmRel)
410 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmRel, 0, 26, 0 /*idxParam*/),
411 DIS_ARMV8_INSN_PARAM_NONE,
412 DIS_ARMV8_INSN_PARAM_NONE,
413 DIS_ARMV8_INSN_PARAM_NONE,
414 DIS_ARMV8_INSN_PARAM_NONE
415DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
416
417
418/* CBZ/CBNZ */
419DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64CmpBrImm)
420 DIS_ARMV8_OP(0x7f000000, 0x34000000, "cbz", OP_ARMV8_A64_CBZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
421 DIS_ARMV8_OP(0x7f000000, 0x35000000, "cbnz", OP_ARMV8_A64_CBNZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
422DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64CmpBrImm, DISARMV8INSNCLASS_F_SF,
423 kDisArmV8OpcDecodeNop, RT_BIT_32(24), 24,
424 kDisArmv8OpParmGpr, kDisArmv8OpParmImmRel)
425 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
426 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmRel, 5, 19, 1 /*idxParam*/),
427 DIS_ARMV8_INSN_PARAM_NONE,
428 DIS_ARMV8_INSN_PARAM_NONE,
429 DIS_ARMV8_INSN_PARAM_NONE
430DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
431
432
433/* TBZ/TBNZ */
434DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64TestBrImm)
435 DIS_ARMV8_OP(0x7f000000, 0x36000000, "tbz", OP_ARMV8_A64_TBZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
436 DIS_ARMV8_OP(0x7f000000, 0x37000000, "tbnz", OP_ARMV8_A64_TBNZ, DISOPTYPE_HARMLESS | DISOPTYPE_CONTROLFLOW),
437DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_3(g_ArmV8A64TestBrImm, DISARMV8INSNCLASS_F_SF, /* Not an SF bit but has the same meaning. */
438 kDisArmV8OpcDecodeNop, RT_BIT_32(24), 24,
439 kDisArmv8OpParmGpr, kDisArmv8OpParmImm, kDisArmv8OpParmImmRel)
440 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
441 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmTbz, 0, 0, 1 /*idxParam*/), /* Hardcoded bit offsets in parser. */
442 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseImmRel, 5, 14, 2 /*idxParam*/),
443 DIS_ARMV8_INSN_PARAM_NONE,
444 DIS_ARMV8_INSN_PARAM_NONE
445DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
446
447
448DIS_ARMV8_DECODE_TBL_DEFINE_BEGIN(g_ArmV8A64BrExcpSys)
449 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfe000000, RT_BIT_32(26) | RT_BIT_32(28) | RT_BIT_32(30), g_ArmV8A64CondBr), /* op0: 010, op1: 0xxxxxxxxxxxxx, op2: - (including o1 from the conditional branch (immediate) class to save us one layer). */
450 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xff000000, RT_BIT_32(26) | RT_BIT_32(28) | RT_BIT_32(30) | RT_BIT_32(31), g_ArmV8A64Excp), /* op0: 110, op1: 00xxxxxxxxxxxx, op2: -. */
451 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff000, 0xd5031000, g_ArmV8A64SysReg), /* op0: 110, op1: 01000000110001, op2: -. */
452 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff01f, 0xd503201f, g_ArmV8A64Hints), /* op0: 110, op1: 01000000110010, op2: 11111. */
453 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff01f, 0xd503301f, g_ArmV8A64DecodeBarriers), /* op0: 110, op1: 01000000110011, op2: - (we include Rt: 11111 from the next stage here). */
454 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff8f01f, 0xd500401f, g_ArmV8A64PState), /* op0: 110, op1: 0100000xxx0100, op2: - (we include Rt: 11111 from the next stage here). */
455 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfffff0e0, 0xd5233060, g_ArmV8A64SysResult), /* op0: 110, op1: 0100100xxxxxxx, op2: - (we include op1, CRn and op2 from the next stage here). */
456 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff80000, 0xd5080000, g_ArmV8A64Sys), /* 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). */
457 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff80000, 0xd5280000, g_ArmV8A64SysL), /* 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). */
458 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff00000, 0xd5100000, g_ArmV8A64Msr), /* 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). */
459 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfff00000, 0xd5300000, g_ArmV8A64Mrs), /* 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). */
460 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0xfe1f0000, 0xd61f0000, g_ArmV8A64UncondBrReg), /* op0: 110, op1: 1xxxxxxxxxxxxx, op2: - (we include the op2 field from the next stage here as it should be always 11111). */
461 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0x7c000000, 0x14000000, g_ArmV8A64UncondBrImm), /* op0: x00, op1: xxxxxxxxxxxxxx, op2: -. */
462 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0x7e000000, 0x34000000, g_ArmV8A64CmpBrImm), /* op0: x01, op1: 0xxxxxxxxxxxxx, op2: -. */
463 DIS_ARMV8_DECODE_TBL_ENTRY_INIT(0x7e000000, 0x36000000, g_ArmV8A64TestBrImm), /* op0: x01, op1: 1xxxxxxxxxxxxx, op2: -. */
464DIS_ARMV8_DECODE_TBL_DEFINE_END(g_ArmV8A64BrExcpSys);
465
466
467/* AND/ORR/EOR/ANDS */
468DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_aArmV8A64InsnLogShiftRegN0)
469 DIS_ARMV8_OP(0x7f200000, 0x0a000000, "and", OP_ARMV8_A64_AND, DISOPTYPE_HARMLESS),
470 DIS_ARMV8_OP(0x7f200000, 0x2a000000, "orr", OP_ARMV8_A64_ORR, DISOPTYPE_HARMLESS),
471 DIS_ARMV8_OP(0x7f200000, 0x4a000000, "eor", OP_ARMV8_A64_EOR, DISOPTYPE_HARMLESS),
472 DIS_ARMV8_OP(0x7f200000, 0x6a000000, "ands", OP_ARMV8_A64_ANDS, DISOPTYPE_HARMLESS)
473DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_3(g_aArmV8A64InsnLogShiftRegN0, DISARMV8INSNCLASS_F_SF,
474 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
475 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmGpr)
476 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
477 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
478 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 16, 5, 2 /*idxParam*/),
479 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseShift, 22, 2, 2 /*idxParam*/),
480 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseShiftAmount, 10, 6, 2 /*idxParam*/),
481DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
482
483
484/* AND/ORR/EOR/ANDS */
485DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_aArmV8A64InsnLogShiftRegN1)
486 DIS_ARMV8_OP(0x7f200000, 0x0a200000, "bic", OP_ARMV8_A64_BIC, DISOPTYPE_HARMLESS),
487 DIS_ARMV8_OP(0x7f200000, 0x2a200000, "orn", OP_ARMV8_A64_ORN, DISOPTYPE_HARMLESS),
488 DIS_ARMV8_OP(0x7f200000, 0x4a200000, "eon", OP_ARMV8_A64_EON, DISOPTYPE_HARMLESS),
489 DIS_ARMV8_OP(0x7f200000, 0x6a200000, "bics", OP_ARMV8_A64_BICS, DISOPTYPE_HARMLESS)
490DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_3(g_aArmV8A64InsnLogShiftRegN1, DISARMV8INSNCLASS_F_SF,
491 kDisArmV8OpcDecodeNop, RT_BIT_32(29) | RT_BIT_32(30), 29,
492 kDisArmv8OpParmGpr, kDisArmv8OpParmGpr, kDisArmv8OpParmGpr)
493 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 0, 5, 0 /*idxParam*/),
494 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 5, 5, 1 /*idxParam*/),
495 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseReg, 16, 5, 2 /*idxParam*/),
496 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseShift, 22, 2, 2 /*idxParam*/),
497 DIS_ARMV8_INSN_PARAM_CREATE(kDisParmParseShiftAmount, 10, 6, 2 /*idxParam*/),
498DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
499
500
501DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_aArmV8A64InsnLogShiftRegN)
502 DIS_ARMV8_DECODE_MAP_ENTRY(g_aArmV8A64InsnLogShiftRegN0), /* Logical (shifted register) - N = 0 */
503 DIS_ARMV8_DECODE_MAP_ENTRY(g_aArmV8A64InsnLogShiftRegN1), /* Logical (shifted register) - N = 1 */
504DIS_ARMV8_DECODE_MAP_DEFINE_END(g_aArmV8A64InsnLogShiftRegN, RT_BIT_32(21), 21);
505
506
507DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_ArmV8A64LogicalAddSubReg)
508 DIS_ARMV8_DECODE_MAP_ENTRY(g_aArmV8A64InsnLogShiftRegN), /* Logical (shifted register) */
509 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Add/subtract (shifted/extended register) */
510DIS_ARMV8_DECODE_MAP_DEFINE_END(g_ArmV8A64LogicalAddSubReg, RT_BIT_32(24), 24);
511
512
513DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_ArmV8A64DataProcReg)
514 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY,
515DIS_ARMV8_DECODE_MAP_DEFINE_END(g_ArmV8A64DataProcReg, RT_BIT_32(24), 24);
516
517
518DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_BEGIN(g_ArmV8A64LdSt)
519 DIS_ARMV8_OP(0xbfc00000, 0xb9400000, "ldr", OP_ARMV8_A64_LDR, DISOPTYPE_HARMLESS),
520 DIS_ARMV8_OP(0xbfc00000, 0xb9000000, "str", OP_ARMV8_A64_STR, DISOPTYPE_HARMLESS),
521DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_PARAMS_2(g_ArmV8A64LdSt, 0 /*fClass*/,
522 kDisArmV8OpcDecodeLookup, 0xbfc00000, 0,
523 kDisArmv8OpParmGpr, kDisArmv8OpParmAddrInGpr)
524 DIS_ARMV8_INSN_PARAM_CREATE( kDisParmParseIs32Bit, 30, 1, DIS_ARMV8_INSN_PARAM_UNSET),
525 DIS_ARMV8_INSN_PARAM_CREATE( kDisParmParseReg, 0, 5, 0 /*idxParam*/),
526 DIS_ARMV8_INSN_PARAM_CREATE_EX(kDisParmParseReg, 5, 5, 1 /*idxParam*/, DIS_ARMV8_INSN_PARAM_F_ADDR_BEGIN),
527 DIS_ARMV8_INSN_PARAM_CREATE_EX(kDisParmParseImm, 10, 12, 2 /*idxParam*/, DIS_ARMV8_INSN_PARAM_F_ADDR_END),
528 DIS_ARMV8_INSN_PARAM_NONE
529DIS_ARMV8_DECODE_INSN_CLASS_DEFINE_END;
530
531
532/*
533 * C4.1 of the ARMv8 architecture reference manual has the following table for the
534 * topmost decoding level (Level 0 in our terms), x means don't care:
535 *
536 * Bit 28 27 26 25
537 * +-------------------------------------------
538 * 0 0 0 0 Reserved or SME encoding (depends on bit 31).
539 * 0 0 0 1 UNALLOC
540 * 0 0 1 0 SVE encodings
541 * 0 0 1 1 UNALLOC
542 * 1 0 0 x Data processing immediate
543 * 1 0 1 x Branch, exception generation and system instructions
544 * x 1 x 0 Loads and stores
545 * x 1 0 1 Data processing - register
546 * x 1 1 1 Data processing - SIMD and floating point
547 *
548 * In order to save us some fiddling with the don't care bits we blow up the lookup table
549 * which gives us 16 possible values (4 bits) we can use as an index into the decoder
550 * lookup table for the next level:
551 * Bit 28 27 26 25
552 * +-------------------------------------------
553 * 0 0 0 0 0 Reserved or SME encoding (depends on bit 31).
554 * 1 0 0 0 1 UNALLOC
555 * 2 0 0 1 0 SVE encodings
556 * 3 0 0 1 1 UNALLOC
557 * 4 0 1 0 0 Loads and stores
558 * 5 0 1 0 1 Data processing - register (using op1 (bit 28) from the next stage to differentiate further already)
559 * 6 0 1 1 0 Loads and stores
560 * 7 0 1 1 1 Data processing - SIMD and floating point
561 * 8 1 0 0 0 Data processing immediate
562 * 9 1 0 0 1 Data processing immediate
563 * 10 1 0 1 0 Branch, exception generation and system instructions
564 * 11 1 0 1 1 Branch, exception generation and system instructions
565 * 12 1 1 0 0 Loads and stores
566 * 13 1 1 0 1 Data processing - register (using op1 (bit 28) from the next stage to differentiate further already)
567 * 14 1 1 1 0 Loads and stores
568 * 15 1 1 1 1 Data processing - SIMD and floating point
569 */
570DIS_ARMV8_DECODE_MAP_DEFINE_BEGIN(g_ArmV8A64DecodeL0)
571 DIS_ARMV8_DECODE_MAP_ENTRY(g_aArmV8A64InsnRsvd), /* Reserved class or SME encoding (@todo). */
572 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Unallocated */
573 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /** @todo SVE */
574 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Unallocated */
575 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Load/Stores */
576 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64LogicalAddSubReg), /* Data processing (register) (see op1 in C4.1.68). */
577 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Load/Stores */
578 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Data processing (SIMD & FP) */
579 DIS_ARMV8_DECODE_MAP_ENTRY(g_aArmV8A64InsnDataProcessingImm), /* Data processing (immediate). */
580 DIS_ARMV8_DECODE_MAP_ENTRY(g_aArmV8A64InsnDataProcessingImm), /* Data processing (immediate). */
581 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64BrExcpSys), /* Branches / Exception generation and system instructions. */
582 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64BrExcpSys), /* Branches / Exception generation and system instructions. */
583 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64LdSt), /* Load/Stores. */
584 DIS_ARMV8_DECODE_MAP_ENTRY(g_ArmV8A64DataProcReg), /* Data processing (register) (see op1 in C4.1.68). */
585 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY, /* Load/Stores. */
586 DIS_ARMV8_DECODE_MAP_INVALID_ENTRY /* Data processing (SIMD & FP). */
587DIS_ARMV8_DECODE_MAP_DEFINE_END_NON_STATIC(g_ArmV8A64DecodeL0, 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