guest_arm_helpers.c revision 99dd03e04a6914d90d5fee727d61d76905334bec
12a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
22a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*---------------------------------------------------------------*/
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin                               guest_arm_helpers.c ---*/
42a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*---------------------------------------------------------------*/
52a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
62a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj   framework.
92a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
1025e547391785959e81250091bf76d91ca30ef3bfsewardj   Copyright (C) 2004-2012 OpenWorks LLP
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj      info@open-works.net
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is free software; you can redistribute it and/or
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj   modify it under the terms of the GNU General Public License as
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj   published by the Free Software Foundation; either version 2 of the
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj   License, or (at your option) any later version.
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is distributed in the hope that it will be useful, but
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj   General Public License for more details.
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj   You should have received a copy of the GNU General Public License
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj   along with this program; if not, write to the Free Software
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj   The GNU General Public License is contained in the file COPYING.
292a9ad023890d3b34cf45e429df2a8ae88b419128sewardj*/
302a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
312a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "libvex_basictypes.h"
3233b024301d2311965cc68dc4cc900f3d0fdd8085florian#include "libvex_emnote.h"
332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "libvex_guest_arm.h"
342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "libvex_ir.h"
352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#include "libvex.h"
362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
37cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h"
386c46befd9eb90c1b6e739926c1fa335cba75bf46philippe#include "main_globals.h"
396c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#include "guest_generic_bb_to_IR.h"
40cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_arm_defs.h"
412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
436c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/* This file contains helper functions for arm guest code.  Calls to
446c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   these functions are generated by the back end.  These calls are of
456c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   course in the host machine code and this file will be compiled to
466c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   host machine code, so that all makes sense.
472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
482a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   Only change the signatures of these helper functions very
492a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   carefully.  If you change the signature here, you'll have to change
502a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   the parameters passed to it in the IR calls constructed by
512a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   guest-arm/toIR.c.
522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj*/
532a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
542a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
5526bc4823f4e3273aab7741edf221592a57d8d78fsewardj/* Set to 1 to get detailed profiling info about individual N, Z, C
5626bc4823f4e3273aab7741edf221592a57d8d78fsewardj   and V flag evaluation. */
5726bc4823f4e3273aab7741edf221592a57d8d78fsewardj#define PROFILE_NZCV_FLAGS 0
5826bc4823f4e3273aab7741edf221592a57d8d78fsewardj
5926bc4823f4e3273aab7741edf221592a57d8d78fsewardj#if PROFILE_NZCV_FLAGS
6026bc4823f4e3273aab7741edf221592a57d8d78fsewardj
6126bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic UInt tab_n_eval[ARMG_CC_OP_NUMBER];
6226bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic UInt tab_z_eval[ARMG_CC_OP_NUMBER];
6326bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic UInt tab_c_eval[ARMG_CC_OP_NUMBER];
6426bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic UInt tab_v_eval[ARMG_CC_OP_NUMBER];
6526bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic UInt initted = 0;
6626bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic UInt tot_evals = 0;
6726bc4823f4e3273aab7741edf221592a57d8d78fsewardj
6826bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic void initCounts ( void )
6926bc4823f4e3273aab7741edf221592a57d8d78fsewardj{
7026bc4823f4e3273aab7741edf221592a57d8d78fsewardj   UInt i;
7126bc4823f4e3273aab7741edf221592a57d8d78fsewardj   for (i = 0; i < ARMG_CC_OP_NUMBER; i++) {
7226bc4823f4e3273aab7741edf221592a57d8d78fsewardj      tab_n_eval[i] = tab_z_eval[i] = tab_c_eval[i] = tab_v_eval[i] = 0;
7326bc4823f4e3273aab7741edf221592a57d8d78fsewardj   }
7426bc4823f4e3273aab7741edf221592a57d8d78fsewardj   initted = 1;
7526bc4823f4e3273aab7741edf221592a57d8d78fsewardj}
7626bc4823f4e3273aab7741edf221592a57d8d78fsewardj
7726bc4823f4e3273aab7741edf221592a57d8d78fsewardjstatic void showCounts ( void )
7826bc4823f4e3273aab7741edf221592a57d8d78fsewardj{
7926bc4823f4e3273aab7741edf221592a57d8d78fsewardj   UInt i;
8026bc4823f4e3273aab7741edf221592a57d8d78fsewardj   vex_printf("\n                 N          Z          C          V\n");
8126bc4823f4e3273aab7741edf221592a57d8d78fsewardj   vex_printf(  "---------------------------------------------------\n");
8226bc4823f4e3273aab7741edf221592a57d8d78fsewardj   for (i = 0; i < ARMG_CC_OP_NUMBER; i++) {
8326bc4823f4e3273aab7741edf221592a57d8d78fsewardj      vex_printf("CC_OP=%d  %9d  %9d  %9d  %9d\n",
8426bc4823f4e3273aab7741edf221592a57d8d78fsewardj                 i,
8526bc4823f4e3273aab7741edf221592a57d8d78fsewardj                 tab_n_eval[i], tab_z_eval[i],
8626bc4823f4e3273aab7741edf221592a57d8d78fsewardj                 tab_c_eval[i], tab_v_eval[i] );
8726bc4823f4e3273aab7741edf221592a57d8d78fsewardj    }
8826bc4823f4e3273aab7741edf221592a57d8d78fsewardj}
8926bc4823f4e3273aab7741edf221592a57d8d78fsewardj
9026bc4823f4e3273aab7741edf221592a57d8d78fsewardj#define NOTE_N_EVAL(_cc_op) NOTE_EVAL(_cc_op, tab_n_eval)
9126bc4823f4e3273aab7741edf221592a57d8d78fsewardj#define NOTE_Z_EVAL(_cc_op) NOTE_EVAL(_cc_op, tab_z_eval)
9226bc4823f4e3273aab7741edf221592a57d8d78fsewardj#define NOTE_C_EVAL(_cc_op) NOTE_EVAL(_cc_op, tab_c_eval)
9326bc4823f4e3273aab7741edf221592a57d8d78fsewardj#define NOTE_V_EVAL(_cc_op) NOTE_EVAL(_cc_op, tab_v_eval)
9426bc4823f4e3273aab7741edf221592a57d8d78fsewardj
9526bc4823f4e3273aab7741edf221592a57d8d78fsewardj#define NOTE_EVAL(_cc_op, _tab) \
9626bc4823f4e3273aab7741edf221592a57d8d78fsewardj   do { \
9726bc4823f4e3273aab7741edf221592a57d8d78fsewardj      if (!initted) initCounts(); \
9826bc4823f4e3273aab7741edf221592a57d8d78fsewardj      vassert( ((UInt)(_cc_op)) < ARMG_CC_OP_NUMBER); \
9926bc4823f4e3273aab7741edf221592a57d8d78fsewardj      _tab[(UInt)(_cc_op)]++; \
10026bc4823f4e3273aab7741edf221592a57d8d78fsewardj      tot_evals++; \
10126bc4823f4e3273aab7741edf221592a57d8d78fsewardj      if (0 == (tot_evals & 0xFFFFF)) \
10226bc4823f4e3273aab7741edf221592a57d8d78fsewardj        showCounts(); \
10326bc4823f4e3273aab7741edf221592a57d8d78fsewardj   } while (0)
10426bc4823f4e3273aab7741edf221592a57d8d78fsewardj
10526bc4823f4e3273aab7741edf221592a57d8d78fsewardj#endif /* PROFILE_NZCV_FLAGS */
10626bc4823f4e3273aab7741edf221592a57d8d78fsewardj
10726bc4823f4e3273aab7741edf221592a57d8d78fsewardj
1083c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj/* Calculate the N flag from the supplied thunk components, in the
1093c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   least significant bit of the word.  Returned bits 31:1 are zero. */
1103c14925dc79642a6c04bb7bf99253a853c1e3f36sewardjstatic
1113c14925dc79642a6c04bb7bf99253a853c1e3f36sewardjUInt armg_calculate_flag_n ( UInt cc_op, UInt cc_dep1,
1123c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                             UInt cc_dep2, UInt cc_dep3 )
1136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj{
11426bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  if PROFILE_NZCV_FLAGS
11526bc4823f4e3273aab7741edf221592a57d8d78fsewardj   NOTE_N_EVAL(cc_op);
11626bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  endif
11726bc4823f4e3273aab7741edf221592a57d8d78fsewardj
1183c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   switch (cc_op) {
1193c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_COPY: {
1203c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (nzcv:28x0, unused, unused) */
1213c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = (cc_dep1 >> ARMG_CC_SHIFT_N) & 1;
1223c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1233c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1243c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_ADD: {
1253c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, unused) */
1263c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
1273c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
1283c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR;
1293c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = res >> 31;
1303c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1313c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1323c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_SUB: {
1333c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, unused) */
1343c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
1353c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
1363c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL - argR;
1373c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = res >> 31;
1383c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1393c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1403c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_ADC: {
1413c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, oldC) */
1423c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
1433c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
1443c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = cc_dep3;
1453c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldC & ~1) == 0);
1463c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR + oldC;
1473c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = res >> 31;
1483c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1493c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1503c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_SBB: {
1513c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, oldC) */
1523c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
1533c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
1543c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = cc_dep3;
1553c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldC & ~1) == 0);
1563c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL - argR - (oldC ^ 1);
1573c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = res >> 31;
1583c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1593c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1603c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_LOGIC: {
1613c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (res, shco, oldV) */
1623c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = cc_dep1;
1633c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = res >> 31;
1643c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1653c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1663c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_MUL: {
1673c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (res, unused, oldC:oldV) */
1683c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = cc_dep1;
1693c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf   = res >> 31;
1703c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1713c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1723c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_MULL: {
1733c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (resLo32, resHi32, oldC:oldV) */
1743c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt resHi32 = cc_dep2;
1753c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt nf      = resHi32 >> 31;
1763c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return nf;
1773c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
1783c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      default:
1793c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* shouldn't really make these calls from generated code */
1803c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vex_printf("armg_calculate_flag_n"
1813c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                    "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
1823c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                    cc_op, cc_dep1, cc_dep2, cc_dep3 );
1833c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vpanic("armg_calculate_flags_n");
1843c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   }
185f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion}
186f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion
187f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion
1883c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj/* Calculate the Z flag from the supplied thunk components, in the
1893c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   least significant bit of the word.  Returned bits 31:1 are zero. */
1903c14925dc79642a6c04bb7bf99253a853c1e3f36sewardjstatic
1913c14925dc79642a6c04bb7bf99253a853c1e3f36sewardjUInt armg_calculate_flag_z ( UInt cc_op, UInt cc_dep1,
1923c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                             UInt cc_dep2, UInt cc_dep3 )
1932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
19426bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  if PROFILE_NZCV_FLAGS
19526bc4823f4e3273aab7741edf221592a57d8d78fsewardj   NOTE_Z_EVAL(cc_op);
19626bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  endif
19726bc4823f4e3273aab7741edf221592a57d8d78fsewardj
1982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   switch (cc_op) {
1993c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_COPY: {
2003c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (nzcv:28x0, unused, unused) */
2013c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = (cc_dep1 >> ARMG_CC_SHIFT_Z) & 1;
2023c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2033c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
2046c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_ADD: {
2056c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (argL, argR, unused) */
2066c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argL = cc_dep1;
2076c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argR = cc_dep2;
2086c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt res  = argL + argR;
2093c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = res == 0;
2103c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2126c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_SUB: {
2136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (argL, argR, unused) */
2146c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argL = cc_dep1;
2156c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argR = cc_dep2;
2166c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt res  = argL - argR;
2173c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = res == 0;
2183c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2196c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2206c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_ADC: {
2216c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (argL, argR, oldC) */
2226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argL = cc_dep1;
2236c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argR = cc_dep2;
2246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt oldC = cc_dep3;
225bb8b394c97a23a17f60712afff6484ab340a93casewardj         vassert((oldC & ~1) == 0);
2263c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR + oldC;
2273c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = res == 0;
2283c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2296c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2306c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_SBB: {
2316c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (argL, argR, oldC) */
2326c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argL = cc_dep1;
2336c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt argR = cc_dep2;
2346c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt oldC = cc_dep3;
235bb8b394c97a23a17f60712afff6484ab340a93casewardj         vassert((oldC & ~1) == 0);
2366c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt res  = argL - argR - (oldC ^ 1);
2373c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = res == 0;
2383c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2396c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2406c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_LOGIC: {
2416c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (res, shco, oldV) */
2426c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt res  = cc_dep1;
2433c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = res == 0;
2443c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2456c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2466c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_MUL: {
2476c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (res, unused, oldC:oldV) */
2486c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt res  = cc_dep1;
2493c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf   = res == 0;
2503c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2516c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2526c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMG_CC_OP_MULL: {
2536c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* (resLo32, resHi32, oldC:oldV) */
2546c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt resLo32 = cc_dep1;
2556c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         UInt resHi32 = cc_dep2;
2563c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt zf      = (resHi32|resLo32) == 0;
2573c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return zf;
2586c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
2596c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      default:
2606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* shouldn't really make these calls from generated code */
2613c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vex_printf("armg_calculate_flags_z"
2626c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                    "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
2636c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                    cc_op, cc_dep1, cc_dep2, cc_dep3 );
2643c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vpanic("armg_calculate_flags_z");
2652a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   }
2662a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
2672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
2686c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
269f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion/* CALLED FROM GENERATED CODE: CLEAN HELPER */
2703c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj/* Calculate the C flag from the supplied thunk components, in the
2713c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   least significant bit of the word.  Returned bits 31:1 are zero. */
2726c299f3acab617581ea504e45fbb6cab24c2b29fsewardjUInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1,
2736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                             UInt cc_dep2, UInt cc_dep3 )
274f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion{
27526bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  if PROFILE_NZCV_FLAGS
27626bc4823f4e3273aab7741edf221592a57d8d78fsewardj   NOTE_C_EVAL(cc_op);
27726bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  endif
27826bc4823f4e3273aab7741edf221592a57d8d78fsewardj
2793c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   switch (cc_op) {
2803c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_COPY: {
2813c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (nzcv:28x0, unused, unused) */
2823c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = (cc_dep1 >> ARMG_CC_SHIFT_C) & 1;
2833c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
2843c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
2853c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_ADD: {
2863c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, unused) */
2873c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
2883c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
2893c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR;
2903c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = res < argL;
2913c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
2923c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
2933c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_SUB: {
2943c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, unused) */
2953c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
2963c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
2973c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = argL >= argR;
2983c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
2993c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3003c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_ADC: {
3013c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, oldC) */
3023c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
3033c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
3043c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = cc_dep3;
3053c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldC & ~1) == 0);
3063c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR + oldC;
3073c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = oldC ? (res <= argL) : (res < argL);
3083c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
3093c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3103c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_SBB: {
3113c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, oldC) */
3123c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
3133c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
3143c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = cc_dep3;
3153c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldC & ~1) == 0);
3163c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = oldC ? (argL >= argR) : (argL > argR);
3173c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
3183c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3193c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_LOGIC: {
3203c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (res, shco, oldV) */
3213c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt shco = cc_dep2;
3223c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((shco & ~1) == 0);
3233c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = shco;
3243c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
3253c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3263c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_MUL: {
3273c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (res, unused, oldC:oldV) */
3283c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = (cc_dep3 >> 1) & 1;
3293c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((cc_dep3 & ~3) == 0);
3303c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf   = oldC;
3313c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
3323c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3333c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_MULL: {
3343c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (resLo32, resHi32, oldC:oldV) */
3353c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC    = (cc_dep3 >> 1) & 1;
3363c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((cc_dep3 & ~3) == 0);
3373c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt cf      = oldC;
3383c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return cf;
3393c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3403c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      default:
3413c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* shouldn't really make these calls from generated code */
3423c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vex_printf("armg_calculate_flag_c"
3433c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                    "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
3443c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                    cc_op, cc_dep1, cc_dep2, cc_dep3 );
3453c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vpanic("armg_calculate_flag_c");
3463c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   }
347f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion}
348f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion
349f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion
3502a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
3513c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj/* Calculate the V flag from the supplied thunk components, in the
3523c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   least significant bit of the word.  Returned bits 31:1 are zero. */
3536c299f3acab617581ea504e45fbb6cab24c2b29fsewardjUInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
3546c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                             UInt cc_dep2, UInt cc_dep3 )
3552a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
35626bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  if PROFILE_NZCV_FLAGS
35726bc4823f4e3273aab7741edf221592a57d8d78fsewardj   NOTE_V_EVAL(cc_op);
35826bc4823f4e3273aab7741edf221592a57d8d78fsewardj#  endif
35926bc4823f4e3273aab7741edf221592a57d8d78fsewardj
3603c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   switch (cc_op) {
3613c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_COPY: {
3623c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (nzcv:28x0, unused, unused) */
3633c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = (cc_dep1 >> ARMG_CC_SHIFT_V) & 1;
3643c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
3653c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3663c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_ADD: {
3673c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, unused) */
3683c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
3693c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
3703c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR;
3713c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = ((res ^ argL) & (res ^ argR)) >> 31;
3723c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
3733c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3743c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_SUB: {
3753c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, unused) */
3763c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
3773c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
3783c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL - argR;
3793c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = ((argL ^ argR) & (argL ^ res)) >> 31;
3803c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
3813c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3823c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_ADC: {
3833c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, oldC) */
3843c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
3853c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
3863c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = cc_dep3;
3873c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldC & ~1) == 0);
3883c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL + argR + oldC;
3893c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = ((res ^ argL) & (res ^ argR)) >> 31;
3903c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
3913c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
3923c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_SBB: {
3933c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (argL, argR, oldC) */
3943c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argL = cc_dep1;
3953c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt argR = cc_dep2;
3963c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldC = cc_dep3;
3973c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldC & ~1) == 0);
3983c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt res  = argL - argR - (oldC ^ 1);
3993c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = ((argL ^ argR) & (argL ^ res)) >> 31;
4003c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
4013c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
4023c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_LOGIC: {
4033c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (res, shco, oldV) */
4043c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldV = cc_dep3;
4053c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((oldV & ~1) == 0);
4063c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = oldV;
4073c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
4083c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
4093c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_MUL: {
4103c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (res, unused, oldC:oldV) */
4113c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldV = (cc_dep3 >> 0) & 1;
4123c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((cc_dep3 & ~3) == 0);
4133c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf   = oldV;
4143c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
4153c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
4163c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      case ARMG_CC_OP_MULL: {
4173c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* (resLo32, resHi32, oldC:oldV) */
4183c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt oldV    = (cc_dep3 >> 0) & 1;
4193c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vassert((cc_dep3 & ~3) == 0);
4203c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         UInt vf      = oldV;
4213c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return vf;
4223c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      }
4233c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj      default:
4243c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         /* shouldn't really make these calls from generated code */
4253c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vex_printf("armg_calculate_flag_v"
4263c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                    "( op=%u, dep1=0x%x, dep2=0x%x, dep3=0x%x )\n",
4273c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                    cc_op, cc_dep1, cc_dep2, cc_dep3 );
4283c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vpanic("armg_calculate_flag_v");
4293c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   }
4306c299f3acab617581ea504e45fbb6cab24c2b29fsewardj}
4316c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
4323c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj
4333c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
4343c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj/* Calculate NZCV from the supplied thunk components, in the positions
4353c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   they appear in the CPSR, viz bits 31:28 for N Z C V respectively.
4363c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   Returned bits 27:0 are zero. */
4373c14925dc79642a6c04bb7bf99253a853c1e3f36sewardjUInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
4383c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj                                 UInt cc_dep2, UInt cc_dep3 )
4393c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj{
4403c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   UInt f;
4413c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   UInt res = 0;
4423c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   f = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
4433c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   res |= (f << ARMG_CC_SHIFT_N);
4443c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   f = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
4453c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   res |= (f << ARMG_CC_SHIFT_Z);
4463c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   f = armg_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3);
4473c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   res |= (f << ARMG_CC_SHIFT_C);
4483c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   f = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
4493c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   res |= (f << ARMG_CC_SHIFT_V);
4503c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   return res;
4513c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj}
4523c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj
4533c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj
454d266447c09a99122cbc220edee5ac936eee7a0ddsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
4559dbbd7b5d3ba12bd46e38bfe6ef24dbabecfed13sewardj/* Calculate the QC flag from the arguments, in the lowest bit
4569dbbd7b5d3ba12bd46e38bfe6ef24dbabecfed13sewardj   of the word (bit 0).  Urr, having this out of line is bizarre.
4579dbbd7b5d3ba12bd46e38bfe6ef24dbabecfed13sewardj   Push back inline. */
458d266447c09a99122cbc220edee5ac936eee7a0ddsewardjUInt armg_calculate_flag_qc ( UInt resL1, UInt resL2,
459d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                              UInt resR1, UInt resR2 )
460d266447c09a99122cbc220edee5ac936eee7a0ddsewardj{
461d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   if (resL1 != resR1 || resL2 != resR2)
462d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      return 1;
463d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   else
464d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      return 0;
465d266447c09a99122cbc220edee5ac936eee7a0ddsewardj}
466d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
4676c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/* CALLED FROM GENERATED CODE: CLEAN HELPER */
4686c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/* Calculate the specified condition from the thunk components, in the
4693c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   lowest bit of the word (bit 0).  Returned bits 31:1 are zero. */
470bb8b394c97a23a17f60712afff6484ab340a93casewardjUInt armg_calculate_condition ( UInt cond_n_op /* (ARMCondcode << 4) | cc_op */,
4716c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                                UInt cc_dep1,
4726c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                                UInt cc_dep2, UInt cc_dep3 )
4736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj{
4746c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   UInt cond  = cond_n_op >> 4;
4756c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   UInt cc_op = cond_n_op & 0xF;
4763c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj   UInt nf, zf, vf, cf, inv;
477d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   //   vex_printf("XXXXXXXX %x %x %x %x\n",
478d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   //              cond_n_op, cc_dep1, cc_dep2, cc_dep3);
479d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
480d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   // skip flags computation in this case
481d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   if (cond == ARMCondAL) return 1;
482d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
483d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   inv  = cond & 1;
4842a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
4852a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   switch (cond) {
4866c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondEQ:    // Z=1         => z
4876c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondNE:    // Z=0
4883c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         zf = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
4893c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ zf;
4906c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
4916c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondHS:    // C=1         => c
4926c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondLO:    // C=0
4933c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         cf = armg_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3);
4943c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ cf;
4956c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
4966c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondMI:    // N=1         => n
4976c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondPL:    // N=0
4983c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         nf = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
4993c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ nf;
5006c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5016c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondVS:    // V=1         => v
5026c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondVC:    // V=0
5033c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vf = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
5043c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ vf;
5056c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5066c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondHI:    // C=1 && Z=0   => c & ~z
5076c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondLS:    // C=0 || Z=1
5083c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         cf = armg_calculate_flag_c(cc_op, cc_dep1, cc_dep2, cc_dep3);
5093c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         zf = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
5103c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ (cf & ~zf);
5116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5126c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondGE:    // N=V          => ~(n^v)
5136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondLT:    // N!=V
5143c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         nf = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
5153c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vf = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
5163c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ (1 & ~(nf ^ vf));
5176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5186c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondGT:    // Z=0 && N=V   => ~z & ~(n^v)  =>  ~(z | (n^v))
5196c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondLE:    // Z=1 || N!=V
5203c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         nf = armg_calculate_flag_n(cc_op, cc_dep1, cc_dep2, cc_dep3);
5213c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         vf = armg_calculate_flag_v(cc_op, cc_dep1, cc_dep2, cc_dep3);
5223c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         zf = armg_calculate_flag_z(cc_op, cc_dep1, cc_dep2, cc_dep3);
5233c14925dc79642a6c04bb7bf99253a853c1e3f36sewardj         return inv ^ (1 & ~(zf | (nf ^ vf)));
5246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
525d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      case ARMCondAL: // handled above
5266c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      case ARMCondNV: // should never get here: Illegal instr
5276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      default:
5286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* shouldn't really make these calls from generated code */
5296c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vex_printf("armg_calculate_condition(ARM)"
5306c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                    "( %u, %u, 0x%x, 0x%x, 0x%x )\n",
5316c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                    cond, cc_op, cc_dep1, cc_dep2, cc_dep3 );
5326c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         vpanic("armg_calculate_condition(ARM)");
5332a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   }
5342a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
5352a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
5362a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
5376c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/*---------------------------------------------------------------*/
5386c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/*--- Flag-helpers translation-time function specialisers.    ---*/
5396c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/*--- These help iropt specialise calls the above run-time    ---*/
5406c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/*--- flags functions.                                        ---*/
5416c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/*---------------------------------------------------------------*/
5426c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/* Used by the optimiser to try specialisations.  Returns an
5442a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   equivalent expression, or NULL if none. */
5452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
5462a9ad023890d3b34cf45e429df2a8ae88b419128sewardjstatic Bool isU32 ( IRExpr* e, UInt n )
5472a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
5486c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   return
5496c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      toBool( e->tag == Iex_Const
5506c299f3acab617581ea504e45fbb6cab24c2b29fsewardj              && e->Iex.Const.con->tag == Ico_U32
5516c299f3acab617581ea504e45fbb6cab24c2b29fsewardj              && e->Iex.Const.con->Ico.U32 == n );
5522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
5536c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5541ff4756e1731485e6bf3cd96717cd8398daec1f2florianIRExpr* guest_arm_spechelper ( const HChar* function_name,
555d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                               IRExpr** args,
556d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                               IRStmt** precedingStmts,
557d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                               Int      n_precedingStmts )
5582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
5596c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  define unop(_op,_a1) IRExpr_Unop((_op),(_a1))
5606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2))
5616c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  define mkU32(_n) IRExpr_Const(IRConst_U32(_n))
5626c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  define mkU8(_n)  IRExpr_Const(IRConst_U8(_n))
5636c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5646c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   Int i, arity = 0;
5656c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   for (i = 0; args[i]; i++)
5666c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      arity++;
5676c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  if 0
5686c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_printf("spec request:\n");
5696c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_printf("   %s  ", function_name);
5706c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   for (i = 0; i < arity; i++) {
5716c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      vex_printf("  ");
5726c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      ppIRExpr(args[i]);
5736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   }
5746c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_printf("\n");
5756c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  endif
5766c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
577d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   /* --------- specialising "armg_calculate_condition" --------- */
5786c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5796c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   if (vex_streq(function_name, "armg_calculate_condition")) {
580bb8b394c97a23a17f60712afff6484ab340a93casewardj
581bb8b394c97a23a17f60712afff6484ab340a93casewardj      /* specialise calls to the "armg_calculate_condition" function.
582bb8b394c97a23a17f60712afff6484ab340a93casewardj         Not sure whether this is strictly necessary, but: the
583bb8b394c97a23a17f60712afff6484ab340a93casewardj         replacement IR must produce only the values 0 or 1.  Bits
584bb8b394c97a23a17f60712afff6484ab340a93casewardj         31:1 are required to be zero. */
585bb8b394c97a23a17f60712afff6484ab340a93casewardj      IRExpr *cond_n_op, *cc_dep1, *cc_dep2, *cc_ndep;
5866c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      vassert(arity == 4);
587bb8b394c97a23a17f60712afff6484ab340a93casewardj      cond_n_op = args[0]; /* (ARMCondcode << 4)  |  ARMG_CC_OP_* */
5886c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      cc_dep1   = args[1];
5896c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      cc_dep2   = args[2];
590bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_ndep   = args[3];
5916c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5926c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /*---------------- SUB ----------------*/
5936c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5946c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondEQ << 4) | ARMG_CC_OP_SUB)) {
5956c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* EQ after SUB --> test argL == argR */
5966c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
5976c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpEQ32, cc_dep1, cc_dep2));
5986c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
5996c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondNE << 4) | ARMG_CC_OP_SUB)) {
6006c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* NE after SUB --> test argL != argR */
6016c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6026c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpNE32, cc_dep1, cc_dep2));
6036c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
6046c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
605285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj      if (isU32(cond_n_op, (ARMCondGT << 4) | ARMG_CC_OP_SUB)) {
606285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj         /* GT after SUB --> test argL >s argR
607285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj                         --> test argR <s argL */
608285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj         return unop(Iop_1Uto32,
609285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj                     binop(Iop_CmpLT32S, cc_dep2, cc_dep1));
610285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj      }
6116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondLE << 4) | ARMG_CC_OP_SUB)) {
6126c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* LE after SUB --> test argL <=s argR */
6136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6146c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpLE32S, cc_dep1, cc_dep2));
6156c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
6166c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondLT << 4) | ARMG_CC_OP_SUB)) {
618d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         /* LT after SUB --> test argL <s argR */
6196c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6206c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpLT32S, cc_dep1, cc_dep2));
6216c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
6226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6236c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondGE << 4) | ARMG_CC_OP_SUB)) {
6246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* GE after SUB --> test argL >=s argR
6256c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                         --> test argR <=s argL */
6266c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpLE32S, cc_dep2, cc_dep1));
6286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
6296c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6306c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondHS << 4) | ARMG_CC_OP_SUB)) {
6316c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* HS after SUB --> test argL >=u argR
6326c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                         --> test argR <=u argL */
6336c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6346c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpLE32U, cc_dep2, cc_dep1));
6356c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
636285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj      if (isU32(cond_n_op, (ARMCondLO << 4) | ARMG_CC_OP_SUB)) {
637285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj         /* LO after SUB --> test argL <u argR */
638285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj         return unop(Iop_1Uto32,
639285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj                     binop(Iop_CmpLT32U, cc_dep1, cc_dep2));
640285c24d360ca1b0ab75728b045a609aa17f63ac6sewardj      }
6416c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6426c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondLS << 4) | ARMG_CC_OP_SUB)) {
6436c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* LS after SUB --> test argL <=u argR */
6446c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6456c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpLE32U, cc_dep1, cc_dep2));
6466c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
64726de96421c01ede25a0691f793174e07a5f0ffe0sewardj      if (isU32(cond_n_op, (ARMCondHI << 4) | ARMG_CC_OP_SUB)) {
64826de96421c01ede25a0691f793174e07a5f0ffe0sewardj         /* HI after SUB --> test argL >u argR
64926de96421c01ede25a0691f793174e07a5f0ffe0sewardj                         --> test argR <u argL */
65026de96421c01ede25a0691f793174e07a5f0ffe0sewardj         return unop(Iop_1Uto32,
65126de96421c01ede25a0691f793174e07a5f0ffe0sewardj                     binop(Iop_CmpLT32U, cc_dep2, cc_dep1));
65226de96421c01ede25a0691f793174e07a5f0ffe0sewardj      }
6536c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
654bb8b394c97a23a17f60712afff6484ab340a93casewardj      /*---------------- SBB ----------------*/
655bb8b394c97a23a17f60712afff6484ab340a93casewardj
656bb8b394c97a23a17f60712afff6484ab340a93casewardj      if (isU32(cond_n_op, (ARMCondHS << 4) | ARMG_CC_OP_SBB)) {
657bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* This seems to happen a lot in softfloat code, eg __divdf3+140 */
658bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */
659bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* HS after SBB (same as C after SBB below)
660bb8b394c97a23a17f60712afff6484ab340a93casewardj            --> oldC ? (argL >=u argR) : (argL >u argR)
661bb8b394c97a23a17f60712afff6484ab340a93casewardj            --> oldC ? (argR <=u argL) : (argR <u argL)
662bb8b394c97a23a17f60712afff6484ab340a93casewardj         */
663bb8b394c97a23a17f60712afff6484ab340a93casewardj         return
66499dd03e04a6914d90d5fee727d61d76905334becflorian            IRExpr_ITE(
665d0f1a93e8e4595616087adb7b1e51ad0bbacdec3sewardj               binop(Iop_CmpNE32, cc_ndep, mkU32(0)),
666bb8b394c97a23a17f60712afff6484ab340a93casewardj               /* case oldC != 0 */
66799dd03e04a6914d90d5fee727d61d76905334becflorian               unop(Iop_1Uto32, binop(Iop_CmpLE32U, cc_dep2, cc_dep1)),
66899dd03e04a6914d90d5fee727d61d76905334becflorian               /* case oldC == 0 */
66999dd03e04a6914d90d5fee727d61d76905334becflorian               unop(Iop_1Uto32, binop(Iop_CmpLT32U, cc_dep2, cc_dep1))
670bb8b394c97a23a17f60712afff6484ab340a93casewardj            );
671bb8b394c97a23a17f60712afff6484ab340a93casewardj      }
672bb8b394c97a23a17f60712afff6484ab340a93casewardj
6736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /*---------------- LOGIC ----------------*/
674bb8b394c97a23a17f60712afff6484ab340a93casewardj
6756c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondEQ << 4) | ARMG_CC_OP_LOGIC)) {
6766c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* EQ after LOGIC --> test res == 0 */
6776c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6786c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
6796c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
6806c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      if (isU32(cond_n_op, (ARMCondNE << 4) | ARMG_CC_OP_LOGIC)) {
6816c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         /* NE after LOGIC --> test res != 0 */
6826c299f3acab617581ea504e45fbb6cab24c2b29fsewardj         return unop(Iop_1Uto32,
6836c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                     binop(Iop_CmpNE32, cc_dep1, mkU32(0)));
6846c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      }
6856c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
686540acf576e17427c55ba021f84d5f701aea6734fsewardj      if (isU32(cond_n_op, (ARMCondPL << 4) | ARMG_CC_OP_LOGIC)) {
687540acf576e17427c55ba021f84d5f701aea6734fsewardj         /* PL after LOGIC --> test (res >> 31) == 0 */
688540acf576e17427c55ba021f84d5f701aea6734fsewardj         return unop(Iop_1Uto32,
689540acf576e17427c55ba021f84d5f701aea6734fsewardj                     binop(Iop_CmpEQ32,
690540acf576e17427c55ba021f84d5f701aea6734fsewardj                           binop(Iop_Shr32, cc_dep1, mkU8(31)),
691540acf576e17427c55ba021f84d5f701aea6734fsewardj                           mkU32(0)));
692540acf576e17427c55ba021f84d5f701aea6734fsewardj      }
693540acf576e17427c55ba021f84d5f701aea6734fsewardj      if (isU32(cond_n_op, (ARMCondMI << 4) | ARMG_CC_OP_LOGIC)) {
694540acf576e17427c55ba021f84d5f701aea6734fsewardj         /* MI after LOGIC --> test (res >> 31) == 1 */
695540acf576e17427c55ba021f84d5f701aea6734fsewardj         return unop(Iop_1Uto32,
696540acf576e17427c55ba021f84d5f701aea6734fsewardj                     binop(Iop_CmpEQ32,
697540acf576e17427c55ba021f84d5f701aea6734fsewardj                           binop(Iop_Shr32, cc_dep1, mkU8(31)),
698540acf576e17427c55ba021f84d5f701aea6734fsewardj                           mkU32(1)));
699540acf576e17427c55ba021f84d5f701aea6734fsewardj      }
700540acf576e17427c55ba021f84d5f701aea6734fsewardj
701ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj      /*---------------- COPY ----------------*/
702ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj
703ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj      if (isU32(cond_n_op, (ARMCondNE << 4) | ARMG_CC_OP_COPY)) {
704ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj         /* NE after COPY --> ((cc_dep1 >> ARMG_CC_SHIFT_Z) ^ 1) & 1 */
705ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj         return binop(Iop_And32,
706ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj                      binop(Iop_Xor32,
707ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj                            binop(Iop_Shr32, cc_dep1,
708ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj                                             mkU8(ARMG_CC_SHIFT_Z)),
709ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj                            mkU32(1)),
710ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj                      mkU32(1));
711ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj      }
712ed055d03c4eee0487ac93be5760bae88fb3f4c23sewardj
713d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      /*----------------- AL -----------------*/
714bb8b394c97a23a17f60712afff6484ab340a93casewardj
715d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      /* A critically important case for Thumb code.
716d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
717d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         What we're trying to spot is the case where cond_n_op is an
718d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         expression of the form Or32(..., 0xE0) since that means the
719d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         caller is asking for CondAL and we can simply return 1
720d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         without caring what the ... part is.  This is a potentially
721d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         dodgy kludge in that it assumes that the ... part has zeroes
722d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         in bits 7:4, so that the result of the Or32 is guaranteed to
723d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         be 0xE in bits 7:4.  Given that the places where this first
724d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         arg are constructed (in guest_arm_toIR.c) are very
725d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         constrained, we can get away with this.  To make this
726d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         guaranteed safe would require to have a new primop, Slice44
727d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         or some such, thusly
728d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
729d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         Slice44(arg1, arg2) = 0--(24)--0 arg1[7:4] arg2[3:0]
730d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
731d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         and we would then look for Slice44(0xE0, ...)
732d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         which would give the required safety property.
733d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
734d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         It would be infeasibly expensive to scan backwards through
735d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         the entire block looking for an assignment to the temp, so
736d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         just look at the previous 16 statements.  That should find it
737d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         if it is an interesting case, as a result of how the
738d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         boilerplate guff at the start of each Thumb insn translation
739d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         is made.
740d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      */
741d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      if (cond_n_op->tag == Iex_RdTmp) {
742d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         Int    j;
743d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         IRTemp look_for = cond_n_op->Iex.RdTmp.tmp;
744d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         Int    limit    = n_precedingStmts - 16;
745d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         if (limit < 0) limit = 0;
746d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         if (0) vex_printf("scanning %d .. %d\n", n_precedingStmts-1, limit);
747d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         for (j = n_precedingStmts - 1; j >= limit; j--) {
748d266447c09a99122cbc220edee5ac936eee7a0ddsewardj            IRStmt* st = precedingStmts[j];
749d266447c09a99122cbc220edee5ac936eee7a0ddsewardj            if (st->tag == Ist_WrTmp
750d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                && st->Ist.WrTmp.tmp == look_for
751d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                && st->Ist.WrTmp.data->tag == Iex_Binop
752d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                && st->Ist.WrTmp.data->Iex.Binop.op == Iop_Or32
753d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                && isU32(st->Ist.WrTmp.data->Iex.Binop.arg2, (ARMCondAL << 4)))
754d266447c09a99122cbc220edee5ac936eee7a0ddsewardj               return mkU32(1);
755d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         }
756d266447c09a99122cbc220edee5ac936eee7a0ddsewardj         /* Didn't find any useful binding to the first arg
757d266447c09a99122cbc220edee5ac936eee7a0ddsewardj            in the previous 16 stmts. */
758d266447c09a99122cbc220edee5ac936eee7a0ddsewardj      }
7596c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   }
7606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
761bb8b394c97a23a17f60712afff6484ab340a93casewardj   /* --------- specialising "armg_calculate_flag_c" --------- */
762bb8b394c97a23a17f60712afff6484ab340a93casewardj
763bb8b394c97a23a17f60712afff6484ab340a93casewardj   else
764bb8b394c97a23a17f60712afff6484ab340a93casewardj   if (vex_streq(function_name, "armg_calculate_flag_c")) {
765bb8b394c97a23a17f60712afff6484ab340a93casewardj
766bb8b394c97a23a17f60712afff6484ab340a93casewardj      /* specialise calls to the "armg_calculate_flag_c" function.
767bb8b394c97a23a17f60712afff6484ab340a93casewardj         Note that the returned value must be either 0 or 1; nonzero
768bb8b394c97a23a17f60712afff6484ab340a93casewardj         bits 31:1 are not allowed.  In turn, incoming oldV and oldC
769bb8b394c97a23a17f60712afff6484ab340a93casewardj         values (from the thunk) are assumed to have bits 31:1
770bb8b394c97a23a17f60712afff6484ab340a93casewardj         clear. */
771bb8b394c97a23a17f60712afff6484ab340a93casewardj      IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep;
772bb8b394c97a23a17f60712afff6484ab340a93casewardj      vassert(arity == 4);
773bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_op   = args[0]; /* ARMG_CC_OP_* */
774bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_dep1 = args[1];
775bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_dep2 = args[2];
776bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_ndep = args[3];
777bb8b394c97a23a17f60712afff6484ab340a93casewardj
778bb8b394c97a23a17f60712afff6484ab340a93casewardj      if (isU32(cc_op, ARMG_CC_OP_LOGIC)) {
779bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* Thunk args are (result, shco, oldV) */
780bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* C after LOGIC --> shco */
781bb8b394c97a23a17f60712afff6484ab340a93casewardj         return cc_dep2;
782bb8b394c97a23a17f60712afff6484ab340a93casewardj      }
783bb8b394c97a23a17f60712afff6484ab340a93casewardj
784bb8b394c97a23a17f60712afff6484ab340a93casewardj      if (isU32(cc_op, ARMG_CC_OP_SUB)) {
785bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* Thunk args are (argL, argR, unused) */
786bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* C after SUB --> argL >=u argR
787bb8b394c97a23a17f60712afff6484ab340a93casewardj                        --> argR <=u argL */
788bb8b394c97a23a17f60712afff6484ab340a93casewardj         return unop(Iop_1Uto32,
789bb8b394c97a23a17f60712afff6484ab340a93casewardj                     binop(Iop_CmpLE32U, cc_dep2, cc_dep1));
790bb8b394c97a23a17f60712afff6484ab340a93casewardj      }
791bb8b394c97a23a17f60712afff6484ab340a93casewardj
792bb8b394c97a23a17f60712afff6484ab340a93casewardj      if (isU32(cc_op, ARMG_CC_OP_SBB)) {
793bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* This happens occasionally in softfloat code, eg __divdf3+140 */
794bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */
795bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* C after SBB (same as HS after SBB above)
796bb8b394c97a23a17f60712afff6484ab340a93casewardj            --> oldC ? (argL >=u argR) : (argL >u argR)
797bb8b394c97a23a17f60712afff6484ab340a93casewardj            --> oldC ? (argR <=u argL) : (argR <u argL)
798bb8b394c97a23a17f60712afff6484ab340a93casewardj         */
799bb8b394c97a23a17f60712afff6484ab340a93casewardj         return
80099dd03e04a6914d90d5fee727d61d76905334becflorian            IRExpr_ITE(
801009230b9758291b594e60d7c0243a73d53e81854sewardj               binop(Iop_CmpNE32, cc_ndep, mkU32(0)),
802bb8b394c97a23a17f60712afff6484ab340a93casewardj               /* case oldC != 0 */
80399dd03e04a6914d90d5fee727d61d76905334becflorian               unop(Iop_1Uto32, binop(Iop_CmpLE32U, cc_dep2, cc_dep1)),
80499dd03e04a6914d90d5fee727d61d76905334becflorian               /* case oldC == 0 */
80599dd03e04a6914d90d5fee727d61d76905334becflorian               unop(Iop_1Uto32, binop(Iop_CmpLT32U, cc_dep2, cc_dep1))
806bb8b394c97a23a17f60712afff6484ab340a93casewardj            );
807bb8b394c97a23a17f60712afff6484ab340a93casewardj      }
808bb8b394c97a23a17f60712afff6484ab340a93casewardj
809bb8b394c97a23a17f60712afff6484ab340a93casewardj   }
810bb8b394c97a23a17f60712afff6484ab340a93casewardj
811bb8b394c97a23a17f60712afff6484ab340a93casewardj   /* --------- specialising "armg_calculate_flag_v" --------- */
812bb8b394c97a23a17f60712afff6484ab340a93casewardj
813bb8b394c97a23a17f60712afff6484ab340a93casewardj   else
814bb8b394c97a23a17f60712afff6484ab340a93casewardj   if (vex_streq(function_name, "armg_calculate_flag_v")) {
815bb8b394c97a23a17f60712afff6484ab340a93casewardj
816bb8b394c97a23a17f60712afff6484ab340a93casewardj      /* specialise calls to the "armg_calculate_flag_v" function.
817bb8b394c97a23a17f60712afff6484ab340a93casewardj         Note that the returned value must be either 0 or 1; nonzero
818bb8b394c97a23a17f60712afff6484ab340a93casewardj         bits 31:1 are not allowed.  In turn, incoming oldV and oldC
819bb8b394c97a23a17f60712afff6484ab340a93casewardj         values (from the thunk) are assumed to have bits 31:1
820bb8b394c97a23a17f60712afff6484ab340a93casewardj         clear. */
821bb8b394c97a23a17f60712afff6484ab340a93casewardj      IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep;
822bb8b394c97a23a17f60712afff6484ab340a93casewardj      vassert(arity == 4);
823bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_op   = args[0]; /* ARMG_CC_OP_* */
824bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_dep1 = args[1];
825bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_dep2 = args[2];
826bb8b394c97a23a17f60712afff6484ab340a93casewardj      cc_ndep = args[3];
827bb8b394c97a23a17f60712afff6484ab340a93casewardj
828bb8b394c97a23a17f60712afff6484ab340a93casewardj      if (isU32(cc_op, ARMG_CC_OP_LOGIC)) {
829bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* Thunk args are (result, shco, oldV) */
830bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* V after LOGIC --> oldV */
831bb8b394c97a23a17f60712afff6484ab340a93casewardj         return cc_ndep;
832bb8b394c97a23a17f60712afff6484ab340a93casewardj      }
833bb8b394c97a23a17f60712afff6484ab340a93casewardj
83499ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj      if (isU32(cc_op, ARMG_CC_OP_SUB)) {
83599ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj         /* Thunk args are (argL, argR, unused) */
83699ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj         /* V after SUB
83799ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj            --> let res = argL - argR
83899ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj                in ((argL ^ argR) & (argL ^ res)) >> 31
83999ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj            --> ((argL ^ argR) & (argL ^ (argL - argR))) >> 31
84099ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj         */
84199ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj         IRExpr* argL = cc_dep1;
84299ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj         IRExpr* argR = cc_dep2;
84399ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj         return
84499ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj            binop(Iop_Shr32,
84599ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj                  binop(Iop_And32,
84699ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj                        binop(Iop_Xor32, argL, argR),
84799ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj                        binop(Iop_Xor32, argL, binop(Iop_Sub32, argL, argR))
84899ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj                  ),
84999ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj                  mkU8(31)
85099ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj            );
85199ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj      }
85299ff62020fbc47e05cb7c041e655f9a75d173ad7sewardj
853bb8b394c97a23a17f60712afff6484ab340a93casewardj      if (isU32(cc_op, ARMG_CC_OP_SBB)) {
854bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* This happens occasionally in softfloat code, eg __divdf3+140 */
855bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* thunk is: (dep1=argL, dep2=argR, ndep=oldC) */
856bb8b394c97a23a17f60712afff6484ab340a93casewardj         /* V after SBB
857bb8b394c97a23a17f60712afff6484ab340a93casewardj            --> let res = argL - argR - (oldC ^ 1)
858bb8b394c97a23a17f60712afff6484ab340a93casewardj                in  (argL ^ argR) & (argL ^ res) & 1
859bb8b394c97a23a17f60712afff6484ab340a93casewardj         */
860bb8b394c97a23a17f60712afff6484ab340a93casewardj         return
861bb8b394c97a23a17f60712afff6484ab340a93casewardj            binop(
862bb8b394c97a23a17f60712afff6484ab340a93casewardj               Iop_And32,
863bb8b394c97a23a17f60712afff6484ab340a93casewardj               binop(
864bb8b394c97a23a17f60712afff6484ab340a93casewardj                  Iop_And32,
865bb8b394c97a23a17f60712afff6484ab340a93casewardj                  // argL ^ argR
866bb8b394c97a23a17f60712afff6484ab340a93casewardj                  binop(Iop_Xor32, cc_dep1, cc_dep2),
867bb8b394c97a23a17f60712afff6484ab340a93casewardj                  // argL ^ (argL - argR - (oldC ^ 1))
868bb8b394c97a23a17f60712afff6484ab340a93casewardj                  binop(Iop_Xor32,
869bb8b394c97a23a17f60712afff6484ab340a93casewardj                        cc_dep1,
870bb8b394c97a23a17f60712afff6484ab340a93casewardj                        binop(Iop_Sub32,
871bb8b394c97a23a17f60712afff6484ab340a93casewardj                              binop(Iop_Sub32, cc_dep1, cc_dep2),
872bb8b394c97a23a17f60712afff6484ab340a93casewardj                              binop(Iop_Xor32, cc_ndep, mkU32(1)))
873bb8b394c97a23a17f60712afff6484ab340a93casewardj                  )
874bb8b394c97a23a17f60712afff6484ab340a93casewardj               ),
875bb8b394c97a23a17f60712afff6484ab340a93casewardj               mkU32(1)
876bb8b394c97a23a17f60712afff6484ab340a93casewardj            );
877bb8b394c97a23a17f60712afff6484ab340a93casewardj      }
878bb8b394c97a23a17f60712afff6484ab340a93casewardj
879bb8b394c97a23a17f60712afff6484ab340a93casewardj   }
880bb8b394c97a23a17f60712afff6484ab340a93casewardj
8816c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  undef unop
8826c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  undef binop
8836c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  undef mkU32
8846c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#  undef mkU8
8856c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
8862a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   return NULL;
8872a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
8882a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
8892a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
8902a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*----------------------------------------------*/
8912a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*--- The exported fns ..                    ---*/
8922a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*----------------------------------------------*/
8932a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
8942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/* VISIBLE TO LIBVEX CLIENT */
895c60c01ebe42c182f84fa6f5217db95f9a7ee0c36cerion#if 0
896f7da63d911934ee20d39e8c994edf7ca0bbc930fcerionvoid LibVEX_GuestARM_put_flags ( UInt flags_native,
8972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj                                 /*OUT*/VexGuestARMState* vex_state )
8982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
8992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vassert(0); // FIXME
9002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
901c60c01ebe42c182f84fa6f5217db95f9a7ee0c36cerion   /* Mask out everything except N Z V C. */
902f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion   flags_native
903c60c01ebe42c182f84fa6f5217db95f9a7ee0c36cerion      &= (ARMG_CC_MASK_N | ARMG_CC_MASK_Z | ARMG_CC_MASK_V | ARMG_CC_MASK_C);
904b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion
905c60c01ebe42c182f84fa6f5217db95f9a7ee0c36cerion   vex_state->guest_CC_OP   = ARMG_CC_OP_COPY;
906f7da63d911934ee20d39e8c994edf7ca0bbc930fcerion   vex_state->guest_CC_DEP1 = flags_native;
9072a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_CC_DEP2 = 0;
9086c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_CC_NDEP = 0;
9092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
910c60c01ebe42c182f84fa6f5217db95f9a7ee0c36cerion#endif
9112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
9122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/* VISIBLE TO LIBVEX CLIENT */
913efa834abaded25c8aff2f3923e476ef7cc1d0396florianUInt LibVEX_GuestARM_get_cpsr ( /*IN*/const VexGuestARMState* vex_state )
9142a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
915854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   UInt cpsr = 0;
916854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // NZCV
917854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   cpsr |= armg_calculate_flags_nzcv(
918854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj               vex_state->guest_CC_OP,
919854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj               vex_state->guest_CC_DEP1,
920854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj               vex_state->guest_CC_DEP2,
921854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj               vex_state->guest_CC_NDEP
922854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj            );
923854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   vassert(0 == (cpsr & 0x0FFFFFFF));
924854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // Q
925854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   if (vex_state->guest_QFLAG32 > 0)
926854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj      cpsr |= (1 << 27);
927854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // GE
928854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   if (vex_state->guest_GEFLAG0 > 0)
929854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj      cpsr |= (1 << 16);
930854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   if (vex_state->guest_GEFLAG1 > 0)
931854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj      cpsr |= (1 << 17);
932854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   if (vex_state->guest_GEFLAG2 > 0)
933854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj      cpsr |= (1 << 18);
934854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   if (vex_state->guest_GEFLAG3 > 0)
935854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj      cpsr |= (1 << 19);
936854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // M
937854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   cpsr |= (1 << 4); // 0b10000 means user-mode
938854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // J,T   J (bit 24) is zero by initialisation above
939854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // T  we copy from R15T[0]
940854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   if (vex_state->guest_R15T & 1)
941854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj      cpsr |= (1 << 5);
942854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // ITSTATE we punt on for the time being.  Could compute it
943854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // if needed though.
944854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // E, endianness, 0 (littleendian) from initialisation above
945854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // A,I,F disable some async exceptions.  Not sure about these.
946854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   // Leave as zero for the time being.
947854cc2bb5228c1b0eba77fb896827203f0e338cdsewardj   return cpsr;
9482a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
9492a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
9502a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/* VISIBLE TO LIBVEX CLIENT */
9512a9ad023890d3b34cf45e429df2a8ae88b419128sewardjvoid LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state )
9522a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
953c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vex_state->host_EvC_FAILADDR = 0;
954c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vex_state->host_EvC_COUNTER = 0;
955c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
9562a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R0  = 0;
9572a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R1  = 0;
9582a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R2  = 0;
9592a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R3  = 0;
9602a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R4  = 0;
9612a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R5  = 0;
9622a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R6  = 0;
9632a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R7  = 0;
9642a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R8  = 0;
9652a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R9  = 0;
9662a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R10 = 0;
9672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R11 = 0;
9682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R12 = 0;
9692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R13 = 0;
9702a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_R14 = 0;
971d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_R15T = 0;  /* NB: implies ARM mode */
9722a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
9736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_CC_OP   = ARMG_CC_OP_COPY;
9742a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_CC_DEP1 = 0;
9752a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   vex_state->guest_CC_DEP2 = 0;
9766c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_CC_NDEP = 0;
977d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_QFLAG32 = 0;
9781f139f58d905803d87fda1229e475c715df603easewardj   vex_state->guest_GEFLAG0 = 0;
9791f139f58d905803d87fda1229e475c715df603easewardj   vex_state->guest_GEFLAG1 = 0;
9801f139f58d905803d87fda1229e475c715df603easewardj   vex_state->guest_GEFLAG2 = 0;
9811f139f58d905803d87fda1229e475c715df603easewardj   vex_state->guest_GEFLAG3 = 0;
9826c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
9836ef84bed9bb3af22060eb1759788034602bbcc88florian   vex_state->guest_EMNOTE  = EmNote_NONE;
9846c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_TISTART = 0;
9856c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_TILEN   = 0;
9866c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_NRADDR  = 0;
9876c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_IP_AT_SYSCALL = 0;
9886c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
9896c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D0  = 0;
9906c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D1  = 0;
9916c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D2  = 0;
9926c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D3  = 0;
9936c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D4  = 0;
9946c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D5  = 0;
9956c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D6  = 0;
9966c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D7  = 0;
9976c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D8  = 0;
9986c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D9  = 0;
9996c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D10 = 0;
10006c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D11 = 0;
10016c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D12 = 0;
10026c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D13 = 0;
10036c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D14 = 0;
10046c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_D15 = 0;
1005d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D16 = 0;
1006d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D17 = 0;
1007d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D18 = 0;
1008d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D19 = 0;
1009d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D20 = 0;
1010d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D21 = 0;
1011d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D22 = 0;
1012d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D23 = 0;
1013d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D24 = 0;
1014d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D25 = 0;
1015d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D26 = 0;
1016d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D27 = 0;
1017d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D28 = 0;
1018d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D29 = 0;
1019d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D30 = 0;
1020d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_D31 = 0;
10216c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
10226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   /* ARM encoded; zero is the default as it happens (result flags
10236c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      (NZCV) cleared, FZ disabled, round to nearest, non-vector mode,
10246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      all exns masked, all exn sticky bits cleared). */
10256c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_FPSCR = 0;
10266c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
10276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   vex_state->guest_TPIDRURO = 0;
10286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
1029d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   /* Not in a Thumb IT block. */
1030d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->guest_ITSTATE = 0;
1031d266447c09a99122cbc220edee5ac936eee7a0ddsewardj
1032d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   vex_state->padding1 = 0;
103362d3cda72152ec8eeb3e1c59f128b8c19a4ee10bsewardj   vex_state->padding2 = 0;
103462d3cda72152ec8eeb3e1c59f128b8c19a4ee10bsewardj   vex_state->padding3 = 0;
103562d3cda72152ec8eeb3e1c59f128b8c19a4ee10bsewardj   vex_state->padding4 = 0;
103662d3cda72152ec8eeb3e1c59f128b8c19a4ee10bsewardj   vex_state->padding5 = 0;
10372a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
10382a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*-----------------------------------------------------------*/
10412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*--- Describing the arm guest state, for the benefit     ---*/
10422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*--- of iropt and instrumenters.                         ---*/
10432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*-----------------------------------------------------------*/
10442a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/* Figure out if any part of the guest state contained in minoff
10462a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   .. maxoff requires precise memory exceptions.  If in doubt return
10476c46befd9eb90c1b6e739926c1fa335cba75bf46philippe   True (but this generates significantly slower code).
10482a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10496c46befd9eb90c1b6e739926c1fa335cba75bf46philippe   We enforce precise exns for guest R13(sp), R15T(pc), R7, R11.
10506c46befd9eb90c1b6e739926c1fa335cba75bf46philippe
10516c46befd9eb90c1b6e739926c1fa335cba75bf46philippe
10526c46befd9eb90c1b6e739926c1fa335cba75bf46philippe   Only R13(sp) is needed in mode VexRegUpdSpAtMemAccess.
10532a9ad023890d3b34cf45e429df2a8ae88b419128sewardj*/
10542a9ad023890d3b34cf45e429df2a8ae88b419128sewardjBool guest_arm_state_requires_precise_mem_exns ( Int minoff,
10552a9ad023890d3b34cf45e429df2a8ae88b419128sewardj                                                 Int maxoff)
10562a9ad023890d3b34cf45e429df2a8ae88b419128sewardj{
10576c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   Int sp_min = offsetof(VexGuestARMState, guest_R13);
10586c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   Int sp_max = sp_min + 4 - 1;
1059d266447c09a99122cbc220edee5ac936eee7a0ddsewardj   Int pc_min = offsetof(VexGuestARMState, guest_R15T);
10606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   Int pc_max = pc_min + 4 - 1;
10612a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10626c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   if (maxoff < sp_min || minoff > sp_max) {
10636c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* no overlap with sp */
10646c46befd9eb90c1b6e739926c1fa335cba75bf46philippe      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
10656c46befd9eb90c1b6e739926c1fa335cba75bf46philippe         return False; // We only need to check stack pointer.
10662a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   } else {
10672a9ad023890d3b34cf45e429df2a8ae88b419128sewardj      return True;
10682a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   }
10692a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10706c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   if (maxoff < pc_min || minoff > pc_max) {
10716c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      /* no overlap with pc */
10726c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   } else {
10736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      return True;
10746c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   }
10756c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
10766c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   /* We appear to need precise updates of R11 in order to get proper
10776c299f3acab617581ea504e45fbb6cab24c2b29fsewardj      stacktraces from non-optimised code. */
10786c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   Int r11_min = offsetof(VexGuestARMState, guest_R11);
10796c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   Int r11_max = r11_min + 4 - 1;
10806c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
10816c299f3acab617581ea504e45fbb6cab24c2b29fsewardj   if (maxoff < r11_min || minoff > r11_max) {
10825de202d057461245b2457f6773511989272a69c9sewardj      /* no overlap with r11 */
10835de202d057461245b2457f6773511989272a69c9sewardj   } else {
10845de202d057461245b2457f6773511989272a69c9sewardj      return True;
10855de202d057461245b2457f6773511989272a69c9sewardj   }
10865de202d057461245b2457f6773511989272a69c9sewardj
10875de202d057461245b2457f6773511989272a69c9sewardj   /* Ditto R7, particularly needed for proper stacktraces in Thumb
10885de202d057461245b2457f6773511989272a69c9sewardj      code. */
10895de202d057461245b2457f6773511989272a69c9sewardj   Int r7_min = offsetof(VexGuestARMState, guest_R7);
10905de202d057461245b2457f6773511989272a69c9sewardj   Int r7_max = r7_min + 4 - 1;
10915de202d057461245b2457f6773511989272a69c9sewardj
10925de202d057461245b2457f6773511989272a69c9sewardj   if (maxoff < r7_min || minoff > r7_max) {
10935de202d057461245b2457f6773511989272a69c9sewardj      /* no overlap with r7 */
10942a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   } else {
10952a9ad023890d3b34cf45e429df2a8ae88b419128sewardj      return True;
10962a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   }
10972a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
10982a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   return False;
10992a9ad023890d3b34cf45e429df2a8ae88b419128sewardj}
11002a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11012a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11022a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11032a9ad023890d3b34cf45e429df2a8ae88b419128sewardj#define ALWAYSDEFD(field)                           \
11042a9ad023890d3b34cf45e429df2a8ae88b419128sewardj    { offsetof(VexGuestARMState, field),            \
11052a9ad023890d3b34cf45e429df2a8ae88b419128sewardj      (sizeof ((VexGuestARMState*)0)->field) }
11062a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11072a9ad023890d3b34cf45e429df2a8ae88b419128sewardjVexGuestLayout
11082a9ad023890d3b34cf45e429df2a8ae88b419128sewardj   armGuest_layout
11092a9ad023890d3b34cf45e429df2a8ae88b419128sewardj      = {
11102a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          /* Total size of the guest state, in bytes. */
11112a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          .total_sizeB = sizeof(VexGuestARMState),
11122a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11132a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          /* Describe the stack pointer. */
11142a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          .offset_SP = offsetof(VexGuestARMState,guest_R13),
11152a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          .sizeof_SP = 4,
11162a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11172a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          /* Describe the instruction pointer. */
1118d266447c09a99122cbc220edee5ac936eee7a0ddsewardj          .offset_IP = offsetof(VexGuestARMState,guest_R15T),
11192a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          .sizeof_IP = 4,
11202a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11212a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          /* Describe any sections to be regarded by Memcheck as
11222a9ad023890d3b34cf45e429df2a8ae88b419128sewardj             'always-defined'. */
1123d266447c09a99122cbc220edee5ac936eee7a0ddsewardj          .n_alwaysDefd = 10,
11246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
11252a9ad023890d3b34cf45e429df2a8ae88b419128sewardj          /* flags thunk: OP is always defd, whereas DEP1 and DEP2
11262a9ad023890d3b34cf45e429df2a8ae88b419128sewardj             have to be tracked.  See detailed comment in gdefs.h on
11272a9ad023890d3b34cf45e429df2a8ae88b419128sewardj             meaning of thunk fields. */
11286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj          .alwaysDefd
1129d266447c09a99122cbc220edee5ac936eee7a0ddsewardj             = { /* 0 */ ALWAYSDEFD(guest_R15T),
11306c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                 /* 1 */ ALWAYSDEFD(guest_CC_OP),
11316c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                 /* 2 */ ALWAYSDEFD(guest_CC_NDEP),
11326ef84bed9bb3af22060eb1759788034602bbcc88florian                 /* 3 */ ALWAYSDEFD(guest_EMNOTE),
11336c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                 /* 4 */ ALWAYSDEFD(guest_TISTART),
11346c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                 /* 5 */ ALWAYSDEFD(guest_TILEN),
11356c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                 /* 6 */ ALWAYSDEFD(guest_NRADDR),
11366c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                 /* 7 */ ALWAYSDEFD(guest_IP_AT_SYSCALL),
1137d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                 /* 8 */ ALWAYSDEFD(guest_TPIDRURO),
1138d266447c09a99122cbc220edee5ac936eee7a0ddsewardj                 /* 9 */ ALWAYSDEFD(guest_ITSTATE)
11392a9ad023890d3b34cf45e429df2a8ae88b419128sewardj               }
11402a9ad023890d3b34cf45e429df2a8ae88b419128sewardj        };
11412a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11422a9ad023890d3b34cf45e429df2a8ae88b419128sewardj
11432a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*---------------------------------------------------------------*/
1144cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                 guest_arm_helpers.c ---*/
11452a9ad023890d3b34cf45e429df2a8ae88b419128sewardj/*---------------------------------------------------------------*/
1146