blob: 2ccbe439896ed44b68c150541e37c77eb42a66c3 [file] [log] [blame]
sewardj2a9ad022004-11-25 02:46:58 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin guest_arm_defs.h ---*/
sewardj2a9ad022004-11-25 02:46:58 +00004/*---------------------------------------------------------------*/
sewardj2a9ad022004-11-25 02:46:58 +00005/*
sewardj752f9062010-05-03 21:38:49 +00006 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
sewardj2a9ad022004-11-25 02:46:58 +00008
Elliott Hughesed398002017-06-21 14:41:24 -07009 Copyright (C) 2004-2017 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000010 info@open-works.net
sewardj2a9ad022004-11-25 02:46:58 +000011
sewardj752f9062010-05-03 21:38:49 +000012 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.
sewardj2a9ad022004-11-25 02:46:58 +000016
sewardj752f9062010-05-03 21:38:49 +000017 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
sewardj7bd6ffe2005-08-03 16:07:36 +000025 02110-1301, USA.
26
sewardj752f9062010-05-03 21:38:49 +000027 The GNU General Public License is contained in the file COPYING.
sewardj2a9ad022004-11-25 02:46:58 +000028*/
29
30/* Only to be used within the guest-arm directory. */
31
sewardjcef7d3e2009-07-02 12:21:59 +000032#ifndef __VEX_GUEST_ARM_DEFS_H
33#define __VEX_GUEST_ARM_DEFS_H
sewardj2a9ad022004-11-25 02:46:58 +000034
florian58a637b2012-09-30 20:30:17 +000035#include "libvex_basictypes.h"
36#include "guest_generic_bb_to_IR.h" // DisResult
sewardj2a9ad022004-11-25 02:46:58 +000037
38/*---------------------------------------------------------*/
39/*--- arm to IR conversion ---*/
40/*---------------------------------------------------------*/
41
sewardj6c299f32009-12-31 18:00:12 +000042/* Convert one ARM insn to IR. See the type DisOneInstrFn in
Elliott Hughesed398002017-06-21 14:41:24 -070043 geust_generic_ bb_to_IR.h. */
sewardj2a9ad022004-11-25 02:46:58 +000044extern
sewardj6c299f32009-12-31 18:00:12 +000045DisResult disInstr_ARM ( IRSB* irbb,
florianbeac5302014-12-31 12:09:38 +000046 Bool (*resteerOkFn) ( void*, Addr ),
sewardj984d9b12010-01-15 10:53:21 +000047 Bool resteerCisOk,
sewardj6c299f32009-12-31 18:00:12 +000048 void* callback_opaque,
florian8462d112014-09-24 15:18:09 +000049 const UChar* guest_code,
sewardj6c299f32009-12-31 18:00:12 +000050 Long delta,
floriand4cc0de2015-01-02 11:44:12 +000051 Addr guest_IP,
sewardj6c299f32009-12-31 18:00:12 +000052 VexArch guest_arch,
floriancacba8e2014-12-15 18:58:07 +000053 const VexArchInfo* archinfo,
54 const VexAbiInfo* abiinfo,
sewardj9b769162014-07-24 12:42:03 +000055 VexEndness host_endness,
sewardj442e51a2012-12-06 18:08:04 +000056 Bool sigill_diag );
sewardj2a9ad022004-11-25 02:46:58 +000057
58/* Used by the optimiser to specialise calls to helpers. */
59extern
florian1ff47562012-10-21 02:09:51 +000060IRExpr* guest_arm_spechelper ( const HChar* function_name,
sewardjd2664472010-08-22 12:44:20 +000061 IRExpr** args,
62 IRStmt** precedingStmts,
63 Int n_precedingStmts );
sewardj2a9ad022004-11-25 02:46:58 +000064
65/* Describes to the optimser which part of the guest state require
66 precise memory exceptions. This is logically part of the guest
67 state description. */
68extern
sewardjca2c3c72015-02-05 12:53:20 +000069Bool guest_arm_state_requires_precise_mem_exns ( Int, Int,
70 VexRegisterUpdates );
sewardj2a9ad022004-11-25 02:46:58 +000071
72extern
73VexGuestLayout armGuest_layout;
74
75
76/*---------------------------------------------------------*/
77/*--- arm guest helpers ---*/
78/*---------------------------------------------------------*/
79
80/* --- CLEAN HELPERS --- */
81
sewardj6c299f32009-12-31 18:00:12 +000082/* Calculate NZCV from the supplied thunk components, in the positions
83 they appear in the CPSR, viz bits 31:28 for N Z V C respectively.
84 Returned bits 27:0 are zero. */
85extern
86UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
87 UInt cc_dep2, UInt cc_dep3 );
sewardj2a9ad022004-11-25 02:46:58 +000088
sewardj6c299f32009-12-31 18:00:12 +000089/* Calculate the C flag from the thunk components, in the lowest bit
90 of the word (bit 0). */
91extern
92UInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1,
93 UInt cc_dep2, UInt cc_dep3 );
94
95/* Calculate the V flag from the thunk components, in the lowest bit
96 of the word (bit 0). */
97extern
98UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
99 UInt cc_dep2, UInt cc_dep3 );
100
101/* Calculate the specified condition from the thunk components, in the
102 lowest bit of the word (bit 0). */
103extern
104UInt armg_calculate_condition ( UInt cond_n_op /* ARMCondcode << 4 | cc_op */,
105 UInt cc_dep1,
106 UInt cc_dep2, UInt cc_dep3 );
sewardj2a9ad022004-11-25 02:46:58 +0000107
sewardjd2664472010-08-22 12:44:20 +0000108/* Calculate the QC flag from the thunk components, in the lowest bit
109 of the word (bit 0). */
110extern
111UInt armg_calculate_flag_qc ( UInt resL1, UInt resL2,
112 UInt resR1, UInt resR2 );
113
Elliott Hughesa0664b92017-04-18 17:46:52 -0700114/* --- DIRTY HELPERS --- */
115
116/* Confusingly, for the AES insns, the 32-bit ARM docs refers to the
117 one-and-only source register as 'm' whereas the 64-bit docs refer to
118 it as 'n'. We sidestep that here by just calling it 'arg32_*'. */
119
120extern
121void armg_dirtyhelper_AESE (
122 /*OUT*/V128* res,
123 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
124 );
125
126extern
127void armg_dirtyhelper_AESD (
128 /*OUT*/V128* res,
129 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
130 );
131
132extern
133void armg_dirtyhelper_AESMC (
134 /*OUT*/V128* res,
135 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
136 );
137
138extern
139void armg_dirtyhelper_AESIMC (
140 /*OUT*/V128* res,
141 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
142 );
143
144extern
145void armg_dirtyhelper_SHA1C (
146 /*OUT*/V128* res,
147 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
148 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
149 UInt argM3, UInt argM2, UInt argM1, UInt argM0
150 );
151
152extern
153void armg_dirtyhelper_SHA1P (
154 /*OUT*/V128* res,
155 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
156 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
157 UInt argM3, UInt argM2, UInt argM1, UInt argM0
158 );
159
160extern
161void armg_dirtyhelper_SHA1M (
162 /*OUT*/V128* res,
163 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
164 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
165 UInt argM3, UInt argM2, UInt argM1, UInt argM0
166 );
167
168extern
169void armg_dirtyhelper_SHA1SU0 (
170 /*OUT*/V128* res,
171 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
172 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
173 UInt argM3, UInt argM2, UInt argM1, UInt argM0
174 );
175
176extern
177void armg_dirtyhelper_SHA256H (
178 /*OUT*/V128* res,
179 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
180 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
181 UInt argM3, UInt argM2, UInt argM1, UInt argM0
182 );
183
184extern
185void armg_dirtyhelper_SHA256H2 (
186 /*OUT*/V128* res,
187 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
188 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
189 UInt argM3, UInt argM2, UInt argM1, UInt argM0
190 );
191
192extern
193void armg_dirtyhelper_SHA256SU1 (
194 /*OUT*/V128* res,
195 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
196 UInt argN3, UInt argN2, UInt argN1, UInt argN0,
197 UInt argM3, UInt argM2, UInt argM1, UInt argM0
198 );
199
200extern
201void armg_dirtyhelper_SHA1SU1 (
202 /*OUT*/V128* res,
203 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
204 UInt argM3, UInt argM2, UInt argM1, UInt argM0
205 );
206
207extern
208void armg_dirtyhelper_SHA256SU0 (
209 /*OUT*/V128* res,
210 UInt argD3, UInt argD2, UInt argD1, UInt argD0,
211 UInt argM3, UInt argM2, UInt argM1, UInt argM0
212 );
213
214extern
215void armg_dirtyhelper_SHA1H (
216 /*OUT*/V128* res,
217 UInt argM3, UInt argM2, UInt argM1, UInt argM0
218 );
219
220extern
221void armg_dirtyhelper_VMULLP64 (
222 /*OUT*/V128* res,
223 UInt argN1, UInt argN0, UInt argM1, UInt argM0
224 );
225
sewardj2a9ad022004-11-25 02:46:58 +0000226
227/*---------------------------------------------------------*/
228/*--- Condition code stuff ---*/
229/*---------------------------------------------------------*/
230
231/* Flags masks. Defines positions of flags bits in the CPSR. */
232#define ARMG_CC_SHIFT_N 31
233#define ARMG_CC_SHIFT_Z 30
234#define ARMG_CC_SHIFT_C 29
235#define ARMG_CC_SHIFT_V 28
sewardjd2664472010-08-22 12:44:20 +0000236#define ARMG_CC_SHIFT_Q 27
sewardj2a9ad022004-11-25 02:46:58 +0000237
238#define ARMG_CC_MASK_N (1 << ARMG_CC_SHIFT_N)
239#define ARMG_CC_MASK_Z (1 << ARMG_CC_SHIFT_Z)
sewardj2a9ad022004-11-25 02:46:58 +0000240#define ARMG_CC_MASK_C (1 << ARMG_CC_SHIFT_C)
sewardj6c299f32009-12-31 18:00:12 +0000241#define ARMG_CC_MASK_V (1 << ARMG_CC_SHIFT_V)
sewardjd2664472010-08-22 12:44:20 +0000242#define ARMG_CC_MASK_Q (1 << ARMG_CC_SHIFT_Q)
sewardj2a9ad022004-11-25 02:46:58 +0000243
sewardj6c299f32009-12-31 18:00:12 +0000244/* Flag thunk descriptors. A four-word thunk is used to record
sewardjd2664472010-08-22 12:44:20 +0000245 details of the most recent flag-setting operation, so NZCV can
sewardj2a9ad022004-11-25 02:46:58 +0000246 be computed later if needed.
247
sewardj6c299f32009-12-31 18:00:12 +0000248 The four words are:
sewardj2a9ad022004-11-25 02:46:58 +0000249
250 CC_OP, which describes the operation.
251
sewardj6c299f32009-12-31 18:00:12 +0000252 CC_DEP1, CC_DEP2, CC_DEP3. These are arguments to the
253 operation. We want set up the mcx_masks in flag helper calls
254 involving these fields so that Memcheck "believes" that the
255 resulting flags are data-dependent on both CC_DEP1 and
256 CC_DEP2. Hence the name DEP.
sewardj2a9ad022004-11-25 02:46:58 +0000257
258 When building the thunk, it is always necessary to write words into
sewardj6c299f32009-12-31 18:00:12 +0000259 CC_DEP1/2/3, even if those args are not used given the
sewardj2a9ad022004-11-25 02:46:58 +0000260 CC_OP field. This is important because otherwise Memcheck could
261 give false positives as it does not understand the relationship
sewardj6c299f32009-12-31 18:00:12 +0000262 between the CC_OP field and CC_DEP1/2/3, and so believes
263 that the definedness of the stored flags always depends on
264 all 3 DEP values.
sewardj2a9ad022004-11-25 02:46:58 +0000265
sewardjbb8b3942011-05-01 18:47:10 +0000266 Fields carrying only 1 or 2 bits of useful information (old_C,
267 shifter_co, old_V, oldC:oldV) must have their top 31 or 30 bits
268 (respectively) zero. The text "31x0:" or "30x0:" denotes this.
269
sewardj2a9ad022004-11-25 02:46:58 +0000270 A summary of the field usages is:
sewardj2a9ad022004-11-25 02:46:58 +0000271
sewardj6c299f32009-12-31 18:00:12 +0000272 OP DEP1 DEP2 DEP3
273 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sewardj2a9ad022004-11-25 02:46:58 +0000274
sewardjda9a9f52012-04-20 22:32:34 +0000275 OP_COPY curr_NZCV:28x0 unused unused
sewardj6c299f32009-12-31 18:00:12 +0000276 OP_ADD argL argR unused
277 OP_SUB argL argR unused
sewardjbb8b3942011-05-01 18:47:10 +0000278 OP_ADC argL argR 31x0:old_C
279 OP_SBB argL argR 31x0:old_C
280 OP_LOGIC result 31x0:shifter_co 31x0:old_V
281 OP_MUL result unused 30x0:old_C:old_V
282 OP_MULL resLO32 resHI32 30x0:old_C:old_V
sewardj2a9ad022004-11-25 02:46:58 +0000283*/
sewardj2a9ad022004-11-25 02:46:58 +0000284
sewardj6c299f32009-12-31 18:00:12 +0000285enum {
286 ARMG_CC_OP_COPY=0, /* DEP1 = NZCV in 31:28, DEP2 = 0, DEP3 = 0
287 just copy DEP1 to output */
288
289 ARMG_CC_OP_ADD, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
290 DEP3 = 0 */
291
292 ARMG_CC_OP_SUB, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
293 DEP3 = 0 */
294
295 ARMG_CC_OP_ADC, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
296 DEP3 = oldC (in LSB) */
297
298 ARMG_CC_OP_SBB, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
299 DEP3 = oldC (in LSB) */
300
301 ARMG_CC_OP_LOGIC, /* DEP1 = result, DEP2 = shifter_carry_out (in LSB),
302 DEP3 = old V flag (in LSB) */
303
304 ARMG_CC_OP_MUL, /* DEP1 = result, DEP2 = 0, DEP3 = oldC:old_V
305 (in bits 1:0) */
306
307 ARMG_CC_OP_MULL, /* DEP1 = resLO32, DEP2 = resHI32, DEP3 = oldC:old_V
308 (in bits 1:0) */
309
cerionb85e8bb2005-02-16 08:54:33 +0000310 ARMG_CC_OP_NUMBER
sewardj2a9ad022004-11-25 02:46:58 +0000311};
312
sewardj6c299f32009-12-31 18:00:12 +0000313/* XXXX because of the calling conventions for
314 armg_calculate_condition, all this OP values MUST be in the range
315 0 .. 15 only (viz, 4-bits). */
sewardj2a9ad022004-11-25 02:46:58 +0000316
317
318
319/* Defines conditions which we can ask for (ARM ARM 2e page A3-6) */
320
321typedef
322 enum {
sewardj6c299f32009-12-31 18:00:12 +0000323 ARMCondEQ = 0, /* equal : Z=1 */
324 ARMCondNE = 1, /* not equal : Z=0 */
sewardj2a9ad022004-11-25 02:46:58 +0000325
sewardj6c299f32009-12-31 18:00:12 +0000326 ARMCondHS = 2, /* >=u (higher or same) : C=1 */
327 ARMCondLO = 3, /* <u (lower) : C=0 */
sewardj2a9ad022004-11-25 02:46:58 +0000328
sewardj6c299f32009-12-31 18:00:12 +0000329 ARMCondMI = 4, /* minus (negative) : N=1 */
330 ARMCondPL = 5, /* plus (zero or +ve) : N=0 */
sewardj2a9ad022004-11-25 02:46:58 +0000331
sewardj6c299f32009-12-31 18:00:12 +0000332 ARMCondVS = 6, /* overflow : V=1 */
333 ARMCondVC = 7, /* no overflow : V=0 */
sewardj2a9ad022004-11-25 02:46:58 +0000334
sewardj6c299f32009-12-31 18:00:12 +0000335 ARMCondHI = 8, /* >u (higher) : C=1 && Z=0 */
336 ARMCondLS = 9, /* <=u (lower or same) : C=0 || Z=1 */
sewardj2a9ad022004-11-25 02:46:58 +0000337
sewardj6c299f32009-12-31 18:00:12 +0000338 ARMCondGE = 10, /* >=s (signed greater or equal) : N=V */
339 ARMCondLT = 11, /* <s (signed less than) : N!=V */
sewardj2a9ad022004-11-25 02:46:58 +0000340
sewardj6c299f32009-12-31 18:00:12 +0000341 ARMCondGT = 12, /* >s (signed greater) : Z=0 && N=V */
342 ARMCondLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
sewardj2a9ad022004-11-25 02:46:58 +0000343
sewardj6c299f32009-12-31 18:00:12 +0000344 ARMCondAL = 14, /* always (unconditional) : 1 */
345 ARMCondNV = 15 /* never (unconditional): : 0 */
346 /* NB: ARM have deprecated the use of the NV condition code.
347 You are now supposed to use MOV R0,R0 as a noop rather than
348 MOVNV R0,R0 as was previously recommended. Future processors
349 may have the NV condition code reused to do other things. */
sewardj2a9ad022004-11-25 02:46:58 +0000350 }
351 ARMCondcode;
352
sewardjcef7d3e2009-07-02 12:21:59 +0000353#endif /* ndef __VEX_GUEST_ARM_DEFS_H */
sewardj2a9ad022004-11-25 02:46:58 +0000354
355/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000356/*--- end guest_arm_defs.h ---*/
sewardj2a9ad022004-11-25 02:46:58 +0000357/*---------------------------------------------------------------*/