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