2 /*---------------------------------------------------------------*/
3 /*--- begin guest_arm_defs.h ---*/
4 /*---------------------------------------------------------------*/
6 This file is part of Valgrind, a dynamic binary instrumentation
9 Copyright (C) 2004-2010 OpenWorks LLP
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.
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.
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
27 The GNU General Public License is contained in the file COPYING.
30 /* Only to be used within the guest-arm directory. */
32 #ifndef __VEX_GUEST_ARM_DEFS_H
33 #define __VEX_GUEST_ARM_DEFS_H
36 /*---------------------------------------------------------*/
37 /*--- arm to IR conversion ---*/
38 /*---------------------------------------------------------*/
40 /* Convert one ARM insn to IR. See the type DisOneInstrFn in
43 DisResult disInstr_ARM ( IRSB* irbb,
45 Bool (*resteerOkFn) ( void*, Addr64 ),
47 void* callback_opaque,
52 VexArchInfo* archinfo,
54 Bool host_bigendian );
56 /* Used by the optimiser to specialise calls to helpers. */
58 IRExpr* guest_arm_spechelper ( HChar* function_name,
61 /* Describes to the optimser which part of the guest state require
62 precise memory exceptions. This is logically part of the guest
65 Bool guest_arm_state_requires_precise_mem_exns ( Int, Int );
68 VexGuestLayout armGuest_layout;
71 /*---------------------------------------------------------*/
72 /*--- arm guest helpers ---*/
73 /*---------------------------------------------------------*/
75 /* --- CLEAN HELPERS --- */
77 /* Calculate NZCV from the supplied thunk components, in the positions
78 they appear in the CPSR, viz bits 31:28 for N Z V C respectively.
79 Returned bits 27:0 are zero. */
81 UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
82 UInt cc_dep2, UInt cc_dep3 );
84 /* Calculate the C flag from the thunk components, in the lowest bit
85 of the word (bit 0). */
87 UInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1,
88 UInt cc_dep2, UInt cc_dep3 );
90 /* Calculate the V flag from the thunk components, in the lowest bit
91 of the word (bit 0). */
93 UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
94 UInt cc_dep2, UInt cc_dep3 );
96 /* Calculate the specified condition from the thunk components, in the
97 lowest bit of the word (bit 0). */
99 UInt armg_calculate_condition ( UInt cond_n_op /* ARMCondcode << 4 | cc_op */,
101 UInt cc_dep2, UInt cc_dep3 );
104 /*---------------------------------------------------------*/
105 /*--- Condition code stuff ---*/
106 /*---------------------------------------------------------*/
108 /* Flags masks. Defines positions of flags bits in the CPSR. */
109 #define ARMG_CC_SHIFT_N 31
110 #define ARMG_CC_SHIFT_Z 30
111 #define ARMG_CC_SHIFT_C 29
112 #define ARMG_CC_SHIFT_V 28
114 #define ARMG_CC_MASK_N (1 << ARMG_CC_SHIFT_N)
115 #define ARMG_CC_MASK_Z (1 << ARMG_CC_SHIFT_Z)
116 #define ARMG_CC_MASK_C (1 << ARMG_CC_SHIFT_C)
117 #define ARMG_CC_MASK_V (1 << ARMG_CC_SHIFT_V)
119 /* Flag thunk descriptors. A four-word thunk is used to record
120 details of the most recent flag-setting operation, so the flags can
121 be computed later if needed.
125 CC_OP, which describes the operation.
127 CC_DEP1, CC_DEP2, CC_DEP3. These are arguments to the
128 operation. We want set up the mcx_masks in flag helper calls
129 involving these fields so that Memcheck "believes" that the
130 resulting flags are data-dependent on both CC_DEP1 and
131 CC_DEP2. Hence the name DEP.
133 When building the thunk, it is always necessary to write words into
134 CC_DEP1/2/3, even if those args are not used given the
135 CC_OP field. This is important because otherwise Memcheck could
136 give false positives as it does not understand the relationship
137 between the CC_OP field and CC_DEP1/2/3, and so believes
138 that the definedness of the stored flags always depends on
141 A summary of the field usages is:
144 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146 OP_COPY current NZCV unused unused
147 OP_ADD argL argR unused
148 OP_SUB argL argR unused
149 OP_ADC argL argR old_C
150 OP_SBB argL argR old_C
151 OP_LOGIC result shifter_co old_V
152 OP_MUL result unused old_C:old_V
153 OP_MULL resLO32 resHI32 old_C:old_V
157 ARMG_CC_OP_COPY=0, /* DEP1 = NZCV in 31:28, DEP2 = 0, DEP3 = 0
158 just copy DEP1 to output */
160 ARMG_CC_OP_ADD, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
163 ARMG_CC_OP_SUB, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
166 ARMG_CC_OP_ADC, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
167 DEP3 = oldC (in LSB) */
169 ARMG_CC_OP_SBB, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
170 DEP3 = oldC (in LSB) */
172 ARMG_CC_OP_LOGIC, /* DEP1 = result, DEP2 = shifter_carry_out (in LSB),
173 DEP3 = old V flag (in LSB) */
175 ARMG_CC_OP_MUL, /* DEP1 = result, DEP2 = 0, DEP3 = oldC:old_V
178 ARMG_CC_OP_MULL, /* DEP1 = resLO32, DEP2 = resHI32, DEP3 = oldC:old_V
184 /* XXXX because of the calling conventions for
185 armg_calculate_condition, all this OP values MUST be in the range
186 0 .. 15 only (viz, 4-bits). */
190 /* Defines conditions which we can ask for (ARM ARM 2e page A3-6) */
194 ARMCondEQ = 0, /* equal : Z=1 */
195 ARMCondNE = 1, /* not equal : Z=0 */
197 ARMCondHS = 2, /* >=u (higher or same) : C=1 */
198 ARMCondLO = 3, /* <u (lower) : C=0 */
200 ARMCondMI = 4, /* minus (negative) : N=1 */
201 ARMCondPL = 5, /* plus (zero or +ve) : N=0 */
203 ARMCondVS = 6, /* overflow : V=1 */
204 ARMCondVC = 7, /* no overflow : V=0 */
206 ARMCondHI = 8, /* >u (higher) : C=1 && Z=0 */
207 ARMCondLS = 9, /* <=u (lower or same) : C=0 || Z=1 */
209 ARMCondGE = 10, /* >=s (signed greater or equal) : N=V */
210 ARMCondLT = 11, /* <s (signed less than) : N!=V */
212 ARMCondGT = 12, /* >s (signed greater) : Z=0 && N=V */
213 ARMCondLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
215 ARMCondAL = 14, /* always (unconditional) : 1 */
216 ARMCondNV = 15 /* never (unconditional): : 0 */
217 /* NB: ARM have deprecated the use of the NV condition code.
218 You are now supposed to use MOV R0,R0 as a noop rather than
219 MOVNV R0,R0 as was previously recommended. Future processors
220 may have the NV condition code reused to do other things. */
224 #endif /* ndef __VEX_GUEST_ARM_DEFS_H */
226 /*---------------------------------------------------------------*/
227 /*--- end guest_arm_defs.h ---*/
228 /*---------------------------------------------------------------*/