1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------------*/ 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- begin host_mips_isel.c ---*/ 4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------------*/ 5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* 7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This file is part of Valgrind, a dynamic binary instrumentation 8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng framework. 9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2010-2013 RT-RK 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mips-valgrind@rt-rk.com 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This program is free software; you can redistribute it and/or 14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng modify it under the terms of the GNU General Public License as 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng published by the Free Software Foundation; either version 2 of the 16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng License, or (at your option) any later version. 17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This program is distributed in the hope that it will be useful, but 19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng General Public License for more details. 22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng You should have received a copy of the GNU General Public License 24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng along with this program; if not, write to the Free Software 25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 02110-1301, USA. 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng The GNU General Public License is contained in the file COPYING. 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "libvex_basictypes.h" 32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "libvex_ir.h" 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "libvex.h" 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "main_util.h" 36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "main_globals.h" 37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "host_generic_regs.h" 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "host_generic_simd64.h" /* for 64-bit SIMD helpers */ 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "host_mips_defs.h" 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- Register Usage Conventions ---*/ 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Integer Regs 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ------------ 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ZERO0 Reserved 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov GPR12:22 Allocateable 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 23 GuestStatePointer 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SP StackFramePointer 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov RA LinkRegister */ 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool mode64 = False; 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Host CPU has FPU and 32 dbl. prec. FP registers. */ 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool fp_mode64 = False; 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* GPR register class for mips32/64 */ 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define HRcGPR(__mode64) (__mode64 ? HRcInt64 : HRcInt32) 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* FPR register class for mips32/64 */ 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define HRcFPR(__mode64) (__mode64 ? HRcFlt64 : HRcFlt32) 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* guest_COND offset */ 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define COND_OFFSET(__mode64) (__mode64 ? 612 : 448) 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISelEnv ---*/ 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This carries around: 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - A mapping from IRTemp to IRType, giving the type of any IRTemp we 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng might encounter. This is computed before insn selection starts, 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng and does not change. 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - A mapping from IRTemp to HReg. This tells the insn selector 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng which virtual register(s) are associated with each IRTemp 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng temporary. This is computed before insn selection starts, and 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng does not change. We expect this mapping to map precisely the 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng same set of IRTemps as the type mapping does. 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - vregmap holds the primary register for the IRTemp. 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - vregmapHI is only used for 64-bit integer-typed 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemps. It holds the identity of a second 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 32-bit virtual HReg, which holds the high half 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng of the value. 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - The code array, that is, the insns selected so far. 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - A counter, for generating new virtual registers. 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov - The host subarchitecture we are selecting insns for. 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This is set at the start and does not change. 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - A Bool for indicating whether we may generate chain-me 97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng instructions for control flow transfers, or whether we must use 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng XAssisted. 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng - The maximum guest address of any guest insn in this block. 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Actually, the address of the highest-addressed byte from any insn 102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng in this block. Is set at the start and does not change. This is 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng used for detecting jumps which are definitely forward-edges from 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng this block, and therefore can be made (chained) to the fast entry 105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng point of the destination, thereby avoiding the destination's 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng event check. 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Note, this is all (well, mostly) host-independent. 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef 112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct { 113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Constant -- are set at the start and do not change. */ 114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTypeEnv* type_env; 115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg* vregmap; 117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg* vregmapHI; 118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int n_vregmap; 119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt hwcaps; 121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool mode64; 122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool fp_mode64; 123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool chainingAllowed; 125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Addr64 max_ga; 126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* These are modified as we go along. */ 128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HInstrArray* code; 129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int vreg_ctr; 130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ISelEnv; 132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg lookupIRTemp(ISelEnv * env, IRTemp tmp) 134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0); 136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp < env->n_vregmap); 137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return env->vregmap[tmp]; 138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void lookupIRTemp64(HReg * vrHI, HReg * vrLO, ISelEnv * env, IRTemp tmp) 141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0); 143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp < env->n_vregmap); 144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(! hregIsInvalid(env->vregmapHI[tmp])); 145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *vrLO = env->vregmap[tmp]; 146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *vrHI = env->vregmapHI[tmp]; 147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void 150663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChenglookupIRTempPair(HReg * vrHI, HReg * vrLO, ISelEnv * env, IRTemp tmp) 151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(env->mode64); 153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp >= 0); 154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(tmp < env->n_vregmap); 155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(! hregIsInvalid(env->vregmapHI[tmp])); 156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *vrLO = env->vregmap[tmp]; 157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *vrHI = env->vregmapHI[tmp]; 158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void addInstr(ISelEnv * env, MIPSInstr * instr) 161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addHInstr(env->code, instr); 163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_traceflags & VEX_TRACE_VCODE) { 164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppMIPSInstr(instr, mode64); 165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("\n"); 166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg newVRegI(ISelEnv * env) 170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg reg = mkHReg(env->vreg_ctr, HRcGPR(env->mode64), 172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng True /*virtual reg */ ); 173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vreg_ctr++; 174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return reg; 175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg newVRegD(ISelEnv * env) 178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg reg = mkHReg(env->vreg_ctr, HRcFlt64, True /*virtual reg */ ); 180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vreg_ctr++; 181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return reg; 182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg newVRegF(ISelEnv * env) 185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg reg = mkHReg(env->vreg_ctr, HRcFPR(env->fp_mode64), 187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng True /*virtual reg */ ); 188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vreg_ctr++; 189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return reg; 190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void add_to_sp(ISelEnv * env, UInt n) 193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg sp = StackPointer(mode64); 195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(n < 256 && (n % 8) == 0); 196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) 197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_DADD, sp, sp, MIPSRH_Imm(True, 198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov toUShort(n)))); 199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_ADD, sp, sp, MIPSRH_Imm(True, 201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov toUShort(n)))); 202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void sub_from_sp(ISelEnv * env, UInt n) 205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg sp = StackPointer(mode64); 207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(n < 256 && (n % 8) == 0); 208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) 209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_DSUB, sp, sp, 210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(True, toUShort(n)))); 211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SUB, sp, sp, 213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(True, toUShort(n)))); 214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Forward declarations ---*/ 218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These are organised as iselXXX and iselXXX_wrk pairs. The 221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselXXX_wrk do the real work, but are not to be called directly. 222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng For each XXX, iselXXX calls its iselXXX_wrk counterpart, then 223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng checks that all returned registers are virtual. You should not 224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng call the _wrk version directly. 225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* 32-bit mode: Compute an I8/I16/I32 into a RH 227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (reg-or-halfword-immediate). 228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng It's important to specify whether the immediate is to be regarded 229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng as signed or not. If yes, this will never return -32768 as an 230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng immediate; this guaranteed that all signed immediates that are 231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return can have their sign inverted if need be. 232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e); 234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH(ISelEnv * env, Bool syned, IRExpr * e); 235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter being an 237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov immediate in the range 1 .. 31 inclusive. Used for doing shift amounts. */ 238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH5u_wrk(ISelEnv * env, IRExpr * e); 239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH5u(ISelEnv * env, IRExpr * e); 240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Compute an I8 into a reg-or-6-bit-unsigned-immediate, the latter being an 242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov immediate in the range 1 .. 63 inclusive. Used for doing shift amounts. */ 243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic MIPSRH *iselWordExpr_RH6u_wrk(ISelEnv * env, IRExpr * e); 244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic MIPSRH *iselWordExpr_RH6u(ISelEnv * env, IRExpr * e); 245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* compute an I8/I16/I32 into a GPR*/ 247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e); 248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselWordExpr_R(ISelEnv * env, IRExpr * e); 249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* compute an I32 into an AMode. */ 251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSAMode *iselWordExpr_AMode_wrk(ISelEnv * env, IRExpr * e, 252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType xferTy); 253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSAMode *iselWordExpr_AMode(ISelEnv * env, IRExpr * e, IRType xferTy); 254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, 256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr * e); 257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt64Expr(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e); 258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* 64-bit mode ONLY: compute an I128 into a GPR64 pair. */ 260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, 261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ISelEnv * env, IRExpr * e); 262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt128Expr(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e); 263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e); 265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSCondCode iselCondCode(ISelEnv * env, IRExpr * e); 266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselDblExpr_wrk(ISelEnv * env, IRExpr * e); 268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselDblExpr(ISelEnv * env, IRExpr * e); 269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e); 271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselFltExpr(ISelEnv * env, IRExpr * e); 272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void set_MIPS_rounding_mode(ISelEnv * env, IRExpr * mode) 274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng rounding mode | MIPS | IR 277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ------------------------ 278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to nearest | 00 | 00 279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to zero | 01 | 11 280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to +infinity | 10 | 10 281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng to -infinity | 11 | 01 282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* rm_MIPS32 = XOR(rm_IR , (rm_IR << 1)) & 2 */ 284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg irrm = iselWordExpr_R(env, mode); 285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp = newVRegI(env); 286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fcsr_old = newVRegI(env); 287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr; 288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, irrm, 290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 1))); 291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_XOR, tmp, irrm, MIPSRH_Reg(tmp))); 292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, irrm, tmp, MIPSRH_Imm(False, 3))); 293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* save old value of FCSR */ 294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_MfFCSR(fcsr_old)); 295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sub_from_sp(env, 8); /* Move SP down 8 bytes */ 296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr = MIPSAMode_IR(0, StackPointer(mode64)); 297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store old FCSR to stack */ 299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(4, am_addr, fcsr_old, mode64)); 300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* set new value of FCSR */ 302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_MtFCSR(irrm)); 303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void set_MIPS_rounding_default(ISelEnv * env) 306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fcsr = newVRegI(env); 308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* load as float */ 309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr; 310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr = MIPSAMode_IR(0, StackPointer(mode64)); 311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, fcsr, am_addr, mode64)); 313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, 8); /* Reset SP */ 315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* set new value of FCSR*/ 317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_MtFCSR(fcsr)); 318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Misc helpers ---*/ 322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Make an int reg-reg move. */ 325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSInstr *mk_iMOVds_RR(HReg r_dst, HReg r_src) 326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(r_dst) == hregClass(r_src)); 328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(r_src) == HRcInt32 || hregClass(r_src) == HRcInt64); 329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSInstr_Alu(Malu_OR, r_dst, r_src, MIPSRH_Reg(r_src)); 330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Function call helpers ---*/ 334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Used only in doHelperCall. See big comment in doHelperCall re 337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng handling of register-parameter args. This function figures out 338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng whether evaluation of an expression might require use of a fixed 339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register. If in doubt return True (safe but suboptimal). 340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool mightRequireFixedRegs(IRExpr * e) 342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->tag) { 344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_RdTmp: 345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Const: 346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Get: 347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return True; 350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Load 2*I32 regs to fp reg */ 354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg mk_LoadRR32toFPR(ISelEnv * env, HReg r_srcHi, HReg r_srcLo) 355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_dst = newVRegD(env); 357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr0, *am_addr1; 358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(r_srcHi) == HRcInt32); 360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(r_srcLo) == HRcInt32); 361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sub_from_sp(env, 16); /* Move SP down 16 bytes */ 363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr0 = MIPSAMode_IR(0, StackPointer(mode64)); 364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr1 = MIPSAMode_IR(4, StackPointer(mode64)); 365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store hi,lo as Ity_I32's */ 367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined (_MIPSEL) 368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(4, am_addr0, r_srcLo, mode64)); 369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(4, am_addr1, r_srcHi, mode64)); 370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined (_MIPSEB) 371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Store(4, am_addr0, r_srcHi, mode64)); 372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Store(4, am_addr1, r_srcLo, mode64)); 373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#else 374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Stop gcc on other platforms complaining about am_addr1 being set 375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov but not used. */ 376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (void)am_addr1; 377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif 378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* load as float */ 380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(True /*load */ , 8, fr_dst, am_addr0)); 381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, 16); /* Reset SP */ 383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return fr_dst; 384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Do a complete function call. |guard| is a Ity_Bit expression 387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng indicating whether or not the call happens. If guard==NULL, the 388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov call is unconditional. |retloc| is set to indicate where the 389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return value is after the call. The caller (of this fn) must 390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov generate code to add |stackAdjustAfterCall| to the stack pointer 391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov after the call is done. */ 392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void doHelperCall(/*OUT*/UInt* stackAdjustAfterCall, 394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*OUT*/RetLoc* retloc, 395436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ISelEnv* env, 396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* guard, 397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRCallee* cee, IRType retTy, IRExpr** args ) 398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSCondCode cc; 400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg argregs[MIPS_N_REGPARMS]; 401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmpregs[MIPS_N_REGPARMS]; 402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool go_fast; 403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int n_args, i, argreg; 404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt argiregs; 405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = INVALID_HREG; 406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Set default returns. We'll update them later if needed. */ 408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *stackAdjustAfterCall = 0; 409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc = mk_RetLoc_INVALID(); 410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* These are used for cross-checking that IR-level constraints on 412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */ 413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt nVECRETs = 0; 414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt nBBPTRs = 0; 415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* MIPS O32 calling convention: up to four registers ($a0 ... $a3) 417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng are allowed to be used for passing integer arguments. They correspond 418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to regs GPR4 ... GPR7. Note that the cee->regparms field is meaningless 419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov on MIPS host (since we only implement one calling convention) and so we 420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng always ignore it. */ 421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* MIPS 64 calling convention: up to four registers ($a0 ... $a7) 423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng are allowed to be used for passing integer arguments. They correspond 424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to regs GPR4 ... GPR11. Note that the cee->regparms field is meaningless 425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov on MIPS host (since we only implement one calling convention) and so we 426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng always ignore it. */ 427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* The return type can be I{64,32,16,8} or V{128,256}. In the 429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov latter two cases, it is expected that |args| will contain the 430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov special node IRExpr_VECRET(), in which case this routine 431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov generates code to allocate space on the stack for the vector 432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return value. Since we are not passing any scalars on the 433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov stack, it is enough to preallocate the return space before 434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov marshalling any arguments, in this case. 435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov |args| may also contain IRExpr_BBPTR(), in which case the value 437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov in the guest state pointer register is passed as the 438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov corresponding argument. */ 439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng n_args = 0; 441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i = 0; args[i]; i++) { 442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* arg = args[i]; 443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (UNLIKELY(arg->tag == Iex_VECRET)) { 444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nVECRETs++; 445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (UNLIKELY(arg->tag == Iex_BBPTR)) { 446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nBBPTRs++; 447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng n_args++; 449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (n_args > MIPS_N_REGPARMS) { 452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("doHelperCall(MIPS): cannot currently handle > 4 or 8 args"); 453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[0] = hregMIPS_GPR4(mode64); 456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[1] = hregMIPS_GPR5(mode64); 457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[2] = hregMIPS_GPR6(mode64); 458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[3] = hregMIPS_GPR7(mode64); 459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[4] = hregMIPS_GPR8(mode64); 460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[5] = hregMIPS_GPR9(mode64); 461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[6] = hregMIPS_GPR10(mode64); 462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[7] = hregMIPS_GPR11(mode64); 463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs = 0; 464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[0] = tmpregs[1] = tmpregs[2] = 465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[3] = tmpregs[4] = tmpregs[5] = 466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[6] = tmpregs[7] = INVALID_HREG; 467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[0] = hregMIPS_GPR4(mode64); 469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[1] = hregMIPS_GPR5(mode64); 470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[2] = hregMIPS_GPR6(mode64); 471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argregs[3] = hregMIPS_GPR7(mode64); 472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs = 0; 473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[0] = tmpregs[1] = tmpregs[2] = tmpregs[3] = INVALID_HREG; 474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* First decide which scheme (slow or fast) is to be used. First assume the 477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fast scheme, and select slow if any contraindications (wow) appear. */ 478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng go_fast = True; 480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* We'll need space on the stack for the return value. Avoid 482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov possible complications with nested calls by using the slow 483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov scheme. */ 484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (retTy == Ity_V128 || retTy == Ity_V256) 485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov go_fast = False; 486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (go_fast && guard) { 488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (guard->tag == Iex_Const && guard->Iex.Const.con->tag == Ico_U1 489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && guard->Iex.Const.con->Ico.U1 == True) { 490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* unconditional */ 491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Not manifestly unconditional -- be conservative. */ 493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng go_fast = False; 494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (go_fast) { 498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n_args; i++) { 499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (mightRequireFixedRegs(args[i])) { 500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng go_fast = False; 501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* At this point the scheme to use has been established. Generate 507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng code to get the arg values into the argument rregs. */ 508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (go_fast) { 509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* FAST SCHEME */ 510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argreg = 0; 511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n_args; i++) { 513436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* arg = args[i]; 514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(argreg < MIPS_N_REGPARMS); 515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType aTy = Ity_INVALID; 517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg))) 518436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov aTy = typeOfIRExpr(env->type_env, arg); 519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (aTy == Ity_I32 || mode64) { 521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argiregs |= (1 << (argreg + 4)); 522436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(argregs[argreg], 523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselWordExpr_R(env, arg))); 524436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 525436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (aTy == Ity_I64) { /* Ity_I64 */ 526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (argreg & 1) { 527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs |= (1 << (argreg + 4)); 529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rHi, rLo; 531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&rHi, &rLo, env, arg); 532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argiregs |= (1 << (argreg + 4)); 533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR( argregs[argreg++], rHi )); 534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs |= (1 << (argreg + 4)); 535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR( argregs[argreg], rLo)); 536436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 537436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (arg->tag == Iex_BBPTR) { 538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); // ATC 539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(argregs[argreg], 540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov GuestStatePointer(mode64))); 541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (arg->tag == Iex_VECRET) { 543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // If this happens, it denotes ill-formed IR. 544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Fast scheme only applies for unconditional calls. Hence: */ 548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_AL; 549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* SLOW SCHEME; move via temporaries */ 551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argreg = 0; 552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n_args; i++) { 554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(argreg < MIPS_N_REGPARMS); 555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRExpr* arg = args[i]; 556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType aTy = Ity_INVALID; 558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg))) 559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov aTy = typeOfIRExpr(env->type_env, arg); 560436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (aTy == Ity_I32 || (mode64 && arg->tag != Iex_BBPTR)) { 562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[argreg] = iselWordExpr_R(env, arg); 563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (aTy == Ity_I64) { /* Ity_I64 */ 565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (argreg & 1) 566436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 567436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (argreg + 1 >= MIPS_N_REGPARMS) 568436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); /* out of argregs */ 569436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg raHi, raLo; 570436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&raHi, &raLo, env, arg); 571436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[argreg] = raLo; 572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 573436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[argreg] = raHi; 574436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 575436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (arg->tag == Iex_BBPTR) { 576436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmpregs[argreg] = GuestStatePointer(mode64); 577436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argreg++; 578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else if (arg->tag == Iex_VECRET) { 580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // If this happens, it denotes ill-formed IR 581436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Now we can compute the condition. We can't do it earlier 586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng because the argument computations could trash the condition 587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng codes. Be a bit clever to handle the common case where the 588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng guard is 1:Bit. */ 589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_AL; 590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (guard) { 591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (guard->tag == Iex_Const && guard->Iex.Const.con->tag == Ico_U1 592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && guard->Iex.Const.con->Ico.U1 == True) { 593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* unconditional -- do nothing */ 594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = iselCondCode(env, guard); 596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng src = iselWordExpr_R(env, guard); 597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Move the args to their final destinations. */ 600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < argreg; i++) { 601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (hregIsInvalid(tmpregs[i])) /* Skip invalid regs */ 602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng continue; 603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* None of these insns, including any spill code that might 604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng be generated, may alter the condition codes. */ 605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng argiregs |= (1 << (i + 4)); 606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(argregs[i], tmpregs[i])); 607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Do final checks, set the return values, and generate the call 611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov instruction proper. */ 612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(nBBPTRs == 0 || nBBPTRs == 1); 613436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(nVECRETs == (retTy == Ity_V128 || retTy == Ity_V256) ? 1 : 0); 614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(*stackAdjustAfterCall == 0); 615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(is_RetLoc_INVALID(*retloc)); 616436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (retTy) { 617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_INVALID: 618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Function doesn't return a value. */ 619436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc = mk_RetLoc_simple(RLPri_None); 620436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 621436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I64: 622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc = mk_RetLoc_simple(mode64 ? RLPri_Int : RLPri_2Int); 623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I32: case Ity_I16: case Ity_I8: 625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc = mk_RetLoc_simple(RLPri_Int); 626436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_V128: 628436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); // ATC 629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc = mk_RetLoc_spRel(RLPri_V128SpRel, 0); 630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *stackAdjustAfterCall = 16; 631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 632436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_V256: 633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); // ATC 634436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc = mk_RetLoc_spRel(RLPri_V256SpRel, 0); 635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *stackAdjustAfterCall = 32; 636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* IR can denote other possible return types, but we don't 639436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov handle those here. */ 640436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 642436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong target = mode64 ? Ptr_to_ULong(cee->addr) : 644436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov toUInt(Ptr_to_ULong(cee->addr)); 645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Finally, generate the call itself. This needs the *retloc value 647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set in the switch above, which is why it's at the end. */ 648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (cc == MIPScc_AL) 649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_CallAlways(cc, (Addr64)target, argiregs, 650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *retloc)); 651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 652436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Call(cc, (Addr64)target, argiregs, src, *retloc)); 653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Integer expression auxiliaries ---*/ 657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* --------------------- AMODEs --------------------- */ 660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Return an AMode which computes the value of the specified 662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng expression, possibly also adding insns to the code list as a 663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng result. The expression may only be a word-size one. 664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool uInt_fits_in_16_bits(UInt u) 667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i = u & 0xFFFF; 669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng i <<= 16; 670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng i >>= 16; 671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool(u == (UInt) i); 672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool uLong_fits_in_16_bits ( ULong u ) 675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Long i = u & 0xFFFFULL; 677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i <<= 48; 678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i >>= 48; 679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return toBool(u == (ULong) i); 680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool uLong_is_4_aligned ( ULong u ) 683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return toBool((u & 3ULL) == 0); 685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool sane_AMode(ISelEnv * env, MIPSAMode * am) 688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (am->tag) { 690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Mam_IR: 691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool(hregClass(am->Mam.IR.base) == HRcGPR(mode64) && 692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hregIsVirtual(am->Mam.IR.base) && 693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uInt_fits_in_16_bits(am->Mam.IR.index)); 694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Mam_RR: 695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool(hregClass(am->Mam.RR.base) == HRcGPR(mode64) && 696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hregIsVirtual(am->Mam.RR.base) && 697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hregClass(am->Mam.RR.index) == HRcGPR(mode64) && 698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hregIsVirtual(am->Mam.RR.index)); 699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("sane_AMode: unknown mips amode tag"); 701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSAMode *iselWordExpr_AMode(ISelEnv * env, IRExpr * e, IRType xferTy) 705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am = iselWordExpr_AMode_wrk(env, e, xferTy); 707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(sane_AMode(env, am)); 708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return am; 709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSAMode *iselWordExpr_AMode_wrk(ISelEnv * env, IRExpr * e, 713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType xferTy) 714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, e); 716436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (env->mode64) { 717436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool aligned4imm = toBool(xferTy == Ity_I32 || xferTy == Ity_I64); 718436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(ty == Ity_I64); 719436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 720436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Add64(expr,i), where i == sign-extend of (i & 0xFFFF) */ 721436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_Add64 722436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && e->Iex.Binop.arg2->tag == Iex_Const 723436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U64 724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && (aligned4imm ? 725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov uLong_is_4_aligned(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64) : True) 726436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && uLong_fits_in_16_bits(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)) { 727436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return MIPSAMode_IR((Int) e->Iex.Binop.arg2->Iex.Const.con->Ico.U64, 728436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselWordExpr_R(env, e->Iex.Binop.arg1)); 729436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 730436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Add64(expr,expr) */ 732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_Add64) { 733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1); 734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_idx = iselWordExpr_R(env, e->Iex.Binop.arg2); 735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return MIPSAMode_RR(r_idx, r_base); 736436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ty == Ity_I32); 739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 740663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */ 741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Binop 742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Binop.op == Iop_Add32 743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Binop.arg2->tag == Iex_Const 744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32 745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && uInt_fits_in_16_bits(e->Iex.Binop.arg2->Iex.Const.con-> Ico.U32)) { 746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSAMode_IR((Int) e->Iex.Binop.arg2->Iex.Const.con->Ico.U32, 747663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselWordExpr_R(env, e->Iex.Binop.arg1)); 748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add32(expr,expr) */ 751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_Add32) { 752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1); 753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_idx = iselWordExpr_R(env, e->Iex.Binop.arg2); 754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSAMode_RR(r_idx, r_base); 756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Doesn't match anything in particular. Generate it into 760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng a register and use that. */ 761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSAMode_IR(0, iselWordExpr_R(env, e)); 762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Integer expressions (64/32/16/8 bit) ---*/ 766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Select insns for an integer-typed expression, and add them to the 769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng code list. Return a reg holding the result. This reg will be a 770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng virtual register. THE RETURNED REG MUST NOT BE MODIFIED. If you 771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng want to modify it, ask for a new vreg, copy it in there, and modify 772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the copy. The register allocator will do its best to map both 773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vregs to the same real register, so the copies will often disappear 774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng later in the game. 775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This should handle expressions of 64, 32, 16 and 8-bit type. 777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng All results are returned in a (mode64 ? 64bit : 32bit) register. 778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng For 16- and 8-bit expressions, the upper (32/48/56 : 16/24) bits 779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng are arbitrary, so you should mask or sign extend partial values 780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if necessary. 781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselWordExpr_R(ISelEnv * env, IRExpr * e) 783663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselWordExpr_R_wrk(env, e); 785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* sanity checks ... */ 786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(r) == HRcGPR(env->mode64)); 788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(r)); 789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r; 790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) 794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 795436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argiregs = 0; 796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, e); 797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I1 798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || ty == Ity_F32 || (ty == Ity_I64 && mode64) 799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || (ty == Ity_I128 && mode64)); 800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->tag) { 802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- TEMP --------- */ 803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_RdTmp: 804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return lookupIRTemp(env, e->Iex.RdTmp.tmp); 805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- LOAD --------- */ 807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Load: { 808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, ty); 810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Load.end != Iend_LE 812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Load.end != Iend_BE) 813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto irreducible; 814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(toUChar(sizeofIRType(ty)), 816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, am_addr, mode64)); 817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- BINARY OP --------- */ 821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Binop: { 822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAluOp aluOp; 823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSShftOp shftOp; 824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Is it an addition or logical style op? */ 826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 827436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Add8: 828436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Add16: 829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Add32: 830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aluOp = Malu_ADD; 831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 832436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sub8: 834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sub16: 835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sub32: 836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aluOp = Malu_SUB; 837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 839436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Sub64: 840436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov aluOp = Malu_DSUB; 841436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 842436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 843436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_And8: 844436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_And16: 845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And32: 846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And64: 847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aluOp = Malu_AND; 848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 849436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 850436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Or8: 851436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Or16: 852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or32: 853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or64: 854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aluOp = Malu_OR; 855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 856436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 857436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Xor8: 858436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Xor16: 859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor32: 860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor64: 861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aluOp = Malu_XOR; 862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 863436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 864436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Add64: 865436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov aluOp = Malu_DADD; 866436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 867436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aluOp = Malu_INVALID; 870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For commutative ops we assume any literal 874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng values are on the second operand. */ 875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (aluOp != Malu_INVALID) { 876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH *ri_srcR = NULL; 879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* get right arg into an RH, in the appropriate way */ 880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (aluOp) { 881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Malu_ADD: 882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Malu_SUB: 883436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Malu_DADD: 884436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Malu_DSUB: 885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ri_srcR = iselWordExpr_RH(env, True /*signed */ , 886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.arg2); 887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Malu_AND: 889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Malu_OR: 890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Malu_XOR: 891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ri_srcR = iselWordExpr_RH(env, False /*unsigned */, 892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.arg2); 893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselWordExpr_R_wrk-aluOp-arg2"); 896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(aluOp, r_dst, r_srcL, ri_srcR)); 898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* a shift? */ 902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shl32: 904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shl64: 905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng shftOp = Mshft_SLL; 906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shr32: 908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shr64: 909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng shftOp = Mshft_SRL; 910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sar32: 912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sar64: 913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng shftOp = Mshft_SRA; 914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng shftOp = Mshft_INVALID; 917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* we assume any literal values are on the second operand. */ 921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (shftOp != Mshft_INVALID) { 922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 924436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *ri_srcR; 925436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) 926436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ri_srcR = iselWordExpr_RH6u(env, e->Iex.Binop.arg2); 927436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 928436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2); 929436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 930436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ty == Ity_I8) { 931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (ty == Ity_I32) { 933436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64 && (shftOp == Mshft_SRA || shftOp == Mshft_SRL)) { 934436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp = newVRegI(env); 935436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_srcL_se = newVRegI(env); 936436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* SRA, SRAV, SRL, SRLV: On 64-bit processors, if GPR rt does 937436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov not contain a sign-extended 32-bit value (bits 63..31 938436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov equal), then the result of the operation is UNPREDICTABLE. 939436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov So we need to sign-extend r_srcL: 940436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DSLLV tmp, r_srcL, 32 941436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DSRAV r_srcL_se, tmp, 32 942436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 943436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tmp, 944436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_srcL, MIPSRH_Imm(False, 32))); 945436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRA, False, r_srcL_se, 946436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp, MIPSRH_Imm(False, 32))); 947436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* And finally do the shift. */ 948436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(shftOp, True /*32bit shift */, 949436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst, r_srcL_se, ri_srcR)); 950436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else 951436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(shftOp, True /*32bit shift */, 952436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst, r_srcL, ri_srcR)); 953436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else if (ty == Ity_I64) { 954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(shftOp, False/*64bit shift */, 956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_srcL, ri_srcR)); 957436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else 958436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov goto irreducible; 959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Cmp*32*(x,y) ? */ 963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_CmpEQ32 964436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || e->Iex.Binop.op == Iop_CmpEQ16 965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpNE32 966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpNE64 967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT32S 968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT32U 969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT64U 970436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || e->Iex.Binop.op == Iop_CmpLE32U 971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE32S 972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE64S 973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT64S 974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpEQ64) { 975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = (e->Iex.Binop.op == Iop_CmpLT32S 977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE32S 978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT64S 979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE64S); 980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool size32; 981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegI(env); 982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r1 = iselWordExpr_R(env, e->Iex.Binop.arg1); 983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r2 = iselWordExpr_R(env, e->Iex.Binop.arg2); 984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSCondCode cc; 986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ32: 989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_EQ; 990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 992436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_CmpEQ16: 993436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc = MIPScc_EQ; 994436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov size32 = True; 995436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNE32: 997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_NE; 998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNE64: 1001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_NE; 1002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 1003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT32S: 1005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LT; 1006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 1007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT32U: 1009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LO; 1010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 1011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT64U: 1013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LO; 1014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 1015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1016436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_CmpLE32U: 1017436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc = MIPScc_LE; 1018436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov size32 = True; 1019436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLE32S: 1021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LE; 1022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 1023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLE64S: 1025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LE; 1026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 1027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT64S: 1029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LT; 1030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ64: 1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_EQ; 1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1037436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("iselCondCode(mips): CmpXX32 or CmpXX64"); 1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Cmp(syned, size32, dst, r1, r2, cc)); 1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_Max32U) { 1045436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp = newVRegI(env); 1046436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg argL = iselWordExpr_R(env, e->Iex.Binop.arg1); 1048436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg argR = iselWordExpr_R(env, e->Iex.Binop.arg2); 1049436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *argRH = iselWordExpr_RH(env, False /*signed */ , 1050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.arg2); 1051436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* max (v0, s0) 1052436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ------------ 1053436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov slt v1, v0, s0 1054436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v0, s0, v1 */ 1055436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1056436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SLT, tmp, argL, argRH)); 1057436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(r_dst, argL)); 1058436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, r_dst, argR, tmp)); 1059436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_Mul32 || e->Iex.Binop.op == Iop_Mul64) { 1063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool sz32 = (e->Iex.Binop.op == Iop_Mul32); 1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 1066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 1067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mul(False/*Unsigned or Signed */ , 1068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng False /*widen */ , 1069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 /*32bit or 64bit */, 1070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_srcL, r_srcR)); 1071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_MullU32 || e->Iex.Binop.op == Iop_MullS32) { 1075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 1077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 1078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo_1 = newVRegI(env); 1079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi_1 = newVRegI(env); 1080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg mask = newVRegI(env); 1081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = toBool(e->Iex.Binop.op == Iop_MullS32); 1083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool size = toBool(e->Iex.Binop.op == Iop_MullS32) 1084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || toBool(e->Iex.Binop.op == Iop_MullU32); 1085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 1086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 1087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mul(syned /*Unsigned or Signed */ , 1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng True /*widen */ , 1089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size /*32bit or 64bit mul */ , 1090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_srcL, r_srcR)); 1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mfhi(tHi)); 1093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mflo(tLo)); 1094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tHi_1, 1096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tHi, MIPSRH_Imm(False, 32))); 1097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(mask, 0xffffffff)); 1099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo, 1100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(mask))); 1101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1, 1103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tLo_1))); 1104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_CmpF64) { 1109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL, r_srcR; 1110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 1111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_srcL = iselFltExpr(env, e->Iex.Binop.arg1); 1112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_srcR = iselFltExpr(env, e->Iex.Binop.arg2); 1113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_srcL = iselDblExpr(env, e->Iex.Binop.arg1); 1115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_srcR = iselDblExpr(env, e->Iex.Binop.arg2); 1116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp = newVRegI(env); 1118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_ccMIPS = newVRegI(env); 1119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_ccIR = newVRegI(env); 1120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_ccIR_b0 = newVRegI(env); 1121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_ccIR_b2 = newVRegI(env); 1122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_ccIR_b6 = newVRegI(env); 1123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Create in dst, the IRCmpF64Result encoded result. */ 1125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* chech for EQ */ 1126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_EQ, tmp, r_srcL, r_srcR)); 1127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, r_ccMIPS, tmp, 1128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 1))); 1129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* chech for UN */ 1130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_UN, tmp, r_srcL, r_srcR)); 1131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS, 1132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tmp))); 1133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* chech for LT */ 1134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_LT, tmp, r_srcL, r_srcR)); 1135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, 1136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp, MIPSRH_Imm(False, 2))); 1137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS, 1138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tmp))); 1139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* chech for GT */ 1140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_NGT, 1141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp, r_srcL, r_srcR)); 1142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, tmp, 1143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 3))); 1144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_NOR, tmp, tmp, MIPSRH_Reg(tmp))); 1146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, tmp, tmp, 1147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 8))); 1148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS, 1149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tmp))); 1150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Map compare result from MIPS to IR, 1151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov conforming to CmpF64 definition. 1152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng FP cmp result | MIPS | IR 1153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng -------------------------- 1154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UN | 0x1 | 0x45 1155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng EQ | 0x2 | 0x40 1156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GT | 0x4 | 0x00 1157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng LT | 0x8 | 0x01 1158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* r_ccIR_b0 = r_ccMIPS[0] | r_ccMIPS[3] */ 1161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRL, True, r_ccIR_b0, r_ccMIPS, 1162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 0x3))); 1163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccIR_b0, r_ccMIPS, 1164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_ccIR_b0))); 1165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, r_ccIR_b0, r_ccIR_b0, 1166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 0x1))); 1167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* r_ccIR_b2 = r_ccMIPS[0] */ 1169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, r_ccIR_b2, r_ccMIPS, 1170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 0x2))); 1171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, r_ccIR_b2, r_ccIR_b2, 1172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 0x4))); 1173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* r_ccIR_b6 = r_ccMIPS[0] | r_ccMIPS[1] */ 1175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRL, True, r_ccIR_b6, 1176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_ccMIPS, MIPSRH_Imm(False, 0x1))); 1177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccIR_b6, r_ccMIPS, 1178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_ccIR_b6))); 1179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, r_ccIR_b6, r_ccIR_b6, 1180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 0x6))); 1181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, r_ccIR_b6, r_ccIR_b6, 1182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 0x40))); 1183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* r_ccIR = r_ccIR_b0 | r_ccIR_b2 | r_ccIR_b6 */ 1185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccIR, r_ccIR_b0, 1186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_ccIR_b2))); 1187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccIR, r_ccIR, 1188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_ccIR_b6))); 1189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_ccIR; 1190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_DivModU64to32 || 1193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.op == Iop_DivModS64to32) { 1194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 1195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 1196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg mask = newVRegI(env); 1197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo_1 = newVRegI(env); 1198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi_1 = newVRegI(env); 1199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = toBool(e->Iex.Binop.op == Iop_DivModS64to32); 1201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 1203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 1204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Div(syned, True, r_srcL, r_srcR)); 1206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mfhi(tHi)); 1207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mflo(tLo)); 1208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tHi_1, tHi, 1210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 32))); 1211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(mask, 0xffffffff)); 1213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo, 1214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(mask))); 1215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1, 1217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tLo_1))); 1218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->Iex.Binop.op == Iop_8HLto16 1223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || e->Iex.Binop.op == Iop_16HLto32) { 1224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi = iselWordExpr_R(env, e->Iex.Binop.arg1); 1225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo = iselWordExpr_R(env, e->Iex.Binop.arg2); 1226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo_1 = newVRegI(env); 1227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi_1 = newVRegI(env); 1228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt shift = 0; 1230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt mask = 0; 1231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Binop.op) { 1232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8HLto16: 1233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov shift = 8; 1234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mask = 0xff; 1235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_16HLto32: 1237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov shift = 16; 1238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mask = 0xffff; 1239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 1241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sll tHi_1, tHi, shift 1245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov and tLo_1, tLo, mask 1246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov or r_dst, tHi_1, tLo_1 */ 1247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tHi_1, tHi, 1248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, shift))); 1249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo, 1250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, mask))); 1251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1, 1252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Reg(tLo_1))); 1253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_32HLto64) { 1257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = iselWordExpr_R(env, e->Iex.Binop.arg1); 1259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = iselWordExpr_R(env, e->Iex.Binop.arg2); 1260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo_1 = newVRegI(env); 1261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi_1 = newVRegI(env); 1262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg mask = newVRegI(env); 1264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tHi_1, tHi, 1266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 32))); 1267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(mask, 0xffffffff)); 1269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo, 1270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(mask))); 1271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1, 1272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tLo_1))); 1273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->Iex.Binop.op == Iop_F32toI64S) { 1278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 1279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valS = newVRegI(env); 1280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmpF = newVRegF(env); 1281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valF = iselFltExpr(env, e->Iex.Binop.arg2); 1282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CVTLS tmpF, valF */ 1284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 1285436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTLS, tmpF, valF)); 1286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 1287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Doubleword Move from Floating Point 1289436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dmfc1 valS, tmpF */ 1290436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_dmfc1, valS, tmpF)); 1291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return valS; 1293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_F64toI32S) { 1296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valD; 1297436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) 1298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valD = iselFltExpr(env, e->Iex.Binop.arg2); 1299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 1300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valD = iselDblExpr(env, e->Iex.Binop.arg2); 1301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg valS = newVRegF(env); 1302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CVTWD valS, valD */ 1305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 1306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpConvert(Mfp_CVTWD, valS, valD)); 1307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_default(env); 1308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word From Floating Point 1310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mfc1 r_dst, valS */ 1311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mfc1, r_dst, valS)); 1312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* -------- DSP ASE -------- */ 1317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* All used cases involving host-side helper calls. */ 1318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void* fn = NULL; 1319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Binop.op) { 1320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_HAdd8Ux4: 1321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fn = &h_generic_calc_HAdd8Ux4; break; 1322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_HSub8Ux4: 1323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fn = &h_generic_calc_HSub8Ux4; break; 1324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_HSub16Sx2: 1325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fn = &h_generic_calc_HSub16Sx2; break; 1326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_QSub8Ux4: 1327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fn = &h_generic_calc_QSub8Ux4; break; 1328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 1329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* What's the retloc? */ 1333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov RetLoc rloc = mk_RetLoc_INVALID(); 1334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ty == Ity_I32) { 1335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rloc = mk_RetLoc_simple(RLPri_Int); 1336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else if (ty == Ity_I64) { 1338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rloc = mode64 ? mk_RetLoc_simple(RLPri_Int) : 1339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mk_RetLoc_simple(RLPri_2Int); 1340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else { 1342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov goto irreducible; 1343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (fn) { 1346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg regL = iselWordExpr_R(env, e->Iex.Binop.arg1); 1347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg regR = iselWordExpr_R(env, e->Iex.Binop.arg2); 1348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg res = newVRegI(env); 1349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(hregMIPS_GPR4(env->mode64), regL)); 1350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(hregMIPS_GPR5(env->mode64), regR)); 1351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs |= (1 << 4); 1352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs |= (1 << 5); 1353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_CallAlways( MIPScc_AL, 1354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (HWord)Ptr_to_ULong(fn), 1355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs, rloc)); 1356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(res, hregMIPS_GPR2(env->mode64))); 1357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return res; 1358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- UNARY OP --------- */ 1363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Unop: { 1364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IROp op_unop = e->Iex.Unop.op; 1365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (op_unop) { 1367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Sto8: 1368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Sto16: 1369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_1Sto32: 1370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Sto16: 1371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_8Sto32: 1372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_16Sto32: 1373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_16Sto64: 1374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_8Sto64: 1375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_1Sto64: { 1376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool sz32; 1379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort amt; 1380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (op_unop) { 1381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Sto8: 1382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov amt = 31; 1383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sz32 = True; 1384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Sto16: 1386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov amt = 31; 1387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sz32 = True; 1388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_1Sto32: 1390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amt = 31; 1391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 = True; 1392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_16Sto32: 1394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amt = 16; 1395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 = True; 1396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_16Sto64: 1398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amt = 48; 1399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 = False; 1400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Sto16: 1402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov amt = 24; 1403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sz32 = True; 1404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_8Sto32: 1406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amt = 24; 1407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 = True; 1408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_8Sto64: 1410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amt = 56; 1411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 = False; 1412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_1Sto64: 1414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amt = 63; 1415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sz32 = False; 1416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(0); 1419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, sz32, r_dst, r_src, 1422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, amt))); 1423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRA, sz32, r_dst, r_dst, 1424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, amt))); 1425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* not(x) = nor(x,x) */ 1429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Not1: { 1430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Unop.arg); 1432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH *r_srcR = MIPSRH_Reg(r_srcL); 1433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(r_dst, 0x1)); 1435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_SUB, r_dst, r_dst, r_srcR)); 1436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Not8: 1440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Not16: 1441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Not32: 1442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Not64: { 1443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Unop.arg); 1445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH *r_srcR = MIPSRH_Reg(r_srcL); 1446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_NOR, r_dst, r_srcL, r_srcR)); 1448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_ReinterpF32asI32: { 1452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselFltExpr(env, e->Iex.Unop.arg); 1453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word From Floating Point 1456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mfc1 r_dst, fr_src */ 1457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mfc1, r_dst, fr_src)); 1458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_ReinterpF64asI64: { 1463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselFltExpr(env, e->Iex.Unop.arg); 1465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Doubleword Move from Floating Point 1468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mfc1 r_dst, fr_src */ 1469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_dmfc1, r_dst, fr_src)); 1470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_F64toI32S: { 1475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valD; 1476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) 1477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valD = iselFltExpr(env, e->Iex.Binop.arg2); 1478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 1479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valD = iselDblExpr(env, e->Iex.Binop.arg2); 1480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valS = newVRegF(env); 1481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 1484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTWD, valS, valD)); 1485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 1486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word From Floating Point 1488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mfc1 r_dst, valS */ 1489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mfc1, r_dst, valS)); 1490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_16to8: 1495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_32to1: 1496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32to8: 1497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32to16: 1498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return iselWordExpr_R(env, e->Iex.Unop.arg); 1499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_32HIto16: { 1501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 1504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst, r_src, MIPSRH_Imm(False, 16))); 1505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1508436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_64to1: 1509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64to8: { 1510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src, r_dst; 1512436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UShort mask = (op_unop == Iop_64to1) ? 0x1 : 0xFF; 1513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst = newVRegI(env); 1514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, r_dst, r_src, 1516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, mask))); 1517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_16HIto8: { 1521436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1522436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 1524436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst, r_src, MIPSRH_Imm(False, 8))); 1525436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Uto8: 1529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Uto32: 1530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Uto64: 1531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Uto16: 1532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_8Uto32: 1533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Uto64: 1534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_16Uto32: 1535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_16Uto64: { 1536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UShort mask = 0; 1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (op_unop) { 1540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Uto64: 1541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 1542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_1Uto8: 1543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_1Uto32: 1544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mask = toUShort(0x1); 1545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1546436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Uto64: 1547436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 1548436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Uto16: 1549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Uto32: 1550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mask = toUShort(0xFF); 1551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_16Uto64: 1553436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 1554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_16Uto32: 1555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mask = toUShort(0xFFFF); 1556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 1559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, r_dst, r_src, 1562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, mask))); 1563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32Uto64: { 1567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1570436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, False /*!32bit shift */, 1571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_src, MIPSRH_Imm(False, 32))); 1572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, False /*!32bit shift */, 1573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_dst, MIPSRH_Imm(False, 32))); 1574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64HIto32: { 1578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (env->mode64) { 1579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1581436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRA, False /*64bit shift */, 1582436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst, r_src, MIPSRH_Imm(True, 32))); 1583436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1584436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rHi, rLo; 1586436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&rHi, &rLo, env, e->Iex.Unop.arg); 1587436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return rHi; 1588436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64to32: { 1592436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (env->mode64) { 1593436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 1594436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = iselWordExpr_R(env, e->Iex.Unop.arg); 1595436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 1596436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rHi, rLo; 1598436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&rHi, &rLo, env, e->Iex.Unop.arg); 1599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return rLo; 1600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64to16: { 1604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(env->mode64); 1605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst = iselWordExpr_R(env, e->Iex.Unop.arg); 1607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32Sto64: { 1611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1612663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1613663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*!32bit shift */, 1615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_src, MIPSRH_Imm(True, 0))); 1616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1619436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_CmpNEZ8: 1620436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_CmpNEZ16: { 1621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp = newVRegI(env); 1623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UShort mask = (op_unop == Iop_CmpNEZ8) ? 0xFF : 0xFFFF; 1625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_AND, tmp, r_src, 1627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, mask))); 1628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Cmp(False, True, r_dst, tmp, 1629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hregMIPS_GPR0(mode64), MIPScc_NE)); 1630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNEZ32: { 1634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Cmp(False, True, r_dst, r_src, 1638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hregMIPS_GPR0(mode64), MIPScc_NE)); 1639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpwNEZ32: { 1643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_SUB, r_dst, hregMIPS_GPR0(mode64), 1647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_src))); 1648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, r_dst, 1650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_src))); 1651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, r_dst, r_dst, 1652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 31))); 1653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Left8: 1657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Left16: 1658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Left32: 1659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Left64: { 1660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (op_unop == Iop_Left64 && !mode64) 1661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto irreducible; 1662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAluOp op = (op_unop == Iop_Left64) ? Malu_DSUB : Malu_SUB; 1665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(op, r_dst, 1666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hregMIPS_GPR0(mode64), 1667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Reg(r_src))); 1668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, r_dst, 1669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(r_src))); 1670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Clz64: 1674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 1675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Clz32: { 1676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSUnaryOp op = (op_unop == Iop_Clz64) ? Mun_DCLZ : Mun_CLZ; 1679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Unary(op, r_dst, r_src)); 1680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNEZ64: { 1684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg hi, lo; 1685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src; 1687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (env->mode64) { 1688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 1689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 1690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_src = newVRegI(env); 1691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&hi, &lo, env, e->Iex.Unop.arg); 1692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, r_src, lo, MIPSRH_Reg(hi))); 1693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Cmp(False, !(env->mode64), r_dst, r_src, 1695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hregMIPS_GPR0(mode64), MIPScc_NE)); 1696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpwNEZ64: { 1700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp1; 1701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp2 = newVRegI(env); 1702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(env->mode64); 1703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tmp1 = iselWordExpr_R(env, e->Iex.Unop.arg); 1704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_DSUB, tmp2, hregMIPS_GPR0(mode64), 1706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tmp1))); 1707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, tmp2, tmp2, MIPSRH_Reg(tmp1))); 1709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRA, False, tmp2, tmp2, 1710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm (False, 63))); 1711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return tmp2; 1712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_128HIto64: { 1715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg rHi, rLo; 1717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt128Expr(&rHi, &rLo, env, e->Iex.Unop.arg); 1718436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return rHi; /* and abandon rLo .. poor wee thing :-) */ 1719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_128to64: { 1722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 1723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg rHi, rLo; 1724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt128Expr(&rHi, &rLo, env, e->Iex.Unop.arg); 1725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return rLo; /* and abandon rLo .. poor wee thing :-) */ 1726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* -------- DSP ASE -------- */ 1733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* All Unop cases involving host-side helper calls. */ 1734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void* fn = NULL; 1735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Unop.op) { 1736436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_CmpNEZ16x2: 1737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fn = &h_generic_calc_CmpNEZ16x2; break; 1738436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_CmpNEZ8x4: 1739436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fn = &h_generic_calc_CmpNEZ8x4; break; 1740436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 1741436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 1742436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1743436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1744436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov RetLoc rloc = mk_RetLoc_INVALID(); 1745436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ty == Ity_I32) { 1746436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rloc = mk_RetLoc_simple(RLPri_Int); 1747436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1748436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else if (ty == Ity_I64) { 1749436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rloc = mode64 ? mk_RetLoc_simple(RLPri_Int) : 1750436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mk_RetLoc_simple(RLPri_2Int); 1751436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else { 1753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov goto irreducible; 1754436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1756436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (fn) { 1757436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg regL = iselWordExpr_R(env, e->Iex.Unop.arg); 1758436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg res = newVRegI(env); 1759436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(hregMIPS_GPR4(env->mode64), regL)); 1760436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs |= (1 << 4); 1761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_CallAlways( MIPScc_AL, 1762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (HWord)Ptr_to_ULong(fn), 1763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov argiregs, rloc)); 1764436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(res, hregMIPS_GPR2(env->mode64))); 1765436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return res; 1766436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1771436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- GET --------- */ 1772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Get: { 1773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 1774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || ((ty == Ity_I64) && mode64)) { 1775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(e->Iex.Get.offset, 1778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 1779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(toUChar(sizeofIRType(ty)), r_dst, am_addr, 1780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mode64)); 1781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1783663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- ITE --------- */ 1787436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iex_ITE: { 1788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((ty == Ity_I8 || ty == Ity_I16 || 1789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ty == Ity_I32 || ((ty == Ity_I64))) && 1790436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1) { 1791436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = iselWordExpr_R(env, e->Iex.ITE.iffalse); 1792436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r1 = iselWordExpr_R(env, e->Iex.ITE.iftrue); 1793436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_cond = iselWordExpr_R(env, e->Iex.ITE.cond); 1794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 1795436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * r_dst = r0 1796436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * movn r_dst, r1, r_cond 1797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 1798436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, r_dst, r1, r_cond)); 1799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1804436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- LITERAL --------- */ 1805436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 32/16/8-bit literals */ 1806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Const: { 1807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Long l; 1808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst *con = e->Iex.Const.con; 1810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (con->tag) { 1811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U64: 1812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!mode64) 1813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto irreducible; 1814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng l = (Long) con->Ico.U64; 1815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U32: 1817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng l = (Long) (Int) con->Ico.U32; 1818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U16: 1820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng l = (Long) (Int) (Short) con->Ico.U16; 1821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U8: 1823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng l = (Long) (Int) (Char) con->Ico.U8; 1824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselIntExpr_R.const(mips)"); 1827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(r_dst, (ULong) l)); 1829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1832436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- CCALL --------- */ 1833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_CCall: { 1834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 1835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ty == e->Iex.CCall.retty); 1836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1837436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* be very restrictive for now. Only 32/64-bit ints allowed for 1838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov args, and 64 and 32 bits for return type. Don't forget to change 1839436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov the RetLoc if more return types are allowed in future. */ 1840436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->Iex.CCall.retty != Ity_I64 && e->Iex.CCall.retty != Ity_I32) 1841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto irreducible; 1842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Marshal args, do the call, clear stack. */ 1844436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt addToSp = 0; 1845436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov RetLoc rloc = mk_RetLoc_INVALID(); 1846436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov doHelperCall(&addToSp, &rloc, env, NULL/*guard*/, e->Iex.CCall.cee, 1847436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov e->Iex.CCall.retty, e->Iex.CCall.args ); 1848436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1849436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(is_sane_RetLoc(rloc)); 1850436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(rloc.pri == RLPri_Int); 1851436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(addToSp == 0); 1852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(r_dst, hregMIPS_GPR2(mode64))); 1853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 1854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1858436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } /* end switch(e->tag) */ 1859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* We get here if no pattern matched. */ 1861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng irreducible: 1862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("--------------->\n"); 1863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_RdTmp) 1864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("Iex_RdTmp \n"); 1865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 1866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselWordExpr_R(mips): cannot reduce tree"); 1868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* --------------------- RH --------------------- */ 1871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Compute an I8/I16/I32 (and I64, in 64-bit mode) into a RH 1873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (reg-or-halfword-immediate). It's important to specify whether the 1874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng immediate is to be regarded as signed or not. If yes, this will 1875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng never return -32768 as an immediate; this guaranteed that all 1876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng signed immediates that are return can have their sign inverted if 1877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng need be. */ 1878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH(ISelEnv * env, Bool syned, IRExpr * e) 1880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH *ri = iselWordExpr_RH_wrk(env, syned, e); 1882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* sanity checks ... */ 1883663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (ri->tag) { 1884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Mrh_Imm: 1885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ri->Mrh.Imm.syned == syned); 1886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (syned) 1887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ri->Mrh.Imm.imm16 != 0x8000); 1888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ri; 1889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Mrh_Reg: 1890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(ri->Mrh.Reg.reg) == HRcGPR(env->mode64)); 1891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(ri->Mrh.Reg.reg)); 1892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ri; 1893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselIntExpr_RH: unknown mips RH tag"); 1895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 1899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e) 1900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong u; 1902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Long l; 1903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, e); 1904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || 1905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ((ty == Ity_I64) && env->mode64)); 1906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* special case: immediate */ 1908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Const) { 1909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst *con = e->Iex.Const.con; 1910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* What value are we aiming to generate? */ 1911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (con->tag) { 1912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Note: Not sign-extending - we carry 'syned' around */ 1913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U64: 1914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(env->mode64); 1915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u = con->Ico.U64; 1916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U32: 1918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u = 0xFFFFFFFF & con->Ico.U32; 1919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U16: 1921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u = 0x0000FFFF & con->Ico.U16; 1922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U8: 1924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng u = 0x000000FF & con->Ico.U8; 1925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselIntExpr_RH.Iex_Const(mips)"); 1928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng l = (Long) u; 1930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Now figure out if it's representable. */ 1931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!syned && u <= 65535) { 1932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSRH_Imm(False /*unsigned */ , toUShort(u & 0xFFFF)); 1933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (syned && l >= -32767 && l <= 32767) { 1935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSRH_Imm(True /*signed */ , toUShort(u & 0xFFFF)); 1936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* no luck; use the Slow Way. */ 1938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* default case: calculate into a register and return that */ 1940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSRH_Reg(iselWordExpr_R(env, e)); 1941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* --------------------- RH5u --------------------- */ 1944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter 1946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng being an immediate in the range 1 .. 31 inclusive. Used for doing 1947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng shift amounts. */ 1948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH5u(ISelEnv * env, IRExpr * e) 1950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH *ri; 1952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ri = iselWordExpr_RH5u_wrk(env, e); 1953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* sanity checks ... */ 1954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (ri->tag) { 1955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Mrh_Imm: 1956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ri->Mrh.Imm.imm16 >= 1 && ri->Mrh.Imm.imm16 <= 31); 1957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(!ri->Mrh.Imm.syned); 1958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ri; 1959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Mrh_Reg: 1960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(ri->Mrh.Reg.reg) == HRcInt32); 1961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(ri->Mrh.Reg.reg)); 1962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ri; 1963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselIntExpr_RH5u: unknown mips RH tag"); 1965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 1969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSRH *iselWordExpr_RH5u_wrk(ISelEnv * env, IRExpr * e) 1970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, e); 1972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ty == Ity_I8); 1973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* special case: immediate */ 1975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Const 1976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Const.con->tag == Ico_U8 1977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Const.con->Ico.U8 >= 1 && e->Iex.Const.con->Ico.U8 <= 31) { 1978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSRH_Imm(False /*unsigned */ , e->Iex.Const.con->Ico.U8); 1979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* default case: calculate into a register and return that */ 1982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPSRH_Reg(iselWordExpr_R(env, e)); 1983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1985436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* --------------------- RH6u --------------------- */ 1986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Only used in 64-bit mode. */ 1988436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic MIPSRH *iselWordExpr_RH6u ( ISelEnv * env, IRExpr * e ) 1989436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 1990436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *ri; 1991436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ri = iselWordExpr_RH6u_wrk(env, e); 1992436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sanity checks ... */ 1993436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (ri->tag) { 1994436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Mrh_Imm: 1995436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(ri->Mrh.Imm.imm16 >= 1 && ri->Mrh.Imm.imm16 <= 63); 1996436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(!ri->Mrh.Imm.syned); 1997436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return ri; 1998436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Mrh_Reg: 1999436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(hregClass(ri->Mrh.Reg.reg) == HRcGPR(env->mode64)); 2000436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(hregIsVirtual(ri->Mrh.Reg.reg)); 2001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return ri; 2002436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 2003436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("iselIntExpr_RH6u: unknown mips64 RI tag"); 2004436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 2006436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2007436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* DO NOT CALL THIS DIRECTLY ! */ 2008436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic MIPSRH *iselWordExpr_RH6u_wrk ( ISelEnv * env, IRExpr * e ) 2009436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 2010436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType ty = typeOfIRExpr(env->type_env, e); 2011436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(ty == Ity_I8); 2012436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2013436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* special case: immediate */ 2014436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_Const 2015436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && e->Iex.Const.con->tag == Ico_U8 2016436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && e->Iex.Const.con->Ico.U8 >= 1 && e->Iex.Const.con->Ico.U8 <= 63) 2017436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov { 2018436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return MIPSRH_Imm(False /*unsigned */ , 2019436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov e->Iex.Const.con->Ico.U8); 2020436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2021436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2022436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* default case: calculate into a register and return that */ 2023436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return MIPSRH_Reg(iselWordExpr_R(env, e)); 2024436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 2025436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2026436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* --------------------- CONDCODE --------------------- */ 2027436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2028436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Generate code to evaluated a bit-typed expression, returning the 2029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng condition code which would correspond when the expression would 2030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng notionally have returned 1. */ 2031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSCondCode iselCondCode(ISelEnv * env, IRExpr * e) 2033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSCondCode cc = iselCondCode_wrk(env,e); 2035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(cc != MIPScc_NV); 2036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return cc; 2037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 2040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e) 2041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e); 2043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(typeOfIRExpr(env->type_env, e) == Ity_I1); 2044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Cmp*32*(x,y) ? */ 2045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_CmpEQ32 2046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpNE32 2047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpNE64 2048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT32S 2049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT32U 2050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT64U 2051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE32S 2052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE64S 2053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT64S 2054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpEQ64) { 2055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = (e->Iex.Binop.op == Iop_CmpLT32S 2057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE32S 2058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLT64S 2059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || e->Iex.Binop.op == Iop_CmpLE64S); 2060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool size32; 2061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegI(env); 2062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r1 = iselWordExpr_R(env, e->Iex.Binop.arg1); 2063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r2 = iselWordExpr_R(env, e->Iex.Binop.arg2); 2064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSCondCode cc; 2066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 2068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ32: 2069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_EQ; 2070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 2071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNE32: 2073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_NE; 2074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 2075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNE64: 2077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_NE; 2078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 2079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT32S: 2081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LT; 2082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 2083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT32U: 2085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LO; 2086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 2087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT64U: 2089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LO; 2090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 2091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLE32S: 2093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LE; 2094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = True; 2095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLE64S: 2097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LE; 2098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 2099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpLT64S: 2101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_LT; 2102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 2103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ64: 2105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc = MIPScc_EQ; 2106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng size32 = False; 2107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vpanic("iselCondCode(mips): CmpXX32 or CmpXX64"); 2110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 2111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Cmp(syned, size32, dst, r1, r2, cc)); 2114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Store result to guest_COND */ 2115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(0, GuestStatePointer(mode64)); 2116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(4, 2118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode_IR(am_addr->Mam.IR.index + COND_OFFSET(mode64), 2119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr->Mam.IR.base), 2120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst, mode64)); 2121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return cc; 2122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Binop.op == Iop_Not1) { 2124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 2125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Unop.arg); 2126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH *r_srcR = MIPSRH_Reg(r_srcL); 2127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(r_dst, 0x1)); 2129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_SUB, r_dst, r_dst, r_srcR)); 2130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Store result to guest_COND */ 2131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(0, GuestStatePointer(mode64)); 2132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(4, 2134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode_IR(am_addr->Mam.IR.index + COND_OFFSET(mode64), 2135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr->Mam.IR.base), 2136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, mode64)); 2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPScc_NE; 2138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_RdTmp || e->tag == Iex_Unop) { 2140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = iselWordExpr_R_wrk(env, e); 2141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Store result to guest_COND */ 2142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(0, GuestStatePointer(mode64)); 2143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(4, 2145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode_IR(am_addr->Mam.IR.index + COND_OFFSET(mode64), 2146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr->Mam.IR.base), 2147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, mode64)); 2148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return MIPScc_EQ; 2149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("iselCondCode(mips): No such tag(%u)\n", e->tag); 2152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 2153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselCondCode(mips)"); 2154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 2157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Integer expressions (128 bit) ---*/ 2158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 2159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* 64-bit mode ONLY: compute a 128-bit value into a register pair, 2161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng which is returned as the first two parameters. As with 2162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselWordExpr_R, these may be either real or virtual regs; in any 2163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case they must not be changed by subsequent code emitted by the 2164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng caller. */ 2165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt128Expr(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e) 2167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(env->mode64); 2169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt128Expr_wrk(rHi, rLo, env, e); 2170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(*rHi) == HRcGPR(env->mode64)); 2171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(*rHi)); 2172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(*rLo) == HRcGPR(env->mode64)); 2173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(*rLo)); 2174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 2177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt128Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, 2178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr * e) 2179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e); 2181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(typeOfIRExpr(env->type_env, e) == Ity_I128); 2182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* read 128-bit IRTemp */ 2184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_RdTmp) { 2185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lookupIRTempPair(rHi, rLo, env, e->Iex.RdTmp.tmp); 2186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- BINARY ops --------- */ 2190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Binop) { 2191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 2192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 64 x 64 -> 128 multiply */ 2193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MullU64: 2194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MullS64: { 2195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo = newVRegI(env); 2196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi = newVRegI(env); 2197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool syned = toBool(e->Iex.Binop.op == Iop_MullS64); 2198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegI(env); 2199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 2200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 2201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Mul(syned, True, False /*64bit mul */ , 2202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst, r_srcL, r_srcR)); 2203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Mfhi(tHi)); 2204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Mflo(tLo)); 2205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = tHi; 2206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = tLo; 2207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 64HLto128(e1,e2) */ 2211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64HLto128: 2212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1); 2213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2); 2214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivModS64to64: { 2217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 2218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 2219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = toBool(e->Iex.Binop.op == Iop_DivModS64to64); 2222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Div(syned, False, r_srcL, r_srcR)); 2224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mfhi(tHi)); 2225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mflo(tLo)); 2226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_DivModU128to64: 2232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_DivModS128to64: { 2233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 2234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg rHi1, rLo1; 2235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt128Expr(&rHi1, &rLo1, env, e->Iex.Binop.arg1); 2236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 2238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = toBool(e->Iex.Binop.op == Iop_DivModS128to64); 2241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Div(syned, False, rLo1, r_srcR)); 2243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mfhi(tHi)); 2244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mflo(tLo)); 2245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("iselInt128Expr(mips64): No such tag(%u)\n", e->tag); 2255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 2256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselInt128Expr(mips64)"); 2257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 2260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Integer expressions (64 bit) ---*/ 2261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 2262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* 32-bit mode ONLY. Compute a 64-bit value into the register 2264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * pair HI, LO. HI and LO must not be changed by subsequent 2265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * code emitted by the caller. */ 2266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt64Expr(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e) 2268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(!env->mode64); 2270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr_wrk(rHi, rLo, env, e); 2271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(*rHi) == HRcInt32); 2272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(*rHi)); 2273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(*rLo) == HRcInt32); 2274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(*rLo)); 2275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY ! */ 2278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e) 2279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e); 2281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(typeOfIRExpr(env->type_env, e) == Ity_I64); 2282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* read 64-bit IRTemp */ 2284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_RdTmp) { 2285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng lookupIRTemp64(rHi, rLo, env, e->Iex.RdTmp.tmp); 2286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 64-bit load */ 2289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Load) { 2290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_addr = iselWordExpr_R(env, e->Iex.Load.addr); 2293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, tHi, MIPSAMode_IR(0, r_addr), mode64)); 2294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, tLo, MIPSAMode_IR(4, r_addr), mode64)); 2295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 64-bit literal */ 2301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Const) { 2302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong w64 = e->Iex.Const.con->Ico.U64; 2303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt wHi = toUInt(w64 >> 32); 2304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt wLo = toUInt(w64); 2305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e->Iex.Const.con->tag == Ico_U64); 2308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (wLo == wHi) { 2310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Save a precious Int register in this special case. */ 2311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(tLo, (ULong) wLo)); 2312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tLo; 2313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 2315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(tHi, (ULong) wHi)); 2316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_LI(tLo, (ULong) wLo)); 2317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 64-bit GET */ 2325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Get) { 2326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(e->Iex.Get.offset, 2330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 2331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, tLo, am_addr, mode64)); 2332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, tHi, nextMIPSAModeInt(am_addr), mode64)); 2333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 64-bit ITE */ 2339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_ITE) { 2340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1); 2341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg expr0Lo, expr0Hi; 2342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg expr1Lo, expr1Hi; 2343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg desLo = newVRegI(env); 2344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg desHi = newVRegI(env); 2345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg cond = iselWordExpr_R(env, e->Iex.ITE.cond); 2346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* expr0Hi:expr0Lo = iffalse */ 2348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* expr1Hi:expr1Lo = iftrue */ 2349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&expr0Hi, &expr0Lo, env, e->Iex.ITE.iffalse); 2350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&expr1Hi, &expr1Lo, env, e->Iex.ITE.iftrue); 2351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* move desLo, expr0Lo 2353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * move desHi, expr0Hi 2354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * movn desLo, expr1Lo, cond 2355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * movn desHi, expr1Hi, cond */ 2356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(desLo, expr0Lo)); 2357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(desHi, expr0Hi)); 2358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, desLo, expr1Lo, cond)); 2359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, desHi, expr1Hi, cond)); 2360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = desHi; 2362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = desLo; 2363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- BINARY ops --------- */ 2367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Binop) { 2368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IROp op_binop = e->Iex.Binop.op; 2369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (op_binop) { 2370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 32 x 32 -> 64 multiply */ 2371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add64 */ 2372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Add64: { 2373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg xLo, xHi, yLo, yHi, carryBit; 2374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi1 = newVRegI(env); 2377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov carryBit = newVRegI(env); 2380436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool size32 = True; 2382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSCondCode cc = MIPScc_LO; 2383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1); 2385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2); 2386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_ADD, tLo, xLo, MIPSRH_Reg(yLo))); 2387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Check carry. */ 2389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Cmp(False, size32, carryBit, tLo, xLo, cc)); 2390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi1, xHi, MIPSRH_Reg(yHi))); 2392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi, tHi1, 2393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Reg(carryBit))); 2394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2395436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = tHi; 2396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = tLo; 2397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Sub64: { 2400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg xLo, xHi, yLo, yHi, borrow; 2401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool size32 = True; 2402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSCondCode cc = MIPScc_LO; 2403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi = newVRegI(env); 2405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo = newVRegI(env); 2406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov borrow = newVRegI(env); 2408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1); 2410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2); 2411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SUB, tLo, xLo, MIPSRH_Reg(yLo))); 2413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Check if borrow is nedded. */ 2415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Cmp(False, size32, borrow, xLo, yLo, cc)); 2416436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_ADD, yHi, yHi, 2418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Reg(borrow))); 2419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SUB, tHi, xHi, MIPSRH_Reg(yHi))); 2420436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MullU32: 2426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MullS32: { 2427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegI(env); 2430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = toBool(op_binop == Iop_MullS32); 2431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1); 2432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 2433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Mul(syned /*Unsigned or Signed */, 2435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng True /*widen */ , True, 2436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_dst, r_srcL, r_srcR)); 2437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mfhi(tHi)); 2438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mflo(tLo)); 2439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivModS64to32: 2445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivModU64to32: { 2446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_sHi, r_sLo; 2447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool syned = toBool(op_binop == Iop_DivModS64to32); 2450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2); 2451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&r_sHi, &r_sLo, env, e->Iex.Binop.arg1); 2453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Div(syned, True, r_sLo, r_srcR)); 2454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mfhi(tHi)); 2455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Mflo(tLo)); 2456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 32HLto64(e1,e2) */ 2463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32HLto64: 2464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = iselWordExpr_R(env, e->Iex.Binop.arg1); 2465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = iselWordExpr_R(env, e->Iex.Binop.arg2); 2466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Or64/And64/Xor64 */ 2469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or64: 2470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And64: 2471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor64: { 2472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg xLo, xHi, yLo, yHi; 2473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAluOp op = (op_binop == Iop_Or64) ? Malu_OR : 2476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (op_binop == Iop_And64) ? Malu_AND : Malu_XOR; 2477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1); 2478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&yHi, &yLo, env, e->Iex.Binop.arg2); 2479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(op, tHi, xHi, MIPSRH_Reg(yHi))); 2480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(op, tLo, xLo, MIPSRH_Reg(yLo))); 2481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Shr64: { 2487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined (_MIPSEL) 2488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 64-bit logical shift right based on what gcc generates: 2489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov <shift>: 2490436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nor v0, zero, a2 2491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sll a3, a1, 0x1 2492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sllv a3, a3, v0 2493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srlv v0, a0, a2 2494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srlv v1, a1, a2 2495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov andi a0, a2, 0x20 2496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov or v0, a3, v0 2497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v0, v1, a0 2498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov jr ra 2499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v1, zero, a0 2500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 2501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a0, a1; 2502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a0tmp = newVRegI(env); 2503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a2 = newVRegI(env); 2504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a3 = newVRegI(env); 2505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v0 = newVRegI(env); 2506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v1 = newVRegI(env); 2507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg zero = newVRegI(env); 2508436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *sa = NULL; 2509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2510436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&a1, &a0, env, e->Iex.Binop.arg1); 2511436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2); 2512436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2513436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sa->tag == Mrh_Imm) { 2514436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16)); 2515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else { 2517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg, 2518436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x3f))); 2519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2521436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(zero, 0x00000000)); 2522436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* nor v0, zero, a2 */ 2523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2))); 2524436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sll a3, a1, 0x1 */ 2525436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a1, MIPSRH_Imm(False, 0x1))); 2527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sllv a3, a3, v0 */ 2528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a3, MIPSRH_Reg(v0))); 2530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srlv v0, a0, a2 */ 2531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v0, a0, MIPSRH_Reg(a2))); 2533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srlv v1, a1, a2 */ 2534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v1, a1, MIPSRH_Reg(a2))); 2536436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* andi a0, a2, 0x20 */ 2537436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, a0tmp, a2, 2538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x20))); 2539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* or v0, a3, v0 */ 2540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, v0, a3, MIPSRH_Reg(v0))); 2541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn v0, v1, a0 */ 2543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v0, v1, a0tmp)); 2544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn v1, zero, a0 */ 2545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, zero, a0tmp)); 2546436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2547436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = v1; 2548436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = v0; 2549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined (_MIPSEB) 2551436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 64-bit logical shift right based on what gcc generates: 2552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov <shift>: 2553436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nor v0, zero, a2 2554436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sll a3, a0, 0x1 2555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sllv a3, a3, v0 2556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srlv v1, a1, a2 2557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov andi v0, a2, 0x20 2558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov or v1, a3, v1 2559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srlv a2, a0, a2 2560436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v1, a2, v0 2561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn a2, zero, v0 2562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov jr ra 2563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov move v0, a2 2564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 2565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a0, a1; 2566436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a2 = newVRegI(env); 2567436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a2tmp = newVRegI(env); 2568436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a3 = newVRegI(env); 2569436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v0 = newVRegI(env); 2570436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v1 = newVRegI(env); 2571436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg zero = newVRegI(env); 2572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *sa = NULL; 2573436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2574436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&a0, &a1, env, e->Iex.Binop.arg1); 2575436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2); 2576436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2577436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sa->tag == Mrh_Imm) { 2578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16)); 2579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else { 2581436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg, 2582436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x3f))); 2583436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2584436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(zero, 0x00000000)); 2586436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* nor v0, zero, a2 */ 2587436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2))); 2588436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sll a3, a0, 0x1 */ 2589436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2590436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a0, MIPSRH_Imm(False, 0x1))); 2591436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sllv a3, a3, v0 */ 2592436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2593436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a3, MIPSRH_Reg(v0))); 2594436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srlv v1, a1, a2 */ 2595436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2596436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v1, a1, MIPSRH_Reg(a2))); 2597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* andi v0, a2, 0x20 */ 2598436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, v0, a2, 2599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x20))); 2600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* or v1, a3, v1 */ 2601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, v1, a3, MIPSRH_Reg(v1))); 2602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srlv a2, a0, a2 */ 2603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a2tmp, a0, MIPSRH_Reg(a2))); 2605436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2606436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn v1, a2, v0 */ 2607436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, a2tmp, v0)); 2608436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn a2, zero, v0 */ 2609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, a2tmp, zero, v0)); 2610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* move v0, a2 */ 2611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(v0, a2tmp)); 2612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2613436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = v0; 2614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = v1; 2615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2616436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif 2617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2619436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Shl64: { 2620436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 64-bit shift left based on what gcc generates: 2621436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov <shift>: 2622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nor v0,zero,a2 2623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srl a3,a0,0x1 2624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srlv a3,a3,v0 2625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sllv v1,a1,a2 2626436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov andi v0,a2,0x20 2627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov or v1,a3,v1 2628436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sllv a2,a0,a2 2629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v1,a2,v0 2630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn a2,zero,v0 2631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov jr ra 2632436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov move v0,a2 2633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 2634436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a0, a1; 2635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a2 = newVRegI(env); 2636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a3 = newVRegI(env); 2637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v0 = newVRegI(env); 2638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v1 = newVRegI(env); 2639436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg zero = newVRegI(env); 2640436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *sa = NULL; 2641436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2642436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&a1, &a0, env, e->Iex.Binop.arg1); 2643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2); 2644436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sa->tag == Mrh_Imm) { 2646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16)); 2647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else { 2649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg, 2650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x3f))); 2651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2652436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2653436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(zero, 0x00000000)); 2654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* nor v0, zero, a2 */ 2655436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2))); 2656436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srl a3, a0, 0x1 */ 2657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2658436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a0, MIPSRH_Imm(False, 0x1))); 2659436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srlv a3, a3, v0 */ 2660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2661436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a3, MIPSRH_Reg(v0))); 2662436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sllv v1, a1, a2 */ 2663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v1, a1, MIPSRH_Reg(a2))); 2665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* andi v0, a2, 0x20 */ 2666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, v0, a2, 2667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x20))); 2668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* or v1, a3, v1 */ 2669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, v1, a3, MIPSRH_Reg(v1))); 2670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sllv a2, a0, a2 */ 2671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a2, a0, MIPSRH_Reg(a2))); 2673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn v1, a2, v0 */ 2675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, a2, v0)); 2676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn a2, zero, v0 */ 2677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, a2, zero, v0)); 2678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(v0, a2)); 2679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = v1; 2681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = v0; 2682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Sar64: { 2686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 64-bit arithmetic shift right based on what gcc generates: 2687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov <shift>: 2688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov nor v0, zero, a2 2689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sll a3, a1, 0x1 2690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sllv a3, a3, v0 2691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srlv v0, a0, a2 2692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov srav v1, a1, a2 2693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov andi a0, a2, 0x20 2694436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sra a1, a1, 0x1f 2695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov or v0, a3, v0 2696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v0, v1, a0 2697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov jr ra 2698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov movn v1, a1, a0 2699436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 2700436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a0, a1; 2701436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a0tmp = newVRegI(env); 2702436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a1tmp = newVRegI(env); 2703436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a2 = newVRegI(env); 2704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg a3 = newVRegI(env); 2705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v0 = newVRegI(env); 2706436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg v1 = newVRegI(env); 2707436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg zero = newVRegI(env); 2708436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH *sa = NULL; 2709436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2710436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&a1, &a0, env, e->Iex.Binop.arg1); 2711436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2); 2712436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sa->tag == Mrh_Imm) { 2714436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16)); 2715436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2716436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else { 2717436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg, 2718436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x3f))); 2719436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2720436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2721436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(zero, 0x00000000)); 2722436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* nor v0, zero, a2 */ 2723436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2))); 2724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sll a3, a1, 0x1 */ 2725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2726436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a1, MIPSRH_Imm(False, 0x1))); 2727436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sllv a3, a3, v0 */ 2728436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */, 2729436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a3, a3, MIPSRH_Reg(v0))); 2730436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srlv v0, a0, a2 */ 2731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */, 2732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v0, a0, MIPSRH_Reg(a2))); 2733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* srav v1, a1, a2 */ 2734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRA, True /* 32bit shift */, 2735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v1, a1, MIPSRH_Reg(a2))); 2736436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* andi a0, a2, 0x20 */ 2737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, a0tmp, a2, 2738436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0x20))); 2739436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* sra a1, a1, 0x1f */ 2740436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRA, True /* 32bit shift */, 2741436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a1tmp, a1, MIPSRH_Imm(False, 0x1f))); 2742436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* or v0, a3, v0 */ 2743436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, v0, a3, MIPSRH_Reg(v0))); 2744436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2745436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn v0, v1, a0 */ 2746436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v0, v1, a0tmp)); 2747436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* movn v1, a1, a0 */ 2748436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, a1tmp, a0tmp)); 2749436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2750436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = v1; 2751436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = v0; 2752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2754436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_F32toI64S: { 2756436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmpD = newVRegD(env); 2757436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valF = iselFltExpr(env, e->Iex.Binop.arg2); 2758436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo = newVRegI(env); 2759436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi = newVRegI(env); 2760436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode *am_addr; 2761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* CVTLS tmpD, valF */ 2763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 2764436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTLS, tmpD, valF)); 2765436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 2766436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sub_from_sp(env, 16); /* Move SP down 16 bytes */ 2768436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr = MIPSAMode_IR(0, StackPointer(mode64)); 2769436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2770436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store as F64 */ 2771436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 8, tmpD, 2772436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr)); 2773436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* load as 2xI32 */ 2774436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined (_MIPSEL) 2775436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(4, tLo, am_addr, mode64)); 2776436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(4, tHi, nextMIPSAModeFloat(am_addr), 2777436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mode64)); 2778436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined (_MIPSEB) 2779436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(4, tHi, am_addr, mode64)); 2780436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(4, tLo, nextMIPSAModeFloat(am_addr), 2781436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mode64)); 2782436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif 2783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2784436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Reset SP */ 2785436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, 16); 2786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2787436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = tHi; 2788436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = tLo; 2789436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2790436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2791436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2792436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- UNARY ops --------- */ 2799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Unop) { 2800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Unop.op) { 2801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_1Sto64: { 2802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselWordExpr_R(env, e->Iex.Unop.arg); 2805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp = newVRegI(env); 2806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, src, 2808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 31))); 2809436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, tmp, 2810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 31))); 2811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(tHi, tmp)); 2813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(tLo, tmp)); 2814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 32Sto64(e) */ 2821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32Sto64: { 2822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselWordExpr_R(env, e->Iex.Unop.arg); 2825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(tHi, src)); 2826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(tLo, src)); 2827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tHi, tHi, 2828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 31))); 2829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2834436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 8Uto64(e) */ 2835436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_8Uto64: { 2836436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo = newVRegI(env); 2837436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi = newVRegI(env); 2838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselWordExpr_R(env, e->Iex.Unop.arg); 2839436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_AND, tLo, src, 2840436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Imm(False, 0xFF))); 2841436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi, hregMIPS_GPR0(mode64), 2842436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSRH_Reg(hregMIPS_GPR0(mode64)))); 2843436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = tHi; 2844436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = tLo; 2845436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2846436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2847436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 32Uto64(e) */ 2849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32Uto64: { 2850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselWordExpr_R(env, e->Iex.Unop.arg); 2853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(tLo, src)); 2854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_ADD, tHi, hregMIPS_GPR0(mode64), 2855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(hregMIPS_GPR0(mode64)))); 2856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2860436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_Left64: { 2862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg yHi, yLo; 2863436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tHi = newVRegI(env); 2864436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tLo = newVRegI(env); 2865436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp = newVRegI(env); 2866436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp1 = newVRegI(env); 2867436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp2 = newVRegI(env); 2868436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg zero = newVRegI(env); 2869436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSCondCode cc = MIPScc_LO; 2870436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2871436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* yHi:yLo = arg */ 2872436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&yHi, &yLo, env, e->Iex.Unop.arg); 2873436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* zero = 0 */ 2874436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LI(zero, 0x00000000)); 2875436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2876436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* tmp2:tmp1 = 0 - (yHi:yLo)*/ 2877436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2, zero, MIPSRH_Reg(yLo))); 2878436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Cmp(False, True, tmp1, zero, tmp2, cc)); 2879436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp, zero, MIPSRH_Reg(yHi))); 2880436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp1, tmp, MIPSRH_Reg(tmp1))); 2881436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2882436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* So now we have tmp2:tmp1 = -arg. To finish off, or 'arg' 2883436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov back in, so as to give the final result 2884436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tHi:tLo = arg | -arg. */ 2885436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, tHi, yHi, MIPSRH_Reg(tmp1))); 2886436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Alu(Malu_OR, tLo, yLo, MIPSRH_Reg(tmp2))); 2887436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rHi = tHi; 2888436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *rLo = tLo; 2889436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 2890436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2891436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpwNEZ64: { 2893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg srcLo, srcHi; 2894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp1 = newVRegI(env); 2895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp2 = newVRegI(env); 2896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* srcHi:srcLo = arg */ 2897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&srcHi, &srcLo, env, e->Iex.Unop.arg); 2898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* tmp1 = srcHi | srcLo */ 2899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, tmp1, srcLo, 2900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(srcHi))); 2901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* tmp2 = (tmp1 | -tmp1) >>s 31 */ 2902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2, hregMIPS_GPR0(mode64), 2904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Reg(tmp1))); 2905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Alu(Malu_OR, tmp2, tmp2, MIPSRH_Reg(tmp1))); 2907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp2, tmp2, 2908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSRH_Imm(False, 31))); 2909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tmp2; 2910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tmp2; 2911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_ReinterpF64asI64: { 2915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tLo = newVRegI(env); 2916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tHi = newVRegI(env); 2917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr; 2918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselDblExpr(env, e->Iex.Unop.arg); 2919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2920436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sub_from_sp(env, 16); /* Move SP down 16 bytes */ 2921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr = MIPSAMode_IR(0, StackPointer(mode64)); 2922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2923436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store as F64 */ 2924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 8, fr_src, 2925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr)); 2926436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* load as 2xI32 */ 2927436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined (_MIPSEL) 2928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, tLo, am_addr, mode64)); 2929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Load(4, tHi, nextMIPSAModeFloat(am_addr), 2930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mode64)); 2931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined (_MIPSEB) 2932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(4, tHi, am_addr, mode64)); 2933436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(4, tLo, nextMIPSAModeFloat(am_addr), 2934436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mode64)); 2935436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif 2936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2937436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Reset SP */ 2938436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, 16); 2939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rHi = tHi; 2941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *rLo = tLo; 2942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 2943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2944436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("UNARY: No such op: "); 2947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIROp(e->Iex.Unop.op); 2948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("\n"); 2949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("iselInt64Expr(mips): No such tag(%u)\n", e->tag); 2954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 2955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselInt64Expr(mips)"); 2956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 2959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Floating point expressions (32 bit) ---*/ 2960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 2961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Nothing interesting here; really just wrappers for 2963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 64-bit stuff. */ 2964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselFltExpr(ISelEnv * env, IRExpr * e) 2965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselFltExpr_wrk(env, e); 2967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(r)); 2968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r; 2969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY */ 2972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) 2973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, e); 2975436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(ty == Ity_F32 || (ty == Ity_F64 && fp_mode64)); 2976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_RdTmp) { 2978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return lookupIRTemp(env, e->Iex.RdTmp.tmp); 2979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Load) { 2982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e->Iex.Load.ty == Ity_F32 2983436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || (e->Iex.Load.ty == Ity_F64 && fp_mode64)); 2984436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst; 2985436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode *am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, ty); 2986436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->Iex.Load.ty == Ity_F64) { 2987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = newVRegD(env); 2988436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, r_dst, am_addr)); 2989436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 2990436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = newVRegF(env); 2991436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(True /*load */, 4, r_dst, am_addr)); 2992436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 2994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Get) { 2997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(e->Iex.Get.offset, 2998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 2999436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst; 3000436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->Iex.Load.ty == Ity_F64) { 3001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = newVRegD(env); 3002436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, r_dst, am_addr)); 3003436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3004436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = newVRegF(env); 3005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(True /*load */, 4, r_dst, am_addr)); 3006436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 3008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Unop) { 3011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Unop.op) { 3012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_ReinterpI32asF32: { 3013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselWordExpr_R(env, e->Iex.Unop.arg); 3014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegF(env); 3015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3016436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word to Floating Point 3017436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mtc1 r_dst, valS */ 3018436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mtc1, r_dst, fr_src)); 3019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 3021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_F32toF64: { 3023436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(fp_mode64); 3024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3025436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegD(env); 3026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3027436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTDS, dst, src)); 3028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3030436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_ReinterpI64asF64: { 3031436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst; 3032436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 3033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselWordExpr_R(env, e->Iex.Unop.arg); 3034436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = newVRegF(env); 3035436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Doubleword to Floating Point 3036436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dmtc1 r_dst, fr_src */ 3037436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_dmtc1, r_dst, fr_src)); 3038436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3039436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg Hi, Lo; 3040436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = newVRegD(env); 3041436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&Hi, &Lo, env, e->Iex.Unop.arg); 3042436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_dst = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ 3043436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3044436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 3045436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3046436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_I32StoF64: { 3047436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(fp_mode64); 3048436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegF(env); 3049436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp = newVRegF(env); 3050436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 3051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3052436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word to Floating Point 3053436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mtc1 tmp, r_src */ 3054436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mtc1, tmp, r_src)); 3055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3056436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* and do convert */ 3057436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTDW, dst, tmp)); 3058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3059436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3060436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AbsF32: 3062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AbsF64: { 3063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool sz32 = e->Iex.Unop.op == Iop_AbsF32; 3064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegF(env); 3066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpUnary(sz32 ? Mfp_ABSS : Mfp_ABSD, dst, src)); 3067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_NegF32: 3070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_NegF64: { 3071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool sz32 = e->Iex.Unop.op == Iop_NegF32; 3072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegF(env); 3074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpUnary(sz32 ? Mfp_NEGS : Mfp_NEGD, dst, src)); 3075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3077436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_RoundF64toF64_ZERO: { 3078436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 3079436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3080436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegF(env); 3081436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_TRULD, dst, src)); 3082436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3083436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3084436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_RoundF64toF64_NEAREST: { 3085436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 3086436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3087436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegF(env); 3088436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_ROUNDLD, dst, src)); 3089436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3090436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3091436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_RoundF64toF64_NegINF: { 3092436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 3093436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3094436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegF(env); 3095436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_FLOORLD, dst, src)); 3096436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3097436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3098436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_RoundF64toF64_PosINF: { 3099436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 3100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegF(env); 3102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CEILLD, dst, src)); 3103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Triop) { 3112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Triop.details->op) { 3113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivF32: 3114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivF64: 3115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MulF32: 3116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MulF64: 3117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AddF32: 3118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AddF64: 3119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SubF32: 3120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SubF64: { 3121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSFpOp op = 0; 3122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg argL = iselFltExpr(env, e->Iex.Triop.details->arg2); 3123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg argR = iselFltExpr(env, e->Iex.Triop.details->arg3); 3124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegF(env); 3125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Triop.details->op) { 3126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivF32: 3127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_DIVS; 3128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_DivF64: 3130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(fp_mode64); 3131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_DIVD; 3132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MulF32: 3134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_MULS; 3135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MulF64: 3137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(fp_mode64); 3138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MULD; 3139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AddF32: 3141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_ADDS; 3142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_AddF64: 3144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(fp_mode64); 3145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_ADDD; 3146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SubF32: 3148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_SUBS; 3149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_SubF64: 3151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(fp_mode64); 3152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_SUBD; 3153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(0); 3156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Triop.details->arg1); 3158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpBinary(op, dst, argL, argR)); 3159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Binop) { 3168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 3169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_F64toF32: { 3170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valD; 3171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) 3172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valD = iselFltExpr(env, e->Iex.Binop.arg2); 3173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 3174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valD = iselDblExpr(env, e->Iex.Binop.arg2); 3175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg valS = newVRegF(env); 3176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpConvert(Mfp_CVTSD, valS, valD)); 3179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_default(env); 3180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return valS; 3181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_RoundF32toInt: { 3184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg valS = newVRegF(env); 3185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg valF = iselFltExpr(env, e->Iex.Binop.arg2); 3186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpConvert(Mfp_CVTWS, valS, valF)); 3189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_default(env); 3190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return valS; 3191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_RoundF64toInt: { 3194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valS = newVRegF(env); 3195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg valF = iselFltExpr(env, e->Iex.Binop.arg2); 3196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTLD, valS, valF)); 3199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return valS; 3201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_I32StoF32: { 3204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegF(env); 3205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); 3206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg tmp = newVRegF(env); 3207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word to Floating Point 3209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mtc1 tmp, fr_src */ 3210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mtc1, tmp, fr_src)); 3211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTSW, r_dst, tmp)); 3214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 3217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_I64StoF64: { 3220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegF(env); 3221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode *am_addr; 3222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp, fr_src; 3223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 3224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp = newVRegF(env); 3225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); 3226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move SP down 8 bytes */ 3227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sub_from_sp(env, 8); 3228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr = MIPSAMode_IR(0, StackPointer(mode64)); 3229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store as I64 */ 3231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Store(8, am_addr, fr_src, mode64)); 3232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* load as Ity_F64 */ 3234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, tmp, am_addr)); 3235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Reset SP */ 3237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, 8); 3238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg Hi, Lo; 3240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp = newVRegD(env); 3241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&Hi, &Lo, env, e->Iex.Binop.arg2); 3242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ 3243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTDL, r_dst, tmp)); 3247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 3250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_I64StoF32: { 3253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegF(env); 3254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode *am_addr; 3255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg fr_src, tmp; 3256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 3257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp = newVRegF(env); 3258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); 3259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move SP down 8 bytes */ 3260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sub_from_sp(env, 8); 3261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr = MIPSAMode_IR(0, StackPointer(mode64)); 3262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store as I64 */ 3264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Store(8, am_addr, fr_src, mode64)); 3265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* load as Ity_F64 */ 3267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, tmp, am_addr)); 3268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Reset SP */ 3270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, 8); 3271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg Hi, Lo; 3273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp = newVRegD(env); 3274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&Hi, &Lo, env, e->Iex.Binop.arg2); 3275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tmp = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ 3276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTSL, r_dst, tmp)); 3280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_default(env); 3281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 3283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SqrtF32: 3286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SqrtF64: { 3287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool sz32 = e->Iex.Binop.op == Iop_SqrtF32; 3288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselFltExpr(env, e->Iex.Binop.arg2); 3289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegF(env); 3290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpUnary(sz32 ? Mfp_SQRTS : Mfp_SQRTD, dst, 3292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng src)); 3293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_MIPS_rounding_default(env); 3294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_Qop) { 3303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Qop.details->op) { 3304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF32: 3305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF64: 3306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF32: 3307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF64: { 3308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSFpOp op = 0; 3309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Qop.details->op) { 3310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF32: 3311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MADDS; 3312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF64: 3314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MADDD; 3315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF32: 3317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MSUBS; 3318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF64: 3320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MSUBD; 3321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 3323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 3324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegF(env); 3326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src1 = iselFltExpr(env, e->Iex.Qop.details->arg2); 3327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src2 = iselFltExpr(env, e->Iex.Qop.details->arg3); 3328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src3 = iselFltExpr(env, e->Iex.Qop.details->arg4); 3329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Qop.details->arg1); 3330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpTernary(op, dst, 3331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov src1, src2, src3)); 3332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 3337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_TruncF64asF32) { 3342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* This is quite subtle. The only way to do the relevant 3343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng truncation is to do a single-precision store and then a 3344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng double precision load to get it back into a register. The 3345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng problem is, if the data is then written to memory a second 3346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng time, as in 3347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng STbe(...) = TruncF64asF32(...) 3349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng then will the second truncation further alter the value? The 3351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng answer is no: flds (as generated here) followed by fsts 3352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (generated for the STbe) is the identity function on 32-bit 3353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng floats, so we are safe. 3354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Another upshot of this is that if iselStmt can see the 3356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng entirety of 3357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng STbe(...) = TruncF64asF32(arg) 3359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng then it can short circuit having to deal with TruncF64asF32 3361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng individually; instead just compute arg into a 64-bit FP 3362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register and do 'fsts' (since that itself does the 3363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng truncation). 3364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng We generate pretty poor code here (should be ok both for 3366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 32-bit and 64-bit mode); but it is expected that for the most 3367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng part the latter optimisation will apply and hence this code 3368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng will not often be used. 3369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 3370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fsrc = iselDblExpr(env, e->Iex.Unop.arg); 3371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fdst = newVRegF(env); 3372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *zero_r1 = MIPSAMode_IR(0, StackPointer(mode64)); 3373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sub_from_sp(env, 16); 3375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* store as F32, hence truncating */ 3376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 4, fsrc, zero_r1)); 3377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* and reload. Good huh?! (sigh) */ 3378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(True /*load */ , 4, fdst, zero_r1)); 3379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng add_to_sp(env, 16); 3380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return fdst; 3381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- ITE --------- */ 3384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_ITE) { 3385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ty == Ity_F64 3386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1) { 3387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(mode64); 3388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r0 = iselFltExpr(env, e->Iex.ITE.iffalse); 3389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r1 = iselFltExpr(env, e->Iex.ITE.iftrue); 3390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_cond = iselWordExpr_R(env, e->Iex.ITE.cond); 3391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegF(env); 3392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpUnary(Mfp_MOVD, r_dst, r0)); 3393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MFpMoveCond_movnd, r_dst, r1, 3394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_cond)); 3395436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return r_dst; 3396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("iselFltExpr(mips): No such tag(0x%x)\n", e->tag); 3400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 3401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselFltExpr_wrk(mips)"); 3402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselDblExpr(ISelEnv * env, IRExpr * e) 3405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselDblExpr_wrk(env, e); 3407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregClass(r) == HRcFlt64); 3408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(hregIsVirtual(r)); 3409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r; 3410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* DO NOT CALL THIS DIRECTLY */ 3413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic HReg iselDblExpr_wrk(ISelEnv * env, IRExpr * e) 3414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, e); 3416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e); 3417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(ty == Ity_F64); 3418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_RdTmp) { 3420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return lookupIRTemp(env, e->Iex.RdTmp.tmp); 3421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- LOAD --------- */ 3424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_Load) { 3425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegD(env); 3426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr; 3427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(e->Iex.Load.ty == Ity_F64); 3428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, ty); 3429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(True /*load */ , 8, r_dst, am_addr)); 3430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 3431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- GET --------- */ 3434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Get) { 3435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = newVRegD(env); 3437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(e->Iex.Get.offset, 3438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 3439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(True /*load */ , 8, r_dst, am_addr)); 3440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 3441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Unop) { 3444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSFpOp fpop = Mfp_INVALID; 3445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Unop.op) { 3446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_NegF64: 3447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpop = Mfp_NEGD; 3448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AbsF64: 3450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fpop = Mfp_ABSD; 3451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_F32toF64: { 3453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(!mode64); 3454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselFltExpr(env, e->Iex.Unop.arg); 3455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegD(env); 3456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTDS, dst, src)); 3458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_ReinterpI64asF64: { 3461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg Hi, Lo; 3462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegD(env); 3463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&Hi, &Lo, env, e->Iex.Unop.arg); 3465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dst = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ 3467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_I32StoF64: { 3470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(!mode64); 3471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegD(env); 3472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg tmp = newVRegF(env); 3473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); 3474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Move Word to Floating Point 3476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov mtc1 tmp, r_src */ 3477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mtc1, tmp, r_src)); 3478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* and do convert */ 3480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTDW, dst, tmp)); 3481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (fpop != Mfp_INVALID) { 3489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselDblExpr(env, e->Iex.Unop.arg); 3490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegD(env); 3491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpUnary(fpop, dst, src)); 3492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Binop) { 3497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Binop.op) { 3498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_RoundF64toInt: { 3499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselDblExpr(env, e->Iex.Binop.arg2); 3500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegD(env); 3501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpConvert(Mfp_CVTLD, dst, src)); 3504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_SqrtF64: { 3510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg src = iselDblExpr(env, e->Iex.Binop.arg2); 3511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegD(env); 3512436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); 3513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpUnary(Mfp_SQRTD, dst, src)); 3514436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_Triop) { 3525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Triop.details->op) { 3526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivF64: 3527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivF32: 3528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MulF64: 3529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AddF64: 3530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SubF64: { 3531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSFpOp op = 0; 3532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg argL = iselDblExpr(env, e->Iex.Triop.details->arg2); 3533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg argR = iselDblExpr(env, e->Iex.Triop.details->arg3); 3534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg dst = newVRegD(env); 3535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Triop.details->op) { 3536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_DivF64: 3537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_DIVD; 3538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_DivF32: 3540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_DIVS; 3541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_MulF64: 3543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_MULD; 3544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AddF64: 3546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_ADDD; 3547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_SubF64: 3549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op = Mfp_SUBD; 3550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(0); 3553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3554436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Triop.details->arg1); 3555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpBinary(op, dst, argL, argR)); 3556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dst; 3558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 3560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_Qop) { 3565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Qop.details->op) { 3566436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF32: 3567436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF64: 3568436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF32: 3569436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF64: { 3570436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSFpOp op = 0; 3571436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (e->Iex.Qop.details->op) { 3572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF32: 3573436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MADDS; 3574436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3575436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MAddF64: 3576436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MADDD; 3577436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF32: 3579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MSUBS; 3580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3581436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Iop_MSubF64: 3582436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov op = Mfp_MSUBD; 3583436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3584436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 3585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 3586436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3587436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = newVRegD(env); 3588436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src1 = iselDblExpr(env, e->Iex.Qop.details->arg2); 3589436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src2 = iselDblExpr(env, e->Iex.Qop.details->arg3); 3590436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src3 = iselDblExpr(env, e->Iex.Qop.details->arg4); 3591436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_mode(env, e->Iex.Qop.details->arg1); 3592436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpTernary(op, dst, 3593436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov src1, src2, src3)); 3594436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_MIPS_rounding_default(env); 3595436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return dst; 3596436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3598436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 3599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- ITE --------- */ 3604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (e->tag == Iex_ITE) { 3605436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ty == Ity_F64 3606436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1) { 3607436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r0 = iselDblExpr(env, e->Iex.ITE.iffalse); 3608436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r1 = iselDblExpr(env, e->Iex.ITE.iftrue); 3609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_cond = iselWordExpr_R(env, e->Iex.ITE.cond); 3610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = newVRegD(env); 3611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpUnary(Mfp_MOVD, r_dst, r0)); 3613436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_MoveCond(MFpMoveCond_movnd, r_dst, r1, 3614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r_cond)); 3615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return r_dst; 3616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3618663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("iselDblExpr(mips): No such tag(%u)\n", e->tag); 3620663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 3621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselDblExpr_wrk(mips)"); 3622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 3625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Statements ---*/ 3626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 3627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselStmt(ISelEnv * env, IRStmt * stmt) 3629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_traceflags & VEX_TRACE_VCODE) { 3631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("\n-- "); 3632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRStmt(stmt); 3634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("\n"); 3635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (stmt->tag) { 3638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- STORE --------- */ 3639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_Store: { 3640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr; 3641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data); 3642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*constructs addressing mode from address provided */ 3644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd); 3645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tyd == Ity_I8 || tyd == Ity_I16 || tyd == Ity_I32 || 3647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (mode64 && (tyd == Ity_I64))) { 3648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, stmt->Ist.Store.data); 3649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(tyd)), 3650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr, r_src, mode64)); 3651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!mode64 && (tyd == Ity_I64)) { 3654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg vHi, vLo; 3655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_addr = iselWordExpr_R(env, stmt->Ist.Store.addr); 3656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&vHi, &vLo, env, stmt->Ist.Store.data); 3658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(Ity_I32)), 3660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode_IR(0, r_addr), vHi, mode64)); 3661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(Ity_I32)), 3662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode_IR(4, r_addr), vLo, mode64)); 3663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tyd == Ity_F32) { 3666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselFltExpr(env, stmt->Ist.Store.data); 3667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 4, fr_src, 3668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr)); 3669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (tyd == Ity_F64 && mode64) { 3672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg fr_src = iselFltExpr(env, stmt->Ist.Store.data); 3673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 8, fr_src, 3674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr)); 3675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!mode64 && (tyd == Ity_F64)) { 3678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg fr_src = iselDblExpr(env, stmt->Ist.Store.data); 3679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 8, fr_src, 3680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov am_addr)); 3681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- PUT --------- */ 3688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_Put: { 3689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data); 3690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || 3692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (ty == Ity_I64 && mode64)) { 3693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, stmt->Ist.Put.data); 3694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(stmt->Ist.Put.offset, 3695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 3696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(ty)), 3697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr, r_src, mode64)); 3698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3700436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_I64 && !mode64) { 3702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg vHi, vLo; 3703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(stmt->Ist.Put.offset, 3704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 3705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr4 = MIPSAMode_IR(stmt->Ist.Put.offset + 4, 3706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 3707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselInt64Expr(&vHi, &vLo, env, stmt->Ist.Put.data); 3708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(Ity_I32)), 3709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr, vLo, mode64)); 3710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_Store(toUChar(sizeofIRType(Ity_I32)), 3711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr4, vHi, mode64)); 3712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3715436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_F32) { 3717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselFltExpr(env, stmt->Ist.Put.data); 3718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(stmt->Ist.Put.offset, 3719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 3720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 4, fr_src, 3721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr)); 3722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_F64) { 3726436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg fr_src = iselFltExpr(env, stmt->Ist.Put.data); 3727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *am_addr = MIPSAMode_IR(stmt->Ist.Put.offset, 3728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng GuestStatePointer(mode64)); 3729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 8, fr_src, 3730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng am_addr)); 3731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3735663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3736663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- TMP --------- */ 3737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_WrTmp: { 3738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp tmp = stmt->Ist.WrTmp.tmp; 3739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType ty = typeOfIRTemp(env->type_env, tmp); 3740663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I1) { 3742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = lookupIRTemp(env, tmp); 3743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, stmt->Ist.WrTmp.data); 3744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, mk_iMOVds_RR(r_dst, r_src)); 3745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3747663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_I64) { 3749436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 3750436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = lookupIRTemp(env, tmp); 3751436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_src = iselWordExpr_R(env, stmt->Ist.WrTmp.data); 3752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(r_dst, r_src)); 3753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3754436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rHi, rLo, dstHi, dstLo; 3756436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt64Expr(&rHi, &rLo, env, stmt->Ist.WrTmp.data); 3757436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lookupIRTemp64(&dstHi, &dstLo, env, tmp); 3758436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(dstHi, rHi)); 3759436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(dstLo, rLo)); 3760436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3764436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64 && ty == Ity_I128) { 3765436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rHi, rLo, dstHi, dstLo; 3766436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov iselInt128Expr(&rHi, &rLo, env, stmt->Ist.WrTmp.data); 3767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lookupIRTempPair(&dstHi, &dstLo, env, tmp); 3768436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(dstHi, rHi)); 3769436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(dstLo, rLo)); 3770436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_F32) { 3774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_dst = lookupIRTemp(env, tmp); 3775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg fr_src = iselFltExpr(env, stmt->Ist.WrTmp.data); 3776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_FpUnary(Mfp_MOVS, fr_dst, fr_src)); 3777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ty == Ity_F64) { 3781436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 3782436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselFltExpr(env, stmt->Ist.WrTmp.data); 3783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = lookupIRTemp(env, tmp); 3784436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpUnary(Mfp_MOVD, dst, src)); 3785436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3787436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg src = iselDblExpr(env, stmt->Ist.WrTmp.data); 3788436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = lookupIRTemp(env, tmp); 3789436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_FpUnary(Mfp_MOVD, dst, src)); 3790436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3791436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- Call to DIRTY helper --------- */ 3797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_Dirty: { 3798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRDirty *d = stmt->Ist.Dirty.details; 3799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3800436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Figure out the return type, if any. */ 3801436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType retty = Ity_INVALID; 3802436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (d->tmp != IRTemp_INVALID) 3803436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov retty = typeOfIRTemp(env->type_env, d->tmp); 3804436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3805436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Throw out any return types we don't know about. */ 3806436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool retty_ok = False; 3807436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (retty) { 3808436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_INVALID: /* Function doesn't return anything. */ 3809436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_V128: 3810436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I64: case Ity_I32: case Ity_I16: case Ity_I8: 3811436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov retty_ok = True; break; 3812436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 3813436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3814436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3815436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3816436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!retty_ok) 3817436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; /* will go to stmt_fail: */ 3818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3819436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Marshal args, do the call, clear stack, set the return value 3820436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to 0x555..555 if this is a conditional call that returns a 3821436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov value and the call is skipped. */ 3822436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt addToSp = 0; 3823436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov RetLoc rloc = mk_RetLoc_INVALID(); 3824436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov doHelperCall( &addToSp, &rloc, env, d->guard, d->cee, retty, d->args ); 3825436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(is_sane_RetLoc(rloc)); 3826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Now figure out what to do with the returned value, if any. */ 3828436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (retty) { 3829436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_INVALID: { 3830436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* No return value. Nothing to do. */ 3831436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(d->tmp == IRTemp_INVALID); 3832436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(rloc.pri == RLPri_None); 3833436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(addToSp == 0); 3834436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3835436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3836436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I32: case Ity_I16: case Ity_I8: { 3837436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* The returned value is in $v0. Park it in the register 3838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov associated with tmp. */ 3839436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = lookupIRTemp(env, d->tmp); 3840436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(r_dst, hregMIPS_GPR2(mode64))); 3841436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(rloc.pri == RLPri_Int); 3842436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(addToSp == 0); 3843436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3844436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3845436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I64: { 3846436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 3847436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* The returned value is in $v0. Park it in the register 3848436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov associated with tmp. */ 3849436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg r_dst = lookupIRTemp(env, d->tmp); 3850436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(r_dst, hregMIPS_GPR2(mode64))); 3851436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(rloc.pri == RLPri_Int); 3852436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(addToSp == 0); 3853436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3854436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3855436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rHi = newVRegI(env); 3856436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg rLo = newVRegI(env); 3857436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dstHi, dstLo; 3858436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(rLo, hregMIPS_GPR2(mode64))); 3859436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(rHi, hregMIPS_GPR3(mode64))); 3860436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lookupIRTemp64(&dstHi, &dstLo, env, d->tmp); 3861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(dstHi, rHi)); 3862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(dstLo, rLo)); 3863436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3864436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3865436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3866436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_V128: { 3867436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* ATC. The code that this produces really 3868436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov needs to be looked at, to verify correctness. 3869436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov I don't think this can ever happen though, since the 3870436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPS front end never produces 128-bit loads/stores. */ 3871436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 3872436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(rloc.pri == RLPri_V128SpRel); 3873436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(addToSp >= 16); 3874436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HReg dst = lookupIRTemp(env, d->tmp); 3875436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode* am = MIPSAMode_IR(rloc.spOff, StackPointer(mode64)); 3876436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_Load(mode64 ? 8 : 4, dst, am, mode64)); 3877436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_to_sp(env, addToSp); 3878436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 3879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3880436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3881436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov default: 3882436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*NOTREACHED*/ 3883436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); 3884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- Load Linked or Store Conditional --------- */ 3888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_LLSC: { 3889436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Temporary solution; this need to be rewritten again for MIPS. 3890436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov On MIPS you can not read from address that is locked with LL 3891436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov before SC. If you read from address that is locked than SC will 3892436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fall. */ 3893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp res = stmt->Ist.LLSC.result; 3894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType tyRes = typeOfIRTemp(env->type_env, res); 3895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType tyAddr = typeOfIRExpr(env->type_env, stmt->Ist.LLSC.addr); 3896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!mode64 && (tyAddr != Ity_I32)) 3898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto stmt_fail; 3899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (stmt->Ist.LLSC.storedata == NULL) { 3901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* LL */ 3902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *r_addr; 3903436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* constructs addressing mode from address provided */ 3904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_addr = iselWordExpr_AMode(env, stmt->Ist.LLSC.addr, tyAddr); 3905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = lookupIRTemp(env, res); 3907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tyRes == Ity_I32) { 3908436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LoadL(4, r_dst, r_addr, mode64)); 3909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (tyRes == Ity_I64 && mode64) { 3911436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_LoadL(8, r_dst, r_addr, mode64)); 3912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* SC */ 3916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *r_addr; 3917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r_addr = iselWordExpr_AMode(env, stmt->Ist.LLSC.addr, tyAddr); 3918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_src = iselWordExpr_R(env, stmt->Ist.LLSC.storedata); 3919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r_dst = lookupIRTemp(env, res); 3920436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRType tyData = typeOfIRExpr(env->type_env, 3921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stmt->Ist.LLSC.storedata); 3922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tyData == Ity_I32) { 3924436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(r_dst, r_src)); 3925436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_StoreC(4, r_addr, r_dst, mode64)); 3926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (tyData == Ity_I64 && mode64) { 3928436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, mk_iMOVds_RR(r_dst, r_src)); 3929436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addInstr(env, MIPSInstr_StoreC(8, r_addr, r_dst, mode64)); 3930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto stmt_fail; 3934436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* NOTREACHED */} 3935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3936436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- INSTR MARK --------- */ 3937436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Doesn't generate any executable code ... */ 3938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_IMark: 3939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3941436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- ABI HINT --------- */ 3942436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* These have no meaning (denotation in the IR) and so we ignore 3943436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov them ... if any actually made it this far. */ 3944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_AbiHint: 3945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3947436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* --------- NO-OP --------- */ 3948436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Fairly self-explanatory, wouldn't you say? */ 3949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_NoOp: 3950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* --------- EXIT --------- */ 3953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_Exit: { 3954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst* dst = stmt->Ist.Exit.dst; 3955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!mode64 && dst->tag != Ico_U32) 3956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselStmt(mips32): Ist_Exit: dst is not a 32-bit value"); 3957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (mode64 && dst->tag != Ico_U64) 3958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselStmt(mips64): Ist_Exit: dst is not a 64-bit value"); 3959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSCondCode cc = iselCondCode(env, stmt->Ist.Exit.guard); 3961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode* amPC = MIPSAMode_IR(stmt->Ist.Exit.offsIP, 3962436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov GuestStatePointer(mode64)); 3963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Case: boring transfer to known address */ 3965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (stmt->Ist.Exit.jk == Ijk_Boring 3966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || stmt->Ist.Exit.jk == Ijk_Call 3967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* || stmt->Ist.Exit.jk == Ijk_Ret */) { 3968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (env->chainingAllowed) { 3969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* .. almost always true .. */ 3970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Skip the event check at the dst if this is a forwards 3971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng edge. */ 3972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool toFastEP 3973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = mode64 3974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ? (((Addr64)stmt->Ist.Exit.dst->Ico.U64) > (Addr64)env->max_ga) 3975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : (((Addr32)stmt->Ist.Exit.dst->Ico.U32) > (Addr32)env->max_ga); 3976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0) vex_printf("%s", toFastEP ? "Y" : ","); 3977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XDirect( 3978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mode64 ? (Addr64)stmt->Ist.Exit.dst->Ico.U64 3979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : (Addr64)stmt->Ist.Exit.dst->Ico.U32, 3980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amPC, cc, toFastEP)); 3981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* .. very occasionally .. */ 3983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* We can't use chaining, so ask for an assisted transfer, 3984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng as that's the only alternative that is allowable. */ 3985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselWordExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst)); 3986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XAssisted(r, amPC, cc, Ijk_Boring)); 3987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 3989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Case: assisted transfer to arbitrary address */ 3992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (stmt->Ist.Exit.jk) { 3993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Keep this list in sync with that in iselNext below */ 3994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_ClientReq: 3995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_EmFail: 3996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_EmWarn: 3997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_NoDecode: 3998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_NoRedir: 3999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_SigBUS: 4000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_SigTRAP: 4001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ijk_SigFPE_IntDiv: 4002436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ijk_SigFPE_IntOvf: 4003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_Sys_syscall: 4004eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov case Ijk_InvalICache: 4005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { 4006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselWordExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst)); 4007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XAssisted(r, amPC, cc, 4008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stmt->Ist.Exit.jk)); 4009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 4010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 4012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Do we ever expect to see any other kind? */ 4016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto stmt_fail; 4017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 4020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stmt_fail: 4024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("stmt_fail tag: 0x%x\n", stmt->tag); 4025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRStmt(stmt); 4026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselStmt:\n"); 4027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 4028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 4030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- ISEL: Basic block terminators (Nexts) ---*/ 4031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 4032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void iselNext ( ISelEnv* env, 4034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* next, IRJumpKind jk, Int offsIP ) 4035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 4036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_traceflags & VEX_TRACE_VCODE) { 4037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf( "\n-- PUT(%d) = ", offsIP); 4038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr( next ); 4039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf( "; exit-"); 4040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRJumpKind(jk); 4041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf( "\n"); 4042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Case: boring transfer to known address */ 4045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (next->tag == Iex_Const) { 4046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst* cdst = next->Iex.Const.con; 4047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(cdst->tag == (env->mode64 ? Ico_U64 :Ico_U32)); 4048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (jk == Ijk_Boring || jk == Ijk_Call) { 4049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Boring transfer to known address */ 4050436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode* amPC = MIPSAMode_IR(offsIP, GuestStatePointer(env->mode64)); 4051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (env->chainingAllowed) { 4052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* .. almost always true .. */ 4053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Skip the event check at the dst if this is a forwards 4054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng edge. */ 4055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool toFastEP 4056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = env->mode64 4057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ? (((Addr64)cdst->Ico.U64) > (Addr64)env->max_ga) 4058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : (((Addr32)cdst->Ico.U32) > (Addr32)env->max_ga); 4059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0) vex_printf("%s", toFastEP ? "X" : "."); 4060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XDirect( 4061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->mode64 ? (Addr64)cdst->Ico.U64 4062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : (Addr64)cdst->Ico.U32, 4063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amPC, MIPScc_AL, toFastEP)); 4064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 4065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* .. very occasionally .. */ 4066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* We can't use chaining, so ask for an assisted transfer, 4067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng as that's the only alternative that is allowable. */ 4068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselWordExpr_R(env, next); 4069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XAssisted(r, amPC, MIPScc_AL, 4070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Ijk_Boring)); 4071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 4073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Case: call/return (==boring) transfer to any address */ 4077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (jk) { 4078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_Boring: case Ijk_Ret: case Ijk_Call: { 4079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselWordExpr_R(env, next); 4080436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode* amPC = MIPSAMode_IR(offsIP, 4081436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov GuestStatePointer(env->mode64)); 4082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (env->chainingAllowed) { 4083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XIndir(r, amPC, MIPScc_AL)); 4084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 4085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XAssisted(r, amPC, MIPScc_AL, 4086436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Ijk_Boring)); 4087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 4089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 4091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Case: assisted transfer to arbitrary address */ 4095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (jk) { 4096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Keep this list in sync with that for Ist_Exit above */ 4097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_ClientReq: 4098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_EmFail: 4099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_EmWarn: 4100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_NoDecode: 4101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_NoRedir: 4102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_SigBUS: 4103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ijk_SigILL: 4104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_SigTRAP: 4105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ijk_SigFPE_IntDiv: 4106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ijk_SigFPE_IntOvf: 4107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ijk_Sys_syscall: 4108eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov case Ijk_InvalICache: { 4109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg r = iselWordExpr_R(env, next); 4110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MIPSAMode* amPC = MIPSAMode_IR(offsIP, GuestStatePointer(env->mode64)); 4111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_XAssisted(r, amPC, MIPScc_AL, jk)); 4112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 4113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 4115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("\n-- PUT(%d) = ", offsIP); 4119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ppIRExpr(next ); 4120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("; exit-"); 4121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRJumpKind(jk); 4122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_printf("\n"); 4123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(0); /* are we expecting any other kind? */ 4124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 4125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 4127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- Insn selector top-level ---*/ 4128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------*/ 4129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Translate an entire BB to mips code. */ 4131663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengHInstrArray *iselSB_MIPS ( IRSB* bb, 4132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VexArch arch_host, 4133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VexArchInfo* archinfo_host, 4134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VexAbiInfo* vbi, 4135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int offs_Host_EvC_Counter, 4136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int offs_Host_EvC_FailAddr, 4137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool chainingAllowed, 4138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool addProfInc, 4139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Addr64 max_ga ) 4140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 4141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i, j; 4142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HReg hreg, hregHI; 4143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ISelEnv* env; 4144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt hwcaps_host = archinfo_host->hwcaps; 4145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPSAMode *amCounter, *amFailAddr; 4146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* sanity ... */ 4148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(arch_host == VexArchMIPS32 || arch_host == VexArchMIPS64); 4149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(VEX_PRID_COMP_MIPS == hwcaps_host 4150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || VEX_PRID_COMP_BROADCOM == hwcaps_host 4151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || VEX_PRID_COMP_NETLOGIC); 4152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mode64 = arch_host != VexArchMIPS32; 4154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if (__mips_fpr==64) 4155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fp_mode64 = ((VEX_MIPS_REV(hwcaps_host) == VEX_PRID_CPU_32FPR) 4156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || arch_host == VexArchMIPS64); 4157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif 4158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Make up an initial environment to use. */ 4160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env = LibVEX_Alloc(sizeof(ISelEnv)); 4161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vreg_ctr = 0; 4162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->mode64 = mode64; 4163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov env->fp_mode64 = fp_mode64; 4164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Set up output code array. */ 4166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->code = newHInstrArray(); 4167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Copy BB's type env. */ 4169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->type_env = bb->tyenv; 4170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Make up an IRTemp -> virtual HReg mapping. This doesn't 4172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng change as we go along. */ 4173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->n_vregmap = bb->tyenv->types_used; 4174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vregmap = LibVEX_Alloc(env->n_vregmap * sizeof(HReg)); 4175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vregmapHI = LibVEX_Alloc(env->n_vregmap * sizeof(HReg)); 4176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* and finally ... */ 4178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->hwcaps = hwcaps_host; 4179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->chainingAllowed = chainingAllowed; 4180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->hwcaps = hwcaps_host; 4181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->max_ga = max_ga; 4182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For each IR temporary, allocate a suitably-kinded virtual 4184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng register. */ 4185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng j = 0; 4186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < env->n_vregmap; i++) { 4187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hregHI = hreg = INVALID_HREG; 4188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (bb->tyenv->types[i]) { 4189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_I1: 4190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_I8: 4191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_I16: 4192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I32: 4193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 4194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hreg = mkHReg(j++, HRcInt64, True); 4195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 4197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hreg = mkHReg(j++, HRcInt32, True); 4198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 4200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_I64: 4201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 4202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hreg = mkHReg(j++, HRcInt64, True); 4203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 4205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hreg = mkHReg(j++, HRcInt32, True); 4206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hregHI = mkHReg(j++, HRcInt32, True); 4207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 4209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_I128: 4210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(mode64); 4211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hreg = mkHReg(j++, HRcInt64, True); 4212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hregHI = mkHReg(j++, HRcInt64, True); 4213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case Ity_F32: 4215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (mode64) { 4216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hreg = mkHReg(j++, HRcFlt64, True); 4217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 4219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov hreg = mkHReg(j++, HRcFlt32, True); 4220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 4222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_F64: 4223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hreg = mkHReg(j++, HRcFlt64, True); 4224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 4226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRType(bb->tyenv->types[i]); 4227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("iselBB(mips): IRTemp type"); 4228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 4229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vregmap[i] = hreg; 4231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vregmapHI[i] = hregHI; 4232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->vreg_ctr = j; 4234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* The very first instruction must be an event check. */ 4236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov amCounter = MIPSAMode_IR(offs_Host_EvC_Counter, GuestStatePointer(mode64)); 4237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov amFailAddr = MIPSAMode_IR(offs_Host_EvC_FailAddr, GuestStatePointer(mode64)); 4238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_EvCheck(amCounter, amFailAddr)); 4239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Possibly a block counter increment (for profiling). At this 4241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng point we don't know the address of the counter, so just pretend 4242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng it is zero. It will have to be patched later, but before this 4243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng translation is used, by a call to LibVEX_patchProfCtr. */ 4244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (addProfInc) { 4245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addInstr(env, MIPSInstr_ProfInc()); 4246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Ok, finally we can iterate over the statements. */ 4249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < bb->stmts_used; i++) 4250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselStmt(env, bb->stmts[i]); 4251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng iselNext(env, bb->next, bb->jumpkind, bb->offsIP); 4253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* record the number of vregs we used. */ 4255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->code->n_vregs = env->vreg_ctr; 4256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return env->code; 4257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 4259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------------*/ 4261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- end host_mips_isel.c ---*/ 4262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------------------------------------------------*/ 4263