libvex_ir.h revision 3bca906f6e715c544eb49c278bedef093c14c0d7
1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 2be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian/*---------------------------------------------------------------*/ 325be043940b25a5fe6eb8058070b3e8f12e92039Brian Paul/*--- ---*/ 45e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen/*--- This file (libvex_ir.h) is ---*/ 59f6022d0567dc1288888212d7128acc48795b306Brian/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ 680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul/*--- ---*/ 75e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen/*---------------------------------------------------------------*/ 8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* 10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg This file is part of LibVEX, a library for dynamic binary 11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg instrumentation and translation. 12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Copyright (C) 2004 OpenWorks, LLP. 145e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen 15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg This program is free software; you can redistribute it and/or modify 16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg it under the terms of the GNU General Public License as published by 175e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen the Free Software Foundation; Version 2 dated June 1991 of the 18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg license. 19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg This program is distributed in the hope that it will be useful, 21afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg but WITHOUT ANY WARRANTY; without even the implied warranty of 22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability 23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg for damages. See the GNU General Public License for more details. 24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Neither the names of the U.S. Department of Energy nor the 266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell University of California nor the names of its contributors may be 27add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul used to endorse or promote products derived from this software 28add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul without prior written permission. 2977ee31930a1b0cc7766939415f4f04ed6a1fa4acBrian Paul 30add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul You should have received a copy of the GNU General Public License 31add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul along with this program; if not, write to the Free Software 32add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 33fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul USA. 34b46712ca9d379d9c091f5543500088d82cf9776cBrian Paul*/ 35afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 36d100cbf721010f4eacc87507cc87c5314150d493Maciej Cencora#ifndef __LIBVEX_IR_H 3734bd1233a9874fe12a822c4fcb926d48456e1f29Brian Paul#define __LIBVEX_IR_H 3834bd1233a9874fe12a822c4fcb926d48456e1f29Brian Paul 392897cee99fb877e1f3cd9a881a61418c9c31867fBrian Paul#include "libvex_basictypes.h" 40afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 413c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul 42ebb248aa5c018dc676d389221d76ed329059789eBrian Paul/*---------------------------------------------------------------*/ 43fa4525e289b475b928a7b2c4055af9dd7fe46600Brian Paul/*--- Type definitions for the IR ---*/ 4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*---------------------------------------------------------------*/ 451a2bb37264b4448d33f2948fe1702c9dc936395dBrian Paul 46afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* ------------------ Types ------------------ */ 47afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 487179a822628963d8cfa0817cf072c5acb70638a7Kristian Høgsbergtypedef 495e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen enum { 50afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Ity_INVALID=0x10FFF, 51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Ity_I1=0x11000, 524cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ity_I8, 5363f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul Ity_I16, 5463f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul Ity_I32, 5563f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul Ity_I64, 5663f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul Ity_F32, /* IEEE 754 float */ 5763f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul Ity_F64, /* IEEE 754 double */ 5863f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul Ity_V128 /* 128-bit SIMD */ 5963f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul } 6063f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul IRType; 6163f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul 6263f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paulextern void ppIRType ( IRType ); 6363f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paulextern Int sizeofIRType ( IRType ); 644cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul 654cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul 664cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul/* ------------------ Constants ------------------ */ 674cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul 684cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paultypedef 694cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul enum { 704cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_U1=0x12000, 714cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_U8, 724cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_U16, 734cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_U32, 744cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_U64, 754cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_F64, /* 64-bit IEEE754 floating */ 764cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_F64i, /* 64-bit unsigned int to be interpreted literally 774cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul as a IEEE754 double value. */ 784cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ico_V128 /* 128-bit restricted vector constant, with 1 bit for 794cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul each of 16 byte lanes */ 804cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul } 814cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul IRConstTag; 824cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul 834cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paultypedef 84f7b5707d66678f09bec652ecce024a0da6cc4a4bBrian Paul struct _IRConst { 85887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul IRConstTag tag; 86973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul union { 87afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Bool U1; 88fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul UChar U8; 89fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul UShort U16; 90afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg UInt U32; 91afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg ULong U64; 92afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Double F64; 93afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg ULong F64i; 94973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul UShort V128; 95afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } Ico; 96973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul } 97973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul IRConst; 98973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul 99afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_U1 ( Bool ); 100afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_U8 ( UChar ); 101afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_U16 ( UShort ); 102afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_U32 ( UInt ); 103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_U64 ( ULong ); 104afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_F64 ( Double ); 105887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paulextern IRConst* IRConst_F64i ( ULong ); 106afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* IRConst_V128 ( UShort ); 107afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 108afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRConst* dopyIRConst ( IRConst* ); 109afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 110afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern void ppIRConst ( IRConst* ); 111afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern Bool eqIRConst ( IRConst*, IRConst* ); 112afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 113afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 1146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/* ------------------ Call targets ------------------ */ 1151749a25ca889d514889b34cf6311c8014d97bf66Brian Paul 1161749a25ca889d514889b34cf6311c8014d97bf66Brian Paul/* Describes a helper function to call. The name part is purely for 1176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell pretty printing and not actually used. regparms=n tells the back 1186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell end that the callee has been declared 1191749a25ca889d514889b34cf6311c8014d97bf66Brian Paul "__attribute__((regparm(n)))". On some targets (x86) the back end 1206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell will need to construct a non-standard sequence to call a function 1216dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell declared like this. 1226dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 12389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul mcx_mask is a sop to Memcheck. It indicates which args should be 12489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul considered 'always defined' when lazily computing definedness of 12589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to 12673b150c816c46a88e3e5d97f9b73ab0095f2bc60Brian Paul args[1], etc. If a bit is set, the corresponding arg is excluded 12773b150c816c46a88e3e5d97f9b73ab0095f2bc60Brian Paul (hence "x" in "mcx") from definedness checking. 128afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg*/ 129b132e8da5e5f2b7da1f2141e0322e66bb0608e02Brian Paul 130f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergtypedef 131afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg struct { 1321749a25ca889d514889b34cf6311c8014d97bf66Brian Paul Int regparms; 133afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Char* name; 134afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg void* addr; 135afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg UInt mcx_mask; 136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 137afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg IRCallee; 138afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 139afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr ); 140afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 141afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRCallee* dopyIRCallee ( IRCallee* ); 142afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 143afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern void ppIRCallee ( IRCallee* ); 144afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 145afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 146afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* ------------------ Guest state arrays ------------------ */ 147afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 148afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgtypedef 149afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg struct { 150afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Int base; 151afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg IRType elemTy; 152afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg Int nElems; 153afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 154afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg IRArray; 155afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 156afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRArray* mkIRArray ( Int, IRType, Int ); 157afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 158afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern IRArray* dopyIRArray ( IRArray* ); 159afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 160afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern void ppIRArray ( IRArray* ); 161afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern Bool eqIRArray ( IRArray*, IRArray* ); 162afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 163afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 164afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* ------------------ Temporaries ------------------ */ 165afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 166afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* The IR optimiser relies on the fact that IRTemps are 32-bit 167afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg ints. Do not change them to be ints of any other size. */ 168afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgtypedef UInt IRTemp; 169afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 170afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgextern void ppIRTemp ( IRTemp ); 171afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 172afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF) 173afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 174afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 175afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* ------------------ Binary and unary ops ------------------ */ 176afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 177afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgtypedef 178afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg enum { 179afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg /* Do not change this ordering. The IR generators 180afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg rely on (eg) Iop_Add64 == IopAdd8 + 3. */ 181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_INVALID=0x13000, 182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64, 183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64, 184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Signless mul. MullS/MullU is elsewhere. */ 185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64, 186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64, 187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_And8, Iop_And16, Iop_And32, Iop_And64, 188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64, 189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64, 190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64, 191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64, 192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Integer comparisons. */ 193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64, 194e71654961868eac559210ced359c1af114138d8aBrian Paul Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64, 195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Tags for unary ops */ 196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64, 197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Widening multiplies */ 198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_MullS8, Iop_MullS16, Iop_MullS32, 199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_MullU8, Iop_MullU16, Iop_MullU32, 2004741dbcbbc2514de370a760f4b78a17491014555Ian Romanick 201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Wierdo integer stuff */ 202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Clz32, /* count leading zeroes */ 2034741dbcbbc2514de370a760f4b78a17491014555Ian Romanick Iop_Ctz32, /* count trailing zeros */ 2044741dbcbbc2514de370a760f4b78a17491014555Ian Romanick /* Ctz32/Clz32 are UNDEFINED when given arguments of zero. 2054741dbcbbc2514de370a760f4b78a17491014555Ian Romanick You must ensure they are never given a zero argument. 206f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul */ 207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Ordering not important after here. */ 209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_CmpLT32S, 210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_CmpLE32S, 21189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul Iop_CmpLT32U, 21233fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_CmpLE32U, 21333fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick /* Division */ 21433fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick /* TODO: clarify semantics wrt rounding, negative values, whatever */ 21533fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_DivModU64to32, // :: I64,I32 -> I64 21633fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick // of which lo half is div and hi half is mod 21733fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_DivModS64to32, // ditto, signed 21833fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick 21933fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick /* Widening conversions */ 22033fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_8Uto16, Iop_8Uto32, Iop_16Uto32, Iop_32Uto64, 22133fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, Iop_32Sto64, 22233fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick /* Narrowing conversions */ 22333fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_32to8, 22433fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick /* 8 <-> 16 bit conversions */ 22533fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_16to8, // :: I16 -> I8, low half 22633fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick Iop_16HIto8, // :: I16 -> I8, high half 227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_8HLto16, // :: (I8,I8) -> I16 228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* 16 <-> 32 bit conversions */ 229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_32to16, // :: I32 -> I16, low half 230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_32HIto16, // :: I32 -> I16, high half 231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_16HLto32, // :: (I16,I16) -> I32 23289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul /* 32 <-> 64 bit conversions */ 233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_64to32, // :: I64 -> I32, low half 23489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul Iop_64HIto32, // :: I64 -> I32, high half 235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_32HLto64, // :: (I32,I32) -> I64 236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* 1-bit stuff */ 237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Not1, /* :: Ity_Bit -> Ity_Bit */ 238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */ 239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */ 240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */ 241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */ 2428f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */ 2438f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */ 244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */ 245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* ------ Floating point. We try and be IEEE754 compliant. ------ */ 24740bd9d0b190e11d39350d1b08d2c2b28e3040bcaDaniel Borca 248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Binary operations mandated by IEEE754. */ 249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */ 250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Binary ops supported by IA32 but not mandated by 754. */ 252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */ 253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */ 254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */ 255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */ 256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */ 257663a9e1b7ef7b8384abe2f81e1a8749b942f6d3aDaniel Borca Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */ 258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */ 259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */ 260663a9e1b7ef7b8384abe2f81e1a8749b942f6d3aDaniel Borca /* Note that on x86 guest, PRem1{C3210} has the same behaviour 261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul as the IEEE mandated RemF64, except it is limited in the 262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul range of its operand. Hence the partialness. */ 263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Unary operations mandated by IEEE754. */ 26589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul Iop_NegF64, Iop_SqrtF64, 266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Unary ops supported by IA32 but not mandated by 754. */ 268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_AbsF64, /* FABS */ 269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_SinF64, /* FSIN */ 2701749a25ca889d514889b34cf6311c8014d97bf66Brian Paul Iop_CosF64, /* FCOS */ 271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_TanF64, /* FTAN */ 272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_2xm1F64, /* (2^arg - 1.0) */ 273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following: 275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0x45 Unordered 276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0x01 LT 277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0x00 GT 278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 0x40 EQ 279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul This just happens to be the Intel encoding. The values 280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul are recorded in the type IRCmpF64Result. 281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul Iop_CmpF64, 283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* --- Int to/from FP conversions. --- */ 285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul /* For the most part, these take a first argument :: Ity_I32 286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul (as IRRoundingMode) which is an indication of the rounding 287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul mode to use, as per the following encoding: 288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 00b to nearest (the default) 289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 01b to -infinity 290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 10b to +infinity 291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 11b to zero 2928f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul This just happens to be the Intel encoding. For reference only, 293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul the PPC encoding is: 294afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 00b to nearest (the default) 295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 01b to zero 296114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 10b to +infinity 297114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 11b to -infinity 298114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger Any PPC -> IR front end will have to translate these PPC 299114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger encodings to the standard encodings. 300114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 301114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger If one of these conversions gets an out-of-range condition, 302114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger or a NaN, as an argument, the result is host-defined. On x86 303114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger the "integer indefinite" value 0x80..00 is produced. 304114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger On PPC it is either 0x80..00 or 0x7F..FF depending on the sign 305114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger of the argument. 306c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger 307c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger Rounding is required whenever the destination type cannot 308c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger represent exactly all values of the source type. 309c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger */ 310c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger Iop_F64toI16, /* IRRoundingMode(I32) x F64 -> I16 */ 311c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger Iop_F64toI32, /* IRRoundingMode(I32) x F64 -> I32 */ 312c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger Iop_F64toI64, /* IRRoundingMode(I32) x F64 -> I64 */ 313c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger 314c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger Iop_I16toF64, /* I16 -> F64 */ 315114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger Iop_I32toF64, /* I32 -> F64 */ 3161ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul Iop_I64toF64, /* IRRoundingMode(I32) x I64 -> F64 */ 3171ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul 3181ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul Iop_F32toF64, /* F32 -> F64 */ 3191ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */ 3201ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul 3211ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul /* F64 -> F64, also takes an I32 first argument encoding the 3221ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul rounding mode. */ 3231ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul Iop_RoundF64, 3241ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul 3251ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul /* Reinterpretation. Take an F64 and produce an I64 with 3260a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul the same bit pattern, or vice versa. */ 3270a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_ReinterpF64asI64, Iop_ReinterpI64asF64, 3280a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3290a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* ------------------ 128-bit SIMD. ------------------ */ 3300a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3310a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* 128-bit ops */ 3320a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_And128, Iop_Or128, Iop_Xor128, 3330a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3340a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* --- 32x4 vector FP --- */ 3350a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3360a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* binary */ 3370a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 3380a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_Max32Fx4, Iop_Min32Fx4, 3390a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, 3400a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 3410a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3420a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* unary */ 3430a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4, 3440a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_ItoF32x4, /* first arg is IRRoundingMode (Ity_I32) */ 3450a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_FtoI32x4, /* first arg is IRRoundingMode (Ity_I32) */ 3460a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3470a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* --- 32x4 lowest-lane-only scalar FP --- */ 3480a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3490a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* In binary cases, upper 3/4 is copied from first operand. In 350abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul unary cases, upper 3/4 is copied from the operand. */ 3510a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul 3520a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul /* binary */ 3530a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 3540a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul Iop_Max32F0x4, Iop_Min32F0x4, 355abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 356abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul /* unary */ 357abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4, 358abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_ItoF320x4, /* first arg is IRRoundingMode (Ity_I32) */ 359abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_FtoI320x4, /* first arg is IRRoundingMode (Ity_I32) */ 360abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 361abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul /* --- pack / unpack --- */ 362abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 363abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul /* 64 <-> 128 bit pack/unpack */ 364abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_128to64, // :: V128 -> I64, low half 365abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_128HIto64, // :: V128 -> I64, high half 366abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_64HLto128, // :: (I64,I64) -> V128 367abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 368abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul /* 128 -> 32 bit unpack */ 369abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_128W3to32, // :: V128 -> I32, bits 127-96 370abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_128W2to32, // :: V128 -> I32, bits 95-64 371abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_128W1to32, // :: V128 -> I32, bits 63-32 372abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Iop_128W0to32 // :: V128 -> I32, bits 31-0 373abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul } 374abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul IROp; 375abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 376abd5627a6a034885b0b01b995c73870da1361bb0Brian Paulextern void ppIROp ( IROp ); 377abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 378abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 379abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul/* Encoding of IEEE754-specified rounding modes in Float -> Int 380abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul conversions. This is the same as the encoding used by Intel IA32 381abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul to indicate x87 rounding mode. */ 382abd5627a6a034885b0b01b995c73870da1361bb0Brian Paultypedef 383abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 } 384abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul IRRoundingMode; 385abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 386abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul/* Floating point comparison result values, as created by Iop_CmpF64. 387abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul This is also derived from what IA32 does. */ 388abd5627a6a034885b0b01b995c73870da1361bb0Brian Paultypedef 389abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul enum { 390abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Ircr_UN = 0x45, 391abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Ircr_LT = 0x01, 392abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Ircr_GT = 0x00, 393abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Ircr_EQ = 0x40 394abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul } 395abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul IRCmpF64Result; 396abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 397abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 398abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul/* ------------------ Expressions ------------------ */ 399abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul/* 400abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul Some details of expression semantics: 401abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul 4026988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRExpr_GetI (also IRStmt_PutI) 4036988f65e43297ae63bbce30bf882f870b370096cBrian Paul ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4046988f65e43297ae63bbce30bf882f870b370096cBrian Paul This carries two ints, which give the lowest and highest possible 4056988f65e43297ae63bbce30bf882f870b370096cBrian Paul byte offsets that the GetI can possibly reference. For example, if 4066988f65e43297ae63bbce30bf882f870b370096cBrian Paul the type is Ity_I32, and the Expr may have a value of M, M+4 or 4073ebbc176f9200ac954d461758937e755220ac551Ian Romanick M+8, where M is a translation-time known constant, then the low and 4083ebbc176f9200ac954d461758937e755220ac551Ian Romanick high limits are M and M+11 respectively. 4093ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4103ebbc176f9200ac954d461758937e755220ac551Ian Romanick PutI's limit values are interpreted identically. 4113ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4126988f65e43297ae63bbce30bf882f870b370096cBrian Paul The limit values are used by IR optimisers to establish 4133ebbc176f9200ac954d461758937e755220ac551Ian Romanick aliasing/non-aliasing between seperate GetI and PutI events, which 4143ebbc176f9200ac954d461758937e755220ac551Ian Romanick could be used to do reordering of them, or suchlike things. 4153ebbc176f9200ac954d461758937e755220ac551Ian Romanick Clearly it's critical to give the correct limit values -- this is 4166988f65e43297ae63bbce30bf882f870b370096cBrian Paul something that can't be automatically checked (in general), and so 4176988f65e43297ae63bbce30bf882f870b370096cBrian Paul the front-end writers must be very careful to tell the truth, since 4186988f65e43297ae63bbce30bf882f870b370096cBrian Paul not doing so could lead to obscure IR optimisation bugs. 4196988f65e43297ae63bbce30bf882f870b370096cBrian Paul 4206988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRExpr_CCall 4216988f65e43297ae63bbce30bf882f870b370096cBrian Paul ~~~~~~~~~~~~ 4223ebbc176f9200ac954d461758937e755220ac551Ian Romanick The name is the C helper function; the backends will call back to 4233ebbc176f9200ac954d461758937e755220ac551Ian Romanick the front ends to get the address of a host-code helper function to 4243ebbc176f9200ac954d461758937e755220ac551Ian Romanick be called. 4253ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4263ebbc176f9200ac954d461758937e755220ac551Ian Romanick The args are a NULL-terminated array of arguments. The stated 4273ebbc176f9200ac954d461758937e755220ac551Ian Romanick return IRType, and the implied argument types, must match that of 4283ebbc176f9200ac954d461758937e755220ac551Ian Romanick the function being called well enough so that the back end can 4293ebbc176f9200ac954d461758937e755220ac551Ian Romanick actually generate correct code for the call. 4303ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4316988f65e43297ae63bbce30bf882f870b370096cBrian Paul The called function **must** satisfy the following: 4323ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4333ebbc176f9200ac954d461758937e755220ac551Ian Romanick * no side effects -- must be a pure function, the result of which 4343ebbc176f9200ac954d461758937e755220ac551Ian Romanick depends only on the passed parameters. 4353ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4363ebbc176f9200ac954d461758937e755220ac551Ian Romanick * it may not look at, nor modify, any of the guest state since that 4376988f65e43297ae63bbce30bf882f870b370096cBrian Paul would hide guest state transitions from instrumenters 4383ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4393ebbc176f9200ac954d461758937e755220ac551Ian Romanick * it may not access guest memory, since that would hide guest 4403ebbc176f9200ac954d461758937e755220ac551Ian Romanick memory transactions from the instrumenters 4416988f65e43297ae63bbce30bf882f870b370096cBrian Paul 4426988f65e43297ae63bbce30bf882f870b370096cBrian Paul This is restrictive, but makes the semantics clean, and does 4436988f65e43297ae63bbce30bf882f870b370096cBrian Paul not interfere with IR optimisation. 4446988f65e43297ae63bbce30bf882f870b370096cBrian Paul 4456988f65e43297ae63bbce30bf882f870b370096cBrian Paul If you want to call a helper which can mess with guest state and/or 4466988f65e43297ae63bbce30bf882f870b370096cBrian Paul memory, instead use IRStmt_Dirty. This is a lot more flexible, but 4473ebbc176f9200ac954d461758937e755220ac551Ian Romanick you pay for that flexibility in that you have to give a bunch of 4483ebbc176f9200ac954d461758937e755220ac551Ian Romanick details about what the helper does (and you better be telling the 4493ebbc176f9200ac954d461758937e755220ac551Ian Romanick truth, otherwise any derived instrumentation will be wrong). Also 4503ebbc176f9200ac954d461758937e755220ac551Ian Romanick IRStmt_Dirty inhibits various IR optimisations and so can cause 4513ebbc176f9200ac954d461758937e755220ac551Ian Romanick quite poor code to be generated. Try to avoid it. 4523ebbc176f9200ac954d461758937e755220ac551Ian Romanick*/ 4533ebbc176f9200ac954d461758937e755220ac551Ian Romanick 4546988f65e43297ae63bbce30bf882f870b370096cBrian Paul/* The possible kinds of expressions are as follows: */ 4556988f65e43297ae63bbce30bf882f870b370096cBrian Paultypedef 4566988f65e43297ae63bbce30bf882f870b370096cBrian Paul enum { 4576988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Binder, /* Used only in pattern matching. 4586988f65e43297ae63bbce30bf882f870b370096cBrian Paul Not an expression. */ 4596988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Get, /* read guest state, fixed offset */ 4606988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_GetI, /* read guest state, run-time offset */ 4616988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Tmp, /* value of temporary */ 4626988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Binop, /* binary operation */ 4636988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Unop, /* unary operation */ 4646988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_LDle, /* little-endian read from memory */ 4656988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Const, /* constant-valued expression */ 4666988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_Mux0X, /* ternary if-then-else operator (STRICT) */ 4676988f65e43297ae63bbce30bf882f870b370096cBrian Paul Iex_CCall /* call to pure (side-effect-free) helper fn */ 4686988f65e43297ae63bbce30bf882f870b370096cBrian Paul } 4696988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRExprTag; 4706988f65e43297ae63bbce30bf882f870b370096cBrian Paul 4716988f65e43297ae63bbce30bf882f870b370096cBrian Paultypedef 4726988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct _IRExpr { 4736988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRExprTag tag; 4746988f65e43297ae63bbce30bf882f870b370096cBrian Paul union { 4756988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct { 4766988f65e43297ae63bbce30bf882f870b370096cBrian Paul Int binder; 4776988f65e43297ae63bbce30bf882f870b370096cBrian Paul } Binder; 4786988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct { 4796988f65e43297ae63bbce30bf882f870b370096cBrian Paul Int offset; 4806988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRType ty; 4816988f65e43297ae63bbce30bf882f870b370096cBrian Paul } Get; 4826988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct { 4836988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRArray* descr; 4846988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct _IRExpr* ix; 4856988f65e43297ae63bbce30bf882f870b370096cBrian Paul Int bias; 4866988f65e43297ae63bbce30bf882f870b370096cBrian Paul } GetI; 4876988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct { 4886988f65e43297ae63bbce30bf882f870b370096cBrian Paul IRTemp tmp; 489e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick } Tmp; 4906988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct { 491e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick IROp op; 492e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick struct _IRExpr* arg1; 4936988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct _IRExpr* arg2; 494e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick } Binop; 495e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick struct { 4966988f65e43297ae63bbce30bf882f870b370096cBrian Paul IROp op; 4976988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct _IRExpr* arg; 4986988f65e43297ae63bbce30bf882f870b370096cBrian Paul } Unop; 4996988f65e43297ae63bbce30bf882f870b370096cBrian Paul struct { 500abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul IRType ty; 501abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul struct _IRExpr* addr; 502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul } LDle; 503afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg struct { 504afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg IRConst* con; 505afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } Const; 5066dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell struct { 507e93243f8b7d43695654a36334c8cc5cea140d23cBrian IRCallee* cee; 508e93243f8b7d43695654a36334c8cc5cea140d23cBrian IRType retty; 509e93243f8b7d43695654a36334c8cc5cea140d23cBrian struct _IRExpr** args; 510e93243f8b7d43695654a36334c8cc5cea140d23cBrian } CCall; 511e93243f8b7d43695654a36334c8cc5cea140d23cBrian struct { 512519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul struct _IRExpr* cond; 513519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul struct _IRExpr* expr0; 514519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul struct _IRExpr* exprX; 515519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul } Mux0X; 516519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul } Iex; 517519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul } 518519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul IRExpr; 519519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul 520519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paulextern IRExpr* IRExpr_Binder ( Int binder ); 521519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paulextern IRExpr* IRExpr_Get ( Int off, IRType ty ); 5226dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ); 5238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulextern IRExpr* IRExpr_Tmp ( IRTemp tmp ); 5248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulextern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); 5256dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ); 5266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ); 5276dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRExpr* IRExpr_Const ( IRConst* con ); 5286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ); 5296dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ); 5306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 5318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulextern IRExpr* dopyIRExpr ( IRExpr* ); 532afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 5333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulextern void ppIRExpr ( IRExpr* ); 5343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul 5353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/* NULL-terminated IRExpr expression vectors, suitable for use as arg 5363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul lists in clean/dirty helper calls. */ 537fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul 5389c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paulextern IRExpr** mkIRExprVec_0 ( void ); 5399c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paulextern IRExpr** mkIRExprVec_1 ( IRExpr* ); 540fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paulextern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* ); 541fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paulextern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* ); 5429c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paulextern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* ); 5439c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paulextern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, 5449c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul IRExpr*, IRExpr*, IRExpr* ); 5459c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul 546a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paulextern IRExpr** sopyIRExprVec ( IRExpr** ); 547a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paulextern IRExpr** dopyIRExprVec ( IRExpr** ); 548fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul 549fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul/* Make a constant expression from the given host word taking into 550fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul account of course the host word size. */ 551a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern IRExpr* mkIRExpr_HWord ( HWord ); 5526dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 5536dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/* Convenience function for constructing clean helper calls. */ 554a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern 555a3f137094cd965d27e1b088499dd609b81a91906Brian PaulIRExpr* mkIRExprCCall ( IRType retty, 5566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell Int regparms, Char* name, void* addr, 5576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell IRExpr** args ); 5586dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 55977ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul 56077ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paulinline static Bool isAtom ( IRExpr* e ) { 561f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg return e->tag == Iex_Tmp || e->tag == Iex_Const; 56277ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul} 563a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 56477ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul 56577ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul/* ------------------ Jump kinds ------------------ */ 56677ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul 56777ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul/* This describes hints which can be passed to the dispatcher at guest 568a3f137094cd965d27e1b088499dd609b81a91906Brian Paul control-flow transfer points. 5693e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell*/ 5704cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paultypedef 5713e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell enum { 5721eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee Ijk_Boring=0x14000, /* not interesting; just goto next */ 5733e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell Ijk_Call, /* guest is doing a call */ 5743e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell Ijk_Ret, /* guest is doing a return */ 5753e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell Ijk_ClientReq, /* do guest client req before continuing */ 5763e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell Ijk_Syscall, /* do guest syscall before continuing */ 577f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg Ijk_Yield, /* client is yielding to thread scheduler */ 5784cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul Ijk_EmWarn /* report emulation warning before continuing */ 5793e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell } 580c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul IRJumpKind; 581c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul 5823e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwellextern void ppIRJumpKind ( IRJumpKind ); 5833e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell 5844cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul 5853e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell/* ------------------ Dirty helper calls ------------------ */ 5863e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell 5873e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell/* A dirty call is a flexible mechanism for calling a helper function 5883e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell or procedure. The helper function may read, write or modify client 5893e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell memory, and may read, write or modify client state. It can take 5903e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell arguments and optionally return a value. It may return different 5913e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell results and/or do different things when called repeated with the 5926dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell same arguments, by means of storing private state. 5936dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 5941eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee If a value is returned, it is assigned to the nominated return 5956dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell temporary. 5963e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell 597a3f137094cd965d27e1b088499dd609b81a91906Brian Paul Dirty calls are statements rather than expressions for obvious 59877ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul reasons. If a dirty call is stated as writing guest state, any 5993c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul values derived from the written parts of the guest state are 6003c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul invalid. Similarly, if the dirty call is stated as writing 60177ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul memory, any loaded values are invalidated by it. 6025ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell 6035ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell In order that instrumentation is possible, the call must state, and 6045ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell state correctly 6055ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell 6065ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell * whether it reads, writes or modifies memory, and if so where 6075ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell (only one chunk can be stated) 6083e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell 609b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * whether it reads, writes or modifies guest state, and if so which 61032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg pieces (several pieces may be stated, and currently their extents 61132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg must be known at translation-time). 61277ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul 61377ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul Normally, code is generated to pass just the args to the helper. 61477ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul However, if .needsBBP is set, then an extra first argument is 6156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell passed, which is the baseblock pointer, so that the callee can 6166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell access the guest state. It is invalid for .nFxState to be zero 6176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell but .needsBBP to be True, since .nFxState==0 is a claim that the 6186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell call does not access guest state. 6196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 6206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The 621aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul arguments are evaluated REGARDLESS of the guard value. It is 62277ee31930a1b0cc7766939415f4f04ed6a1fa4acBrian Paul unspecified the relative order of arg evaluation and guard 62377ee31930a1b0cc7766939415f4f04ed6a1fa4acBrian Paul evaluation. 624aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul*/ 6252465c4fa9cabe8c40e526b9e081de3b70c851455Brian Paul 6262465c4fa9cabe8c40e526b9e081de3b70c851455Brian Paul#define VEX_N_FXSTATE 5 /* enough for FSAVE/FRSTOR on x86 */ 6272465c4fa9cabe8c40e526b9e081de3b70c851455Brian Paul 6288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paultypedef 6298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul enum { 6308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul Ifx_None = 0x15000, /* no effect */ 63127f4484fb73ac7bf4f790ca2d3efd50b6bea25c3Brian Paul Ifx_Read, /* reads the resource */ 632bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick Ifx_Write, /* writes the resource */ 633bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick Ifx_Modify, /* modifies the resource */ 634bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 635aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul IREffect; 636aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul 637aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paulextern void ppIREffect ( IREffect ); 6386dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 63935f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 64035f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paultypedef 64135f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul struct { 64235f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul /* What to call, and details of args/results */ 64335f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRCallee* cee; /* where to call */ 64435f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */ 64535f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRExpr** args; /* arg list, ends in NULL */ 64635f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */ 64735f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 64835f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul /* Mem effects; we allow only one R/W/M region to be stated */ 64935f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IREffect mFx; /* indicates memory effects, if any */ 65035f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */ 65135f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul Int mSize; /* of access, or zero if mFx==Ifx_None */ 65235f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 65335f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul /* Guest state effects; up to N allowed */ 65435f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul Bool needsBBP; /* True => also pass guest state ptr to callee */ 65535f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul Int nFxState; /* must be 0 .. VEX_N_FXSTATE */ 65635f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul struct { 65735f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IREffect fx; /* read, write or modify? Ifx_None is invalid. */ 65835f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul Int offset; 65935f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul Int size; 66035f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul } fxState[VEX_N_FXSTATE]; 66135f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul } 66235f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRDirty; 66335f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 66435f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paulextern void ppIRDirty ( IRDirty* ); 66535f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paulextern IRDirty* emptyIRDirty ( void ); 66635f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 66735f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paulextern IRDirty* dopyIRDirty ( IRDirty* ); 66835f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 66935f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul/* A handy function which takes some of the tedium out of constructing 67035f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul dirty helper calls. The called function impliedly does not return 67135f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul any value and has a constant-True guard. The call is marked as 67235f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul accessing neither guest state nor memory (hence the "unsafe" 67335f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul designation) -- you can mess with this later if need be. A 67435f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul suitable IRCallee is constructed from the supplied bits. */ 67535f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paulextern 67635f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian PaulIRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr, 67735f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul IRExpr** args ); 67835f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul 67935f620d55ced7fcb3f39465c173ba2ae435a2ba1Brian Paul/* Similarly, make a zero-annotation dirty call which returns a value, 6803c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul and assign that to the given temp. */ 6813c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paulextern 6826dc85575000127630489b407c50a4b3ea87c9acbKeith WhitwellIRDirty* unsafeIRDirty_1_N ( IRTemp dst, 6836dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell Int regparms, Char* name, void* addr, 6846dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell IRExpr** args ); 6856dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 6866dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 6876dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/* ------------------ Statements ------------------ */ 6886dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 6896dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/* The possible kinds of statements are as follows: */ 69035d5301a54153930ee6fd60dff1010ce9f901397Brian Paultypedef 69135d5301a54153930ee6fd60dff1010ce9f901397Brian Paul enum { 6923c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul Ist_Put, /* write guest state, fixed offset */ 6933c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul Ist_PutI, /* write guest state, run-time offset */ 69435d5301a54153930ee6fd60dff1010ce9f901397Brian Paul Ist_Tmp, /* assign value to temporary */ 69535d5301a54153930ee6fd60dff1010ce9f901397Brian Paul Ist_STle, /* little-endian write to memory */ 69635d5301a54153930ee6fd60dff1010ce9f901397Brian Paul Ist_Dirty, /* call complex ("dirty") helper function */ 69735d5301a54153930ee6fd60dff1010ce9f901397Brian Paul Ist_Exit /* conditional exit from BB */ 6989818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul } 69935d5301a54153930ee6fd60dff1010ce9f901397Brian Paul IRStmtTag; 700fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian 70135d5301a54153930ee6fd60dff1010ce9f901397Brian Paultypedef 7029818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul struct _IRStmt { 70335d5301a54153930ee6fd60dff1010ce9f901397Brian Paul IRStmtTag tag; 704fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian union { 70535d5301a54153930ee6fd60dff1010ce9f901397Brian Paul struct { 7069818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul Int offset; 70735d5301a54153930ee6fd60dff1010ce9f901397Brian Paul IRExpr* data; 708fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian } Put; 70935d5301a54153930ee6fd60dff1010ce9f901397Brian Paul struct { 71035d5301a54153930ee6fd60dff1010ce9f901397Brian Paul IRArray* descr; 71135d5301a54153930ee6fd60dff1010ce9f901397Brian Paul IRExpr* ix; 71235d5301a54153930ee6fd60dff1010ce9f901397Brian Paul Int bias; 71335d5301a54153930ee6fd60dff1010ce9f901397Brian Paul IRExpr* data; 71435d5301a54153930ee6fd60dff1010ce9f901397Brian Paul } PutI; 7155ff4075a6961b26042dc2d7f4adcf333439823f4Brian Paul struct { 716a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell IRTemp tmp; 7179818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul IRExpr* data; 71835d5301a54153930ee6fd60dff1010ce9f901397Brian Paul } Tmp; 719a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell struct { 720fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian IRExpr* addr; 7218afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul IRExpr* data; 7228afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul } STle; 7239818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul struct { 7248afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul IRDirty* details; 7258afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul } Dirty; 726fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian struct { 727bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick IRExpr* guard; 728bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick IRJumpKind jk; 7299818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul IRConst* dst; 730bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } Exit; 731bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } Ist; 732fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian } 733bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick IRStmt; 734bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 7359818734e0148510967ca9ee0d1aa8b196b509f02Brian Paulextern IRStmt* IRStmt_Put ( Int off, IRExpr* data ); 736bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickextern IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix, Int bias, 737bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick IRExpr* data ); 738fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrianextern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ); 73935d5301a54153930ee6fd60dff1010ce9f901397Brian Paulextern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data ); 74008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paulextern IRStmt* IRStmt_Dirty ( IRDirty* details ); 74135d5301a54153930ee6fd60dff1010ce9f901397Brian Paulextern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ); 74235d5301a54153930ee6fd60dff1010ce9f901397Brian Paul 74335d5301a54153930ee6fd60dff1010ce9f901397Brian Paulextern IRStmt* dopyIRStmt ( IRStmt* ); 74435d5301a54153930ee6fd60dff1010ce9f901397Brian Paul 74535d5301a54153930ee6fd60dff1010ce9f901397Brian Paulextern void ppIRStmt ( IRStmt* ); 7466dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 747b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul 748b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul/* ------------------ Basic Blocks ------------------ */ 749b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul 750f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg/* A bunch of statements, expressions, etc, are incomplete without an 751b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul environment indicating the type of each IRTemp. So this provides 752b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul one. IR temporaries are really just unsigned ints and so this 753b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul provides an array, 0 .. n_types_used-1 of them. 754b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul*/ 755b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paultypedef 756b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul struct { 757b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul IRType* types; 758c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul Int types_size; 759c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul Int types_used; 760c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul } 7616dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell IRTypeEnv; 7626dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 7631eee1bac1f6d911e6124daafc9b9291666d91cefVinson Leeextern IRTemp newIRTemp ( IRTypeEnv*, IRType ); 7646dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* ); 7656dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 7666dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellextern void ppIRTypeEnv ( IRTypeEnv* ); 767c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul 768fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul 769fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul/* Basic blocks contain: 7703c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul - A table giving a type for each temp 7713c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul - An expandable array of statements 7725ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell - An expression of type 32 or 64 bits, depending on the 773fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul guest's word size, indicating the next destination. 774c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul - An indication of any special actions (JumpKind) needed 7755ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell for this final jump. 776c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul*/ 777c156eeb682d673e571c1798ff21e183ad4114feaBrian Paultypedef 778c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul struct _IRBB { 779bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick IRTypeEnv* tyenv; 780c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul IRStmt** stmts; 781fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul Int stmts_size; 782fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul Int stmts_used; 783fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul IRExpr* next; 784a3f137094cd965d27e1b088499dd609b81a91906Brian Paul IRJumpKind jumpkind; 785a3f137094cd965d27e1b088499dd609b81a91906Brian Paul } 786a3f137094cd965d27e1b088499dd609b81a91906Brian Paul IRBB; 787a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 788a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern IRBB* emptyIRBB ( void ); 789a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 790f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergextern IRBB* dopyIRBB ( IRBB* ); 791a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 792a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern void ppIRBB ( IRBB* ); 793a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 7945ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwellextern void addStmtToIRBB ( IRBB*, IRStmt* ); 7955ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell 7965ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell 7975ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell/*---------------------------------------------------------------*/ 7985ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell/*--- Helper functions for the IR ---*/ 799a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/*---------------------------------------------------------------*/ 800a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 801a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/* For messing with IR type environments */ 802a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern IRTypeEnv* emptyIRTypeEnv ( void ); 803a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 804a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/* What is the type of this expression? */ 8055ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwellextern IRType typeOfIRConst ( IRConst* ); 806a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp ); 807a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); 8085ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell 809a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/* Sanity check a BB of IR */ 810a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size ); 811a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern Bool isFlatIRStmt ( IRStmt* ); 812a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 813a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/* Is this any value actually in the enumeration 'IRType' ? */ 814a3f137094cd965d27e1b088499dd609b81a91906Brian Paulextern Bool isPlausibleType ( IRType ty ); 815a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 816a3f137094cd965d27e1b088499dd609b81a91906Brian Paul#endif /* ndef __LIBVEX_IR_H */ 817a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 818a3f137094cd965d27e1b088499dd609b81a91906Brian Paul 819a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/*---------------------------------------------------------------*/ 820f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg/*--- libvex_ir.h ---*/ 821a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/*---------------------------------------------------------------*/ 822a3f137094cd965d27e1b088499dd609b81a91906Brian Paul