guest_arm_defs.h revision e739ac0589b4fb43561f801c4faba8c1b89f8680
1
2/*---------------------------------------------------------------*/
3/*--- begin                                  guest_arm_defs.h ---*/
4/*---------------------------------------------------------------*/
5/*
6   This file is part of Valgrind, a dynamic binary instrumentation
7   framework.
8
9   Copyright (C) 2004-2010 OpenWorks LLP
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/* Only to be used within the guest-arm directory. */
31
32#ifndef __VEX_GUEST_ARM_DEFS_H
33#define __VEX_GUEST_ARM_DEFS_H
34
35
36/*---------------------------------------------------------*/
37/*--- arm to IR conversion                              ---*/
38/*---------------------------------------------------------*/
39
40/* Convert one ARM insn to IR.  See the type DisOneInstrFn in
41   bb_to_IR.h. */
42extern
43DisResult disInstr_ARM ( IRSB*        irbb,
44                         Bool         put_IP,
45                         Bool         (*resteerOkFn) ( void*, Addr64 ),
46                         Bool         resteerCisOk,
47                         void*        callback_opaque,
48                         UChar*       guest_code,
49                         Long         delta,
50                         Addr64       guest_IP,
51                         VexArch      guest_arch,
52                         VexArchInfo* archinfo,
53                         VexAbiInfo*  abiinfo,
54                         Bool         host_bigendian );
55
56/* Used by the optimiser to specialise calls to helpers. */
57extern
58IRExpr* guest_arm_spechelper ( 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_arm_state_requires_precise_mem_exns ( Int, Int );
68
69extern
70VexGuestLayout armGuest_layout;
71
72
73/*---------------------------------------------------------*/
74/*--- arm 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 V C respectively.
81   Returned bits 27:0 are zero. */
82extern
83UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
84                                 UInt cc_dep2, UInt cc_dep3 );
85
86/* Calculate the C flag from the thunk components, in the lowest bit
87   of the word (bit 0). */
88extern
89UInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1,
90                             UInt cc_dep2, UInt cc_dep3 );
91
92/* Calculate the V flag from the thunk components, in the lowest bit
93   of the word (bit 0). */
94extern
95UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
96                             UInt cc_dep2, UInt cc_dep3 );
97
98/* Calculate the specified condition from the thunk components, in the
99   lowest bit of the word (bit 0). */
100extern
101UInt armg_calculate_condition ( UInt cond_n_op /* ARMCondcode << 4 | cc_op */,
102                                UInt cc_dep1,
103                                UInt cc_dep2, UInt cc_dep3 );
104
105/* Calculate the QC flag from the thunk components, in the lowest bit
106   of the word (bit 0). */
107extern
108UInt armg_calculate_flag_qc ( UInt resL1, UInt resL2,
109                              UInt resR1, UInt resR2 );
110
111
112/*---------------------------------------------------------*/
113/*--- Condition code stuff                              ---*/
114/*---------------------------------------------------------*/
115
116/* Flags masks.  Defines positions of flags bits in the CPSR. */
117#define ARMG_CC_SHIFT_N  31
118#define ARMG_CC_SHIFT_Z  30
119#define ARMG_CC_SHIFT_C  29
120#define ARMG_CC_SHIFT_V  28
121#define ARMG_CC_SHIFT_Q  27
122
123#define ARMG_CC_MASK_N    (1 << ARMG_CC_SHIFT_N)
124#define ARMG_CC_MASK_Z    (1 << ARMG_CC_SHIFT_Z)
125#define ARMG_CC_MASK_C    (1 << ARMG_CC_SHIFT_C)
126#define ARMG_CC_MASK_V    (1 << ARMG_CC_SHIFT_V)
127#define ARMG_CC_MASK_Q    (1 << ARMG_CC_SHIFT_Q)
128
129/* Flag thunk descriptors.  A four-word thunk is used to record
130   details of the most recent flag-setting operation, so NZCV can
131   be computed later if needed.
132
133   The four words are:
134
135      CC_OP, which describes the operation.
136
137      CC_DEP1, CC_DEP2, CC_DEP3.  These are arguments to the
138         operation.  We want set up the mcx_masks in flag helper calls
139         involving these fields so that Memcheck "believes" that the
140         resulting flags are data-dependent on both CC_DEP1 and
141         CC_DEP2.  Hence the name DEP.
142
143   When building the thunk, it is always necessary to write words into
144   CC_DEP1/2/3, even if those args are not used given the
145   CC_OP field.  This is important because otherwise Memcheck could
146   give false positives as it does not understand the relationship
147   between the CC_OP field and CC_DEP1/2/3, and so believes
148   that the definedness of the stored flags always depends on
149   all 3 DEP values.
150
151   A summary of the field usages is:
152
153   OP                DEP1              DEP2              DEP3
154   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155
156   OP_COPY           current NZCV      unused            unused
157   OP_ADD            argL              argR              unused
158   OP_SUB            argL              argR              unused
159   OP_ADC            argL              argR              old_C
160   OP_SBB            argL              argR              old_C
161   OP_LOGIC          result            shifter_co        old_V
162   OP_MUL            result            unused            old_C:old_V
163   OP_MULL           resLO32           resHI32           old_C:old_V
164*/
165
166enum {
167   ARMG_CC_OP_COPY=0,  /* DEP1 = NZCV in 31:28, DEP2 = 0, DEP3 = 0
168                          just copy DEP1 to output */
169
170   ARMG_CC_OP_ADD,     /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
171                          DEP3 = 0 */
172
173   ARMG_CC_OP_SUB,     /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
174                          DEP3 = 0 */
175
176   ARMG_CC_OP_ADC,     /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
177                          DEP3 = oldC (in LSB) */
178
179   ARMG_CC_OP_SBB,     /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
180                          DEP3 = oldC (in LSB) */
181
182   ARMG_CC_OP_LOGIC,   /* DEP1 = result, DEP2 = shifter_carry_out (in LSB),
183                          DEP3 = old V flag (in LSB) */
184
185   ARMG_CC_OP_MUL,     /* DEP1 = result, DEP2 = 0, DEP3 = oldC:old_V
186                          (in bits 1:0) */
187
188   ARMG_CC_OP_MULL,    /* DEP1 = resLO32, DEP2 = resHI32, DEP3 = oldC:old_V
189                          (in bits 1:0) */
190
191   ARMG_CC_OP_NUMBER
192};
193
194/* XXXX because of the calling conventions for
195   armg_calculate_condition, all this OP values MUST be in the range
196   0 .. 15 only (viz, 4-bits). */
197
198
199
200/* Defines conditions which we can ask for (ARM ARM 2e page A3-6) */
201
202typedef
203   enum {
204      ARMCondEQ     = 0,  /* equal                         : Z=1 */
205      ARMCondNE     = 1,  /* not equal                     : Z=0 */
206
207      ARMCondHS     = 2,  /* >=u (higher or same)          : C=1 */
208      ARMCondLO     = 3,  /* <u  (lower)                   : C=0 */
209
210      ARMCondMI     = 4,  /* minus (negative)              : N=1 */
211      ARMCondPL     = 5,  /* plus (zero or +ve)            : N=0 */
212
213      ARMCondVS     = 6,  /* overflow                      : V=1 */
214      ARMCondVC     = 7,  /* no overflow                   : V=0 */
215
216      ARMCondHI     = 8,  /* >u   (higher)                 : C=1 && Z=0 */
217      ARMCondLS     = 9,  /* <=u  (lower or same)          : C=0 || Z=1 */
218
219      ARMCondGE     = 10, /* >=s (signed greater or equal) : N=V */
220      ARMCondLT     = 11, /* <s  (signed less than)        : N!=V */
221
222      ARMCondGT     = 12, /* >s  (signed greater)          : Z=0 && N=V */
223      ARMCondLE     = 13, /* <=s (signed less or equal)    : Z=1 || N!=V */
224
225      ARMCondAL     = 14, /* always (unconditional)        : 1 */
226      ARMCondNV     = 15  /* never (unconditional):        : 0 */
227      /* NB: ARM have deprecated the use of the NV condition code.
228         You are now supposed to use MOV R0,R0 as a noop rather than
229         MOVNV R0,R0 as was previously recommended.  Future processors
230         may have the NV condition code reused to do other things.  */
231   }
232   ARMCondcode;
233
234#endif /* ndef __VEX_GUEST_ARM_DEFS_H */
235
236/*---------------------------------------------------------------*/
237/*--- end                                    guest_arm_defs.h ---*/
238/*---------------------------------------------------------------*/
239