📄 toir.c
字号:
/*--------------------------------------------------------------------*//*--- ---*//*--- This file (guest-ppc32/toIR.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.*//* TODO 2005 07 15: Get rid of all vestiges of flag helper fns. Spot rlwini cases which are simply left/right shifts and emit Shl32/Shr32 accordingly. Move mtxer/mfxer code into its own function.*//* Translates PPC32 code to IR. *//* References#define PPC32 "PowerPC Microprocessor Family: The Programming Environments for 32-Bit Microprocessors" 02/21/2000 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600719DF2#define AV "PowerPC Microprocessor Family: AltiVec(TM) Technology Programming Environments Manual" 07/10/2003 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/FBFA164F824370F987256D6A006F424D Other refs: "PowerPC Microprocessor Family: Programming Environments Manual for 64 and 32-Bit Microprocessors Version 2.0" 06/10/2003 http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/F6153E213FDD912E87256D49006C6541*/#include "libvex_basictypes.h"#include "libvex_ir.h"#include "libvex.h"#include "libvex_guest_ppc32.h"#include "main/vex_util.h"#include "main/vex_globals.h"#include "guest-generic/bb_to_IR.h"#include "guest-ppc32/gdefs.h"/*------------------------------------------------------------*//*--- Globals ---*//*------------------------------------------------------------*//* These are set at the start of the translation of an insn, right down in disInstr_PPC32, so that we don't have to pass them around endlessly. They are all constant during the translation of any given insn. *//* We need to know this to do sub-register accesses correctly. */static Bool host_is_bigendian;/* Pointer to the guest code area. */static UChar* guest_code;/* The guest address corresponding to guest_code[0]. */static Addr32 guest_CIA_bbstart;/* The guest address for the instruction currently being translated. */static Addr32 guest_CIA_curr_instr;/* The IRBB* into which we're generating code. */static IRBB* irbb;/*------------------------------------------------------------*//*--- Debugging output ---*//*------------------------------------------------------------*/#define PPC32_TOIR_DEBUG 0#define DIP(format, args...) \ if (vex_traceflags & VEX_TRACE_FE) \ vex_printf(format, ## args)#define DIS(buf, format, args...) \ if (vex_traceflags & VEX_TRACE_FE) \ vex_sprintf(buf, format, ## args)/*------------------------------------------------------------*//*--- Offsets of various parts of the ppc32 guest state. ---*//*------------------------------------------------------------*/#define OFFB_CIA offsetof(VexGuestPPC32State,guest_CIA)#define OFFB_LR offsetof(VexGuestPPC32State,guest_LR)#define OFFB_CTR offsetof(VexGuestPPC32State,guest_CTR)#define OFFB_XER_SO offsetof(VexGuestPPC32State,guest_XER_SO)#define OFFB_XER_OV offsetof(VexGuestPPC32State,guest_XER_OV)#define OFFB_XER_CA offsetof(VexGuestPPC32State,guest_XER_CA)#define OFFB_XER_BC offsetof(VexGuestPPC32State,guest_XER_BC)#define OFFB_FPROUND offsetof(VexGuestPPC32State,guest_FPROUND)#define OFFB_VRSAVE offsetof(VexGuestPPC32State,guest_VRSAVE)#define OFFB_VSCR offsetof(VexGuestPPC32State,guest_VSCR)#define OFFB_EMWARN offsetof(VexGuestPPC32State,guest_EMWARN)#define OFFB_TISTART offsetof(VexGuestPPC32State,guest_TISTART)#define OFFB_TILEN offsetof(VexGuestPPC32State,guest_TILEN)/*------------------------------------------------------------*//*--- Extract instruction fields --- *//*------------------------------------------------------------*//* Extract primary opcode, instr[31:26] */static UInt ifieldOPC ( UInt instr ) { return (instr >> 26) & 0x3F;}/* Extract 10-bit secondary opcode, instr[11:1] */static UInt ifieldOPClo10 ( UInt instr) { return (instr >> 1 ) & 0x3FF;}/* Extract RD (destination register) field, instr[25:21] */static UInt ifieldRD ( UInt instr ) { return (instr >> 21) & 0x1F;}/* Extract RA (first source register) field, instr[20:16] */static UInt ifieldRA ( UInt instr ) { return (instr >> 16) & 0x1F;}/* Extract RB (first source register) field, instr[15:11] */static UInt ifieldRB ( UInt instr ) { return (instr >> 11) & 0x1F;}/* Extract bottom bit (Rc?) from instr */static UInt ifieldBIT0 ( UInt instr ) { return instr & 1;}/* Extract lower half of instruction and sign extent to 32 bits */static Int ifieldSIMM16 ( UInt instr ) { Int i = instr & 0xFFFF; return (i << 16) >> 16;}//zz /*------------------------------------------------------------*///zz /*--- Abstract register interface (non-gpr|fpr) --- *///zz /*------------------------------------------------------------*///zz //zz /* Offsets of bitfields within various ppc32 registers *///zz #define SHIFT_XER_SO 31//zz #define SHIFT_XER_OV 30//zz #define SHIFT_XER_CA 29//zz #define SHIFT_XER_BC 0//zz //zz #define SHIFT_CR_LT 8//zz #define SHIFT_CR_GT 4//zz #define SHIFT_CR_EQ 2//zz #define SHIFT_CR_SO 1#define SHIFT_FPSCR_RN 0#define MASK_FPSCR_RN (3 << SHIFT_FPSCR_RN)//zz #define SHIFT_VSCR_NJ 16//zz #define SHIFT_VSCR_SAT 0// Special purpose (i.e. non-gpr/fpr) registerstypedef enum { PPC32_SPR_CIA, // Current Instruction Address PPC32_SPR_LR, // Link Register PPC32_SPR_CTR, // Count Register//zz PPC32_SPR_XER, // Summary Overflow//zz PPC32_SPR_CR, // Condition Register PPC32_SPR_FPSCR, // Floating Point Status/Control Register PPC32_SPR_VRSAVE, // Vector Save/Restore Register//zz PPC32_SPR_VSCR, // Vector Status and Control Register PPC32_SPR_MAX} PPC32SPR;//zz /*//zz Note on FPSCR: Floating Point Status and Control Register//zz //zz We're only keeping hold of fp rounding-mode bits, via guest_FPROUND//zz The rest of the FPSCR is set to 0x0, which corresponds to//zz 'all exceptions masked'//zz //zz FPSCR[29:31] => Exception Summaries//zz FPSCR[17:28] => Exceptions//zz FPSCR[16] => FPRF::Class Descriptor//zz FPSCR[12:15] => FPRF::Condition Code//zz FPSCR[11] => Unused (0)//zz FPSCR[8:10] => Exceptions//zz FPSCR[3:7] => Exception Control//zz FPSCR[2] => Non-IEEE mode//zz FPSCR[0:1] => Rounding Mode//zz //zz CAB: Perhaps necessary to record writes to FPRF ?//zz Set by dis_fp_cmp() instrs, also some fp arith/round/conv instrs.//zz Tested using dis_fp_scr(): e.g fpscr->cr, branch conditional...//zz *///zz //zz //zz /* Gets from SPR (non-GPR|FPR) registers *///zz static IRExpr* getReg_masked ( PPC32SPR reg, UInt mask );static IRExpr* getSPR ( PPC32SPR reg );//zz static IRExpr* getReg_field ( PPC32SPR reg, UInt field_idx );//zz static IRExpr* getReg_bit ( PPC32SPR reg, UInt bit_idx );//zz //zz /* Puts to SPR (non-GPR|FPR) registers *///zz static void putReg_masked ( PPC32SPR reg, IRExpr* src, UInt mask );static void putSPR ( PPC32SPR reg, IRExpr* src );//zz static void putReg_field ( PPC32SPR reg, IRExpr* src, UInt field_idx );//zz static void putReg_bit ( PPC32SPR reg, IRExpr* src, UInt bit_idx );/* FP Helpers */static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ );/*------------------------------------------------------------*//*--- Misc Helpers ---*//*------------------------------------------------------------*/static UInt MASK( UInt begin, UInt end ){ UInt m1 = ((UInt)(-1)) << begin; UInt m2 = ((UInt)(-1)) << (end + 1); UInt mask = m1 ^ m2; if (begin > end) mask = ~mask; // wrap mask return mask;}//zz #if PPC32_TOIR_DEBUG//zz static void vex_printf_binary( UInt x, UInt len, Bool spaces )//zz {//zz UInt i;//zz vassert(len > 0 && len <= 32);//zz //zz for (i=len; i>0; i--) {//zz vex_printf("%d", ((x & (1<<(len-1))) != 0) );//zz x = x << 1;//zz if (((i-1)%4)==0 && (i > 1) && spaces) {//zz vex_printf(" ");//zz }//zz }//zz }//zz #endif/*------------------------------------------------------------*//*--- Helper bits and pieces for deconstructing the ---*//*--- ppc32 insn stream. ---*//*------------------------------------------------------------*//* Add a statement to the list held by "irbb". */static void stmt ( IRStmt* st ){ addStmtToIRBB( irbb, st );}/* Generate a new temporary of the given type. */static IRTemp newTemp ( IRType ty ){ vassert(isPlausibleIRType(ty)); return newIRTemp( irbb->tyenv, ty );}//zz /* Various simple conversions *///zz //zz static UChar extend_s_5to8 ( UChar x )//zz {//zz return toUChar((((Int)x) << 27) >> 27);//zz }//zz //zz #if 0//zz static UInt extend_s_8to32( UInt x )//zz {//zz return (UInt)((((Int)x) << 24) >> 24);//zz }//zz #endifstatic UInt extend_s_16to32 ( UInt x ){ return (UInt)((((Int)x) << 16) >> 16);}static UInt extend_s_26to32 ( UInt x ){ return (UInt)((((Int)x) << 6) >> 6);}/* Do a big-endian load of a 32-bit word, regardless of the endianness of the underlying host. */static UInt getUIntBigendianly ( UChar* p ){ UInt w = 0; w = (w << 8) | p[0]; w = (w << 8) | p[1]; w = (w << 8) | p[2]; w = (w << 8) | p[3]; return w;}/*------------------------------------------------------------*//*--- Helpers for constructing IR. ---*//*------------------------------------------------------------*/static void assign ( IRTemp dst, IRExpr* e ){ stmt( IRStmt_Tmp(dst, e) );}static void storeBE ( IRExpr* addr, IRExpr* data ){ stmt( IRStmt_Store(Iend_BE,addr,data) );}static IRExpr* unop ( IROp op, IRExpr* a ){ return IRExpr_Unop(op, a);}static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -