blob: 5656786cccb3568b42aedaf858a4e35196f0efe6 [file] [log] [blame]
sewardjbbcf1882014-01-12 12:49:10 +00001
2/*---------------------------------------------------------------*/
3/*--- begin guest_arm64_defs.h ---*/
4/*---------------------------------------------------------------*/
5/*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
8
9 Copyright (C) 2013-2013 OpenWorks
10 info@open-works.net
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 as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
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, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 02110-1301, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30#ifndef __VEX_GUEST_ARM64_DEFS_H
31#define __VEX_GUEST_ARM64_DEFS_H
32
33#include "libvex_basictypes.h"
34#include "guest_generic_bb_to_IR.h" // DisResult
35
36/*---------------------------------------------------------*/
37/*--- arm64 to IR conversion ---*/
38/*---------------------------------------------------------*/
39
40/* Convert one ARM64 insn to IR. See the type DisOneInstrFn in
41 bb_to_IR.h. */
42extern
43DisResult disInstr_ARM64 ( IRSB* irbb,
44 Bool (*resteerOkFn) ( void*, Addr64 ),
45 Bool resteerCisOk,
46 void* callback_opaque,
florian8462d112014-09-24 15:18:09 +000047 const UChar* guest_code,
sewardjbbcf1882014-01-12 12:49:10 +000048 Long delta,
49 Addr64 guest_IP,
50 VexArch guest_arch,
51 VexArchInfo* archinfo,
52 VexAbiInfo* abiinfo,
sewardj9b769162014-07-24 12:42:03 +000053 VexEndness host_endness,
sewardjbbcf1882014-01-12 12:49:10 +000054 Bool sigill_diag );
55
56/* Used by the optimiser to specialise calls to helpers. */
57extern
58IRExpr* guest_arm64_spechelper ( const HChar* function_name,
59 IRExpr** args,
60 IRStmt** precedingStmts,
61 Int n_precedingStmts );
62
63/* Describes to the optimser which part of the guest state require
64 precise memory exceptions. This is logically part of the guest
65 state description. */
66extern
67Bool guest_arm64_state_requires_precise_mem_exns ( Int, Int );
68
69extern
70VexGuestLayout arm64Guest_layout;
71
72
73/*---------------------------------------------------------*/
74/*--- arm64 guest helpers ---*/
75/*---------------------------------------------------------*/
76
77/* --- CLEAN HELPERS --- */
78
79/* Calculate NZCV from the supplied thunk components, in the positions
80 they appear in the CPSR, viz bits 31:28 for N Z C V respectively.
81 Returned bits 63:32 and 27:0 are zero. */
82extern
83ULong arm64g_calculate_flags_nzcv ( ULong cc_op, ULong cc_dep1,
84 ULong cc_dep2, ULong cc_dep3 );
85
sewardjdee30502014-06-04 13:09:44 +000086/* Calculate the C flag from the thunk components, in the lowest bit
87 of the word (bit 0). */
88extern
89ULong arm64g_calculate_flag_c ( ULong cc_op, ULong cc_dep1,
90 ULong cc_dep2, ULong cc_dep3 );
91
sewardjbbcf1882014-01-12 12:49:10 +000092//ZZ /* Calculate the V flag from the thunk components, in the lowest bit
93//ZZ of the word (bit 0). */
94//ZZ extern
95//ZZ UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
96//ZZ UInt cc_dep2, UInt cc_dep3 );
97//ZZ
98/* Calculate the specified condition from the thunk components, in the
99 lowest bit of the word (bit 0). */
100extern
101ULong arm64g_calculate_condition ( /* ARM64Condcode << 4 | cc_op */
102 ULong cond_n_op ,
103 ULong cc_dep1,
104 ULong cc_dep2, ULong cc_dep3 );
105
106//ZZ /* Calculate the QC flag from the thunk components, in the lowest bit
107//ZZ of the word (bit 0). */
108//ZZ extern
109//ZZ UInt armg_calculate_flag_qc ( UInt resL1, UInt resL2,
110//ZZ UInt resR1, UInt resR2 );
111
112
sewardj6eb5ef82014-07-14 20:39:23 +0000113/* --- DIRTY HELPERS --- */
114
115extern ULong arm64g_dirtyhelper_MRS_CNTVCT_EL0 ( void );
116
117
sewardjbbcf1882014-01-12 12:49:10 +0000118/*---------------------------------------------------------*/
119/*--- Condition code stuff ---*/
120/*---------------------------------------------------------*/
121
122/* Flag masks. Defines positions of flag bits in the NZCV
123 register. */
124#define ARM64G_CC_SHIFT_N 31
125#define ARM64G_CC_SHIFT_Z 30
126#define ARM64G_CC_SHIFT_C 29
127#define ARM64G_CC_SHIFT_V 28
128//ZZ #define ARMG_CC_SHIFT_Q 27
129//ZZ
130//ZZ #define ARMG_CC_MASK_N (1 << ARMG_CC_SHIFT_N)
131//ZZ #define ARMG_CC_MASK_Z (1 << ARMG_CC_SHIFT_Z)
132//ZZ #define ARMG_CC_MASK_C (1 << ARMG_CC_SHIFT_C)
133//ZZ #define ARMG_CC_MASK_V (1 << ARMG_CC_SHIFT_V)
134//ZZ #define ARMG_CC_MASK_Q (1 << ARMG_CC_SHIFT_Q)
135
136/* Flag thunk descriptors. A four-word thunk is used to record
137 details of the most recent flag-setting operation, so NZCV can
138 be computed later if needed.
139
140 The four words are:
141
142 CC_OP, which describes the operation.
143
144 CC_DEP1, CC_DEP2, CC_NDEP. These are arguments to the
145 operation. We want set up the mcx_masks in flag helper calls
146 involving these fields so that Memcheck "believes" that the
147 resulting flags are data-dependent on both CC_DEP1 and
148 CC_DEP2. Hence the name DEP.
149
150 When building the thunk, it is always necessary to write words into
151 CC_DEP1/2 and NDEP, even if those args are not used given the CC_OP
152 field. This is important because otherwise Memcheck could give
153 false positives as it does not understand the relationship between
154 the CC_OP field and CC_DEP1/2/NDEP, and so believes that the
155 definedness of the stored flags always depends on all 3 DEP values.
156
157 A summary of the field usages is:
158
159 OP DEP1 DEP2 DEP3
160 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161
162 OP_COPY curr_NZCV:28x0 unused unused
163 OP_ADD32 argL argR unused
164 OP_ADD64 argL argR unused
165 OP_SUB32 argL argR unused
166 OP_SUB64 argL argR unused
sewardjdee30502014-06-04 13:09:44 +0000167 OP_ADC32 argL argR 63x0:old_C
168 OP_ADC64 argL argR 63x0:old_C
169 OP_SBC32 argL argR 63x0:old_C
170 OP_SBC64 argL argR 63x0:old_C
sewardjbbcf1882014-01-12 12:49:10 +0000171 OP_LOGIC32 result unused unused
172 OP_LOGIC64 result unused unused
173//ZZ OP_MUL result unused 30x0:old_C:old_V
174//ZZ OP_MULL resLO32 resHI32 30x0:old_C:old_V
175//ZZ */
176
177enum {
178 ARM64G_CC_OP_COPY=0, /* DEP1 = NZCV in 31:28, DEP2 = 0, DEP3 = 0
179 just copy DEP1 to output */
180
181 ARM64G_CC_OP_ADD32, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
182 DEP3 = 0 */
183
184 ARM64G_CC_OP_ADD64, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
185 DEP3 = 0 */
186
187 ARM64G_CC_OP_SUB32, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
188 DEP3 = 0 */
189
190 ARM64G_CC_OP_SUB64, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
191 DEP3 = 0 */
192
sewardjdee30502014-06-04 13:09:44 +0000193 ARM64G_CC_OP_ADC32, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
194 DEP3 = oldC (in LSB) */
195
196 ARM64G_CC_OP_ADC64, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
197 DEP3 = oldC (in LSB) */
198
199 ARM64G_CC_OP_SBC32, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
200 DEP3 = oldC (in LSB) */
201
202 ARM64G_CC_OP_SBC64, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
203 DEP3 = oldC (in LSB) */
sewardjbbcf1882014-01-12 12:49:10 +0000204
205 ARM64G_CC_OP_LOGIC32, /* DEP1 = result, DEP2 = 0, DEP3 = 0 */
206 ARM64G_CC_OP_LOGIC64, /* DEP1 = result, DEP2 = 0, DEP3 = 0 */
207
208//ZZ ARMG_CC_OP_MUL, /* DEP1 = result, DEP2 = 0, DEP3 = oldC:old_V
209//ZZ (in bits 1:0) */
210//ZZ
211//ZZ ARMG_CC_OP_MULL, /* DEP1 = resLO32, DEP2 = resHI32, DEP3 = oldC:old_V
212//ZZ (in bits 1:0) */
213
214 ARM64G_CC_OP_NUMBER
215};
216
217/* XXXX because of the calling conventions for
218 arm64g_calculate_condition, all these OP values MUST be in the range
219 0 .. 15 only (viz, 4-bits). */
220
221
222
223/* Defines conditions which we can ask for */
224
225typedef
226 enum {
227 ARM64CondEQ = 0, /* equal : Z=1 */
228 ARM64CondNE = 1, /* not equal : Z=0 */
229
230 ARM64CondCS = 2, /* >=u (higher or same) (aka HS) : C=1 */
231 ARM64CondCC = 3, /* <u (lower) (aka LO) : C=0 */
232
233 ARM64CondMI = 4, /* minus (negative) : N=1 */
234 ARM64CondPL = 5, /* plus (zero or +ve) : N=0 */
235
236 ARM64CondVS = 6, /* overflow : V=1 */
237 ARM64CondVC = 7, /* no overflow : V=0 */
238
239 ARM64CondHI = 8, /* >u (higher) : C=1 && Z=0 */
240 ARM64CondLS = 9, /* <=u (lower or same) : C=0 || Z=1 */
241
242 ARM64CondGE = 10, /* >=s (signed greater or equal) : N=V */
243 ARM64CondLT = 11, /* <s (signed less than) : N!=V */
244
245 ARM64CondGT = 12, /* >s (signed greater) : Z=0 && N=V */
246 ARM64CondLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
247
248 ARM64CondAL = 14, /* always (unconditional) : 1 */
249 ARM64CondNV = 15 /* always (unconditional) : 1 */
250 }
251 ARM64Condcode;
252
253#endif /* ndef __VEX_GUEST_ARM64_DEFS_H */
254
255/*---------------------------------------------------------------*/
256/*--- end guest_arm64_defs.h ---*/
257/*---------------------------------------------------------------*/