⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isel.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*---------------------------------------------------------------*//*---                                                         ---*//*--- This file (host-ppc32/isel.c) is                        ---*//*--- Copyright (C) OpenWorks LLP.  All rights reserved.      ---*//*---                                                         ---*//*---------------------------------------------------------------*//*   This file is part of LibVEX, a library for dynamic binary   instrumentation and translation.   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.   This library is made available under a dual licensing scheme.   If you link LibVEX against other code all of which is itself   licensed under the GNU General Public License, version 2 dated June   1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL   v2, as appearing in the file LICENSE.GPL.  If the file LICENSE.GPL   is missing, you can obtain a copy of the GPL v2 from the Free   Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA   02110-1301, USA.   For any other uses of LibVEX, you must first obtain a commercial   license from OpenWorks LLP.  Please contact info@open-works.co.uk   for information about commercial licensing.   This software is provided by OpenWorks LLP "as is" and any express   or implied warranties, including, but not limited to, the implied   warranties of merchantability and fitness for a particular purpose   are disclaimed.  In no event shall OpenWorks LLP be liable for any   direct, indirect, incidental, special, exemplary, or consequential   damages (including, but not limited to, procurement of substitute   goods or services; loss of use, data, or profits; or business   interruption) however caused and on any theory of liability,   whether in contract, strict liability, or tort (including   negligence or otherwise) arising in any way out of the use of this   software, even if advised of the possibility of such damage.   Neither the names of the U.S. Department of Energy nor the   University of California nor the names of its contributors may be   used to endorse or promote products derived from this software   without prior written permission.*/#include "libvex_basictypes.h"#include "libvex_ir.h"#include "libvex.h"#include "ir/irmatch.h"#include "main/vex_util.h"#include "main/vex_globals.h"#include "host-generic/h_generic_regs.h"#include "host-ppc32/hdefs.h"/*---------------------------------------------------------*//*--- Register Usage Conventions                        ---*//*---------------------------------------------------------*//*  Integer Regs  ------------  GPR0       Reserved  GPR1       Stack Pointer  GPR2       TOC pointer - not used  GPR3:12    Allocateable  GPR13      Thread-specific pointer - not used  GPR14:29   Allocateable  GPR30      AltiVec temp spill register  GPR31      GuestStatePointer  Of Allocateable regs:  GPR3:12    Caller-saved regs  GPR14:29   Callee-saved regs  GPR3       [Return | Parameter] - carrying reg  GPR4:10    Parameter-carrying regs  Floating Point Regs  -------------------  FPR0:31    Allocateable  FPR0:13    Caller-saved regs  FPR14:31   Callee-saved regs  *//*---------------------------------------------------------*//*--- PPC32 FP Status & Control Register Conventions    ---*//*---------------------------------------------------------*//*  Vex-generated code expects to run with the FPU set as follows: all  exceptions masked, round-to-nearest.  This corresponds to a FPU control word value of 0x0.    %fpscr should have this value on entry to Vex-generated code,  and those values should be unchanged at exit.    Warning: For simplicity, set_FPU_rounding_* assumes this is 0x0  - if this is changed, update those functions.*//*---------------------------------------------------------*//*--- misc helpers                                      ---*//*---------------------------------------------------------*//* These are duplicated in guest-ppc32/toIR.c */static IRExpr* unop ( IROp op, IRExpr* a ){   return IRExpr_Unop(op, a);}#if 0static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ){   return IRExpr_Binop(op, a1, a2);}#endif//.. static IRExpr* mkU64 ( ULong i )//.. {//..    return IRExpr_Const(IRConst_U64(i));//.. }//.. //.. static IRExpr* mkU32 ( UInt i )//.. {//..    return IRExpr_Const(IRConst_U32(i));//.. }static IRExpr* bind ( Int binder ){   return IRExpr_Binder(binder);}/*---------------------------------------------------------*//*--- ISelEnv                                           ---*//*---------------------------------------------------------*//* This carries around:   - A mapping from IRTemp to IRType, giving the type of any IRTemp we     might encounter.  This is computed before insn selection starts,     and does not change.   - A mapping from IRTemp to HReg.  This tells the insn selector     which virtual register(s) are associated with each IRTemp      temporary.  This is computed before insn selection starts, and      does not change.  We expect this mapping to map precisely the      same set of IRTemps as the type mapping does.          - vregmap   holds the primary register for the IRTemp.         - vregmapHI is only used for 64-bit integer-typed              IRTemps.  It holds the identity of a second              32-bit virtual HReg, which holds the high half              of the value.    - A copy of the link reg, so helper functions don't kill it.    - The code array, that is, the insns selected so far.     - A counter, for generating new virtual registers.     - The host subarchitecture we are selecting insns for.        This is set at the start and does not change.     Note, this is all host-independent.  (JRS 20050201: well, kinda   ... not completely.  Compare with ISelEnv for amd64.)*/ typedef   struct {      IRTypeEnv*   type_env;       HReg*        vregmap;      HReg*        vregmapHI;      Int          n_vregmap;       HReg         savedLR;      HInstrArray* code;       Int          vreg_ctr;       VexSubArch   subarch;   }   ISelEnv;  static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp ){   vassert(tmp >= 0);   vassert(tmp < env->n_vregmap);   return env->vregmap[tmp];}static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp ){   vassert(tmp >= 0);   vassert(tmp < env->n_vregmap);   vassert(env->vregmapHI[tmp] != INVALID_HREG);   *vrLO = env->vregmap[tmp];   *vrHI = env->vregmapHI[tmp];}static void addInstr ( ISelEnv* env, PPC32Instr* instr ){   addHInstr(env->code, instr);   if (vex_traceflags & VEX_TRACE_VCODE) {      ppPPC32Instr(instr);      vex_printf("\n");   }}static HReg newVRegI ( ISelEnv* env ){   HReg reg = mkHReg(env->vreg_ctr, HRcInt32, True/*virtual reg*/);   env->vreg_ctr++;   return reg;}static HReg newVRegF ( ISelEnv* env ){   HReg reg = mkHReg(env->vreg_ctr, HRcFlt64, True/*virtual reg*/);   env->vreg_ctr++;   return reg;}static HReg newVRegV ( ISelEnv* env ){   HReg reg = mkHReg(env->vreg_ctr, HRcVec128, True/*virtual reg*/);   env->vreg_ctr++;   return reg;}/*---------------------------------------------------------*//*--- ISEL: Forward declarations                        ---*//*---------------------------------------------------------*//* These are organised as iselXXX and iselXXX_wrk pairs.  The   iselXXX_wrk do the real work, but are not to be called directly.   For each XXX, iselXXX calls its iselXXX_wrk counterpart, then   checks that all returned registers are virtual.  You should not   call the _wrk version directly.*//* Compute an I8/I16/I32 into a GPR. */static HReg          iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e );static HReg          iselIntExpr_R     ( ISelEnv* env, IRExpr* e );/* Compute an I8/I16/I32 into a RH (reg-or-halfword-immediate).  It's   important to specify whether the immediate is to be regarded as   signed or not.  If yes, this will never return -32768 as an   immediate; this guaranteed that all signed immediates that are   return can have their sign inverted if need be. */static PPC32RH*      iselIntExpr_RH_wrk ( ISelEnv* env,                                           Bool syned, IRExpr* e );static PPC32RH*      iselIntExpr_RH     ( ISelEnv* env,                                           Bool syned, IRExpr* e );/* Compute an I32 into a RI (reg or 32-bit immediate). */static PPC32RI*      iselIntExpr_RI_wrk ( ISelEnv* env, IRExpr* e );static PPC32RI*      iselIntExpr_RI     ( ISelEnv* env, IRExpr* e );/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter   being an immediate in the range 1 .. 31 inclusive.  Used for doing   shift amounts. */static PPC32RH*      iselIntExpr_RH5u_wrk ( ISelEnv* env, IRExpr* e );static PPC32RH*      iselIntExpr_RH5u     ( ISelEnv* env, IRExpr* e );/* Compute an I32 into an AMode. */static PPC32AMode*   iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e );static PPC32AMode*   iselIntExpr_AMode     ( ISelEnv* env, IRExpr* e );/* Compute an I64 into a GPR pair. */static void          iselInt64Expr_wrk ( HReg* rHi, HReg* rLo,                                          ISelEnv* env, IRExpr* e );static void          iselInt64Expr     ( HReg* rHi, HReg* rLo,                                          ISelEnv* env, IRExpr* e );static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e );static PPC32CondCode iselCondCode     ( ISelEnv* env, IRExpr* e );static HReg          iselDblExpr_wrk ( ISelEnv* env, IRExpr* e );static HReg          iselDblExpr     ( ISelEnv* env, IRExpr* e );static HReg          iselFltExpr_wrk ( ISelEnv* env, IRExpr* e );static HReg          iselFltExpr     ( ISelEnv* env, IRExpr* e );static HReg          iselVecExpr_wrk ( ISelEnv* env, IRExpr* e );static HReg          iselVecExpr     ( ISelEnv* env, IRExpr* e );/*---------------------------------------------------------*//*--- ISEL: Misc helpers                                ---*//*---------------------------------------------------------*///.. /* Is this a 32-bit zero expression? *///.. //.. static Bool isZero32 ( IRExpr* e )//.. {//..    return e->tag == Iex_Const//..           && e->Iex.Const.con->tag == Ico_U32//..           && e->Iex.Const.con->Ico.U32 == 0;//.. }/* Make an int reg-reg move. */static PPC32Instr* mk_iMOVds_RR ( HReg r_dst, HReg r_src ){   vassert(hregClass(r_dst) == HRcInt32);   vassert(hregClass(r_src) == HRcInt32);   return PPC32Instr_Alu32(Palu_OR, r_dst, r_src, PPC32RH_Reg(r_src));}//.. /* Make a vector reg-reg move. *///.. //.. static X86Instr* mk_vMOVsd_RR ( HReg src, HReg dst )//.. {//..    vassert(hregClass(src) == HRcVec128);//..    vassert(hregClass(dst) == HRcVec128);//..    return X86Instr_SseReRg(Xsse_MOV, src, dst);//.. }/* Advance/retreat %sp by n. */static void add_to_sp ( ISelEnv* env, Int n ){   HReg sp = StackFramePtr;   vassert(n > 0 && n < 256 && (n%16) == 0);   addInstr(env, PPC32Instr_Alu32(Palu_ADD, sp, sp, PPC32RH_Imm(True,n)));}static void sub_from_sp ( ISelEnv* env, Int n ){   HReg sp = StackFramePtr;   vassert(n > 0 && n < 256 && (n%16) == 0);   addInstr(env, PPC32Instr_Alu32(Palu_SUB, sp, sp, PPC32RH_Imm(True,n)));}/* Load 2*I32 regs to fp reg */static HReg mk_LoadRRtoFPR ( ISelEnv* env, HReg r_srcHi, HReg r_srcLo ){   HReg fr_dst = newVRegF(env);   PPC32AMode *am_addr0, *am_addr1;   sub_from_sp( env, 16 );        // Move SP down 16 bytes   am_addr0 = PPC32AMode_IR(0, StackFramePtr);   am_addr1 = PPC32AMode_IR(4, StackFramePtr);   // store hi,lo as Ity_I32's   addInstr(env, PPC32Instr_Store( 4, am_addr0, r_srcHi ));   addInstr(env, PPC32Instr_Store( 4, am_addr1, r_srcLo ));   // load as float   addInstr(env, PPC32Instr_FpLdSt(True/*load*/, 8, fr_dst, am_addr0));      add_to_sp( env, 16 );          // Reset SP   return fr_dst;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -