libvex_ir.h revision 6d2638e5edd8849e036f235d42a23c959e3bc3d8
1 2/*---------------------------------------------------------------*/ 3/*--- ---*/ 4/*--- This file (libvex_ir.h) is ---*/ 5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ 6/*--- ---*/ 7/*---------------------------------------------------------------*/ 8 9#ifndef __LIBVEX_IR_H 10#define __LIBVEX_IR_H 11 12#include "libvex_basictypes.h" 13 14 15/*---------------------------------------------------------------*/ 16/*--- Type definitions for the IR ---*/ 17/*---------------------------------------------------------------*/ 18 19/* ------------------ Types ------------------ */ 20 21typedef 22 enum { Ity_INVALID=0x10FFF, 23 Ity_Bit=0x11000, 24 Ity_I8, Ity_I16, Ity_I32, Ity_I64 } 25 IRType; 26 27extern void ppIRType ( IRType ); 28 29 30/* ------------------ Constants ------------------ */ 31 32typedef 33 enum { Ico_U8, Ico_U16, Ico_U32, Ico_U64 } 34 IRConstTag; 35 36typedef 37 struct _IRConst { 38 IRConstTag tag; 39 union { 40 UChar U8; 41 UShort U16; 42 UInt U32; 43 ULong U64; 44 } Ico; 45 } 46 IRConst; 47 48extern IRConst* IRConst_U8 ( UChar ); 49extern IRConst* IRConst_U16 ( UShort ); 50extern IRConst* IRConst_U32 ( UInt ); 51extern IRConst* IRConst_U64 ( ULong ); 52 53extern void ppIRConst ( IRConst* ); 54 55 56/* ------------------ Temporaries ------------------ */ 57 58typedef UInt IRTemp; 59 60extern void ppIRTemp ( IRTemp ); 61 62#define INVALID_IRTEMP ((IRTemp)0xFFFFFFFF) 63 64 65/* ------------------ Binary and unary ops ------------------ */ 66 67typedef 68 enum { 69 /* Do not change this ordering. The IR generators 70 rely on (eg) Iop_Add64 == IopAdd8 + 3. */ 71 Iop_Add8=0x12000, 72 Iop_Add16, Iop_Add32, Iop_Add64, 73 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64, 74 Iop_Adc8, Iop_Adc16, Iop_Adc32, Iop_Adc64, 75 Iop_Sbb8, Iop_Sbb16, Iop_Sbb32, Iop_Sbb64, 76 /* Signless mul. MullS/MullU is elsewhere. */ 77 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64, 78 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64, 79 Iop_And8, Iop_And16, Iop_And32, Iop_And64, 80 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64, 81 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64, 82 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64, 83 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64, 84 /* Integer comparisons. */ 85 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64, 86 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64, 87 /* Tags for unary ops */ 88 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64, 89 Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64, 90 /* Widening multiplies */ 91 Iop_MullS8, Iop_MullS16, Iop_MullS32, 92 Iop_MullU8, Iop_MullU16, Iop_MullU32, 93 /* Ordering not important after here. */ 94 /* Division */ 95 Iop_DivModU64to32, // :: I64,I32 -> I64 96 // of which lo half is div and hi half is mod 97 Iop_DivModS64to32, // ditto, signed 98 /* Widening conversions */ 99 Iop_8Uto16, Iop_8Uto32, Iop_16Uto32, 100 Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, 101 /* 32 <-> 64 bit conversions */ 102 Iop_64LOto32, // :: I64 -> I32, low half 103 Iop_64HIto32, // :: I64 -> I32, high half 104 Iop_32HLto64, // :: (I32,I32) -> I64 105 /* 1-bit stuff */ 106 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */ 107 Iop_1Uto8 /* :: Ity_Bit -> Ity_I8, unsigned widen */ 108 } 109 IROp; 110 111extern void ppIROp ( IROp ); 112 113 114/* ------------------ Expressions ------------------ */ 115/* 116data Expr 117 = GET Int Int -- offset, size 118 | TMP Temp -- value of temporary 119 | BINOP Op Expr Expr -- binary op 120 | UNOP Op Expr -- unary op 121 | LDle Type Expr -- load of the given type, Expr:: 32 or 64 122 | CONST Const -- 8/16/32/64-bit int constant 123*/ 124typedef 125 enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle, 126 Iex_Const, Iex_CCall } 127 IRExprTag; 128 129typedef 130 struct _IRExpr { 131 IRExprTag tag; 132 union { 133 struct { 134 Int offset; 135 IRType ty; 136 } Get; 137 struct { 138 IRTemp tmp; 139 } Tmp; 140 struct { 141 IROp op; 142 struct _IRExpr* arg1; 143 struct _IRExpr* arg2; 144 } Binop; 145 struct { 146 IROp op; 147 struct _IRExpr* arg; 148 } Unop; 149 struct { 150 IRType ty; 151 struct _IRExpr* addr; 152 } LDle; 153 struct { 154 IRConst* con; 155 } Const; 156 struct { 157 Char* name; 158 IRType retty; 159 struct _IRExpr** args; 160 } CCall; 161 } Iex; 162 } 163 IRExpr; 164 165extern IRExpr* IRExpr_Get ( Int off, IRType ty ); 166extern IRExpr* IRExpr_Tmp ( IRTemp tmp ); 167extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); 168extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ); 169extern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ); 170extern IRExpr* IRExpr_Const ( IRConst* con ); 171extern IRExpr* IRExpr_CCall ( Char* name, IRType retty, IRExpr** args ); 172 173extern void ppIRExpr ( IRExpr* ); 174 175/* CCall info. The name is the C helper function; the backends 176 will look it up in a table of known helpers, to get the address. 177 178 The args are a NULL-terminated array of arguments. The stated 179 return IRType, and the implied argument types, must match that 180 of the function being called well enough so that the back end 181 can actually generate correct code for the call. (too vague) 182 183 The called function must satisfy the following: 184 185 * no side effects -- must be a pure function 186 * it may not look at any of the guest state -- must depend 187 purely on passed parameters 188 * it may not access guest memory -- since that would 189 hide guest memory transactions from the instrumenters 190*/ 191 192/* ------------------ Statements ------------------ */ 193/* 194data Stmt 195 = PUT Int Int Expr -- offset, size, value 196 | TMP Temp Expr -- store value in Temp 197 | STle Expr Expr -- address (32 or 64 bit), value 198 | Exit Expr Const -- conditional exit from middle of BB 199 -- Const is destination guest addr 200*/ 201typedef 202 enum { Ist_Put, Ist_Tmp, Ist_STle, Ist_Exit } 203 IRStmtTag; 204 205typedef 206 struct _IRStmt { 207 IRStmtTag tag; 208 union { 209 struct { 210 IRExpr* guard; 211 Int offset; 212 IRExpr* expr; 213 } Put; 214 struct { 215 IRTemp tmp; 216 IRExpr* expr; 217 } Tmp; 218 struct { 219 IRExpr* addr; 220 IRExpr* data; 221 } STle; 222 struct { 223 IRExpr* cond; 224 IRConst* dst; 225 } Exit; 226 } Ist; 227 struct _IRStmt* link; 228 } 229 IRStmt; 230 231extern IRStmt* IRStmt_Put ( IRExpr* guard, Int off, IRExpr* value ); 232extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* expr ); 233extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* value ); 234extern IRStmt* IRStmt_Exit ( IRExpr* cond, IRConst* dst ); 235 236extern void ppIRStmt ( IRStmt* ); 237 238/* Guards in Put: if NULL, the Put is always done. 239 If non-NULL, the expr must denote a value of Ity_Bit, and 240 the Put is only done if this evaluates to 1. The expression 241 to be stored (expr) will be evaluated regardless of what 242 the guard is. 243*/ 244 245/* ------------------ Basic Blocks ------------------ */ 246 247/* This describes the unconditional jumps which implicitly happen at 248 the end of each basic block. Conditional jumps -- which can only 249 be done with the IRStmt_Exit statement -- are implicitly of the 250 Ijk_Boring kind. */ 251 252typedef 253 enum { 254 Ijk_Boring=0x13000, /* not interesting; just goto next */ 255 Ijk_Call, /* guest is doing a call */ 256 Ijk_Ret, /* guest is doing a return */ 257 Ijk_ClientReq, /* do guest client req before continuing */ 258 Ijk_Syscall, /* do guest syscall before continuing */ 259 Ijk_Yield /* client is yielding to thread scheduler */ 260 } 261 IRJumpKind; 262 263extern void ppIRJumpKind ( IRJumpKind ); 264 265 266/* A bunch of statements, expressions, etc, are incomplete without an 267 environment indicating the type of each IRTemp. So this provides 268 one. IR temporaries are really just unsigned ints and so this 269 provides an array, 0 .. n_types_used-1 of them. 270*/ 271typedef 272 struct { 273 IRType* types; 274 Int types_size; 275 Int types_used; 276 } 277 IRTypeEnv; 278 279extern void ppIRTypeEnv ( IRTypeEnv* ); 280 281 282/* Basic blocks contain 4 fields: 283 - A table giving a type for each temp 284 - A list of statements 285 - An expression of type 32 or 64 bits, depending on the 286 guest's word size, indicating the next destination. 287*/ 288typedef 289 struct _IRBB { 290 IRTypeEnv* tyenv; 291 IRStmt* stmts; 292 IRExpr* next; 293 IRJumpKind jumpkind; 294 } 295 IRBB; 296 297extern IRBB* mkIRBB ( IRTypeEnv*, IRStmt*, IRExpr*, IRJumpKind ); 298 299extern void ppIRBB ( IRBB* ); 300 301 302/*---------------------------------------------------------------*/ 303/*--- Helper functions for the IR ---*/ 304/*---------------------------------------------------------------*/ 305 306/* For messing with IR type environments */ 307extern IRTypeEnv* newIRTypeEnv ( void ); 308extern IRTemp newIRTemp ( IRTypeEnv*, IRType ); 309extern IRType lookupIRTypeEnv ( IRTypeEnv*, IRTemp ); 310 311/* What is the type of this expression? */ 312extern IRType typeOfIRConst ( IRConst* ); 313extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); 314 315/* Sanity check a BB of IR */ 316extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size ); 317 318/* Is this any value actually in the enumeration 'IRType' ? */ 319extern Bool isPlausibleType ( IRType ty ); 320 321#endif /* ndef __LIBVEX_IR_H */ 322 323 324/*---------------------------------------------------------------*/ 325/*--- libvex_ir.h ---*/ 326/*---------------------------------------------------------------*/ 327