libvex_ir.h revision 206c36410bd92f385b972e36a3a40e38675294e2
17d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
27d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*---------------------------------------------------------------*/
37d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*---                                                         ---*/
47d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*--- This file (libvex_ir.h) is                              ---*/
57d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*--- Copyright (C) OpenWorks LLP.  All rights reserved.      ---*/
67d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*---                                                         ---*/
77d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*---------------------------------------------------------------*/
87d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
97d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*
10c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru   This file is part of LibVEX, a library for dynamic binary
117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   instrumentation and translation.
127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.
147d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth   This library is made available under a dual licensing scheme.
160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth
177d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   If you link LibVEX against other code all of which is itself
187d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   licensed under the GNU General Public License, version 2 dated June
197d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
207d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   v2, as appearing in the file LICENSE.GPL.  If the file LICENSE.GPL
217d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   is missing, you can obtain a copy of the GPL v2 from the Free
227d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
237d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   02110-1301, USA.
247d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
257d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   For any other uses of LibVEX, you must first obtain a commercial
267d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   license from OpenWorks LLP.  Please contact info@open-works.co.uk
277d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   for information about commercial licensing.
287d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
297d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   This software is provided by OpenWorks LLP "as is" and any express
307d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   or implied warranties, including, but not limited to, the implied
317d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   warranties of merchantability and fitness for a particular purpose
327d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   are disclaimed.  In no event shall OpenWorks LLP be liable for any
337d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   direct, indirect, incidental, special, exemplary, or consequential
347d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   damages (including, but not limited to, procurement of substitute
357d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   goods or services; loss of use, data, or profits; or business
367d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   interruption) however caused and on any theory of liability,
377d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   whether in contract, strict liability, or tort (including
387d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   negligence or otherwise) arising in any way out of the use of this
397d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   software, even if advised of the possibility of such damage.
407d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
417d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   Neither the names of the U.S. Department of Energy nor the
427d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   University of California nor the names of its contributors may be
437d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   used to endorse or promote products derived from this software
447d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   without prior written permission.
457d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin*/
462d24e2a396a1d211baaeedf32148a3b657240170David Blaikie
472d24e2a396a1d211baaeedf32148a3b657240170David Blaikie#ifndef __LIBVEX_IR_H
487d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#define __LIBVEX_IR_H
497d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
507d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "libvex_basictypes.h"
517d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
527d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
537d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
547d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*---------------------------------------------------------------*/
557d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*--- Type definitions for the IR                             ---*/
567d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/*---------------------------------------------------------------*/
577d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
587d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* General comments about naming schemes:
597d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
607d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   All publically visible functions contain the name of the primary
617d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   type on which they operate (IRFoo, IRBar, etc).  Hence you should
627d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   be able to identify these functions by grepping for "IR[A-Z]".
637d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
647d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   For some type 'IRFoo':
657d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
667d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   - ppIRFoo is the printing method for IRFoo, printing it to the
677d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin     output channel specified in the LibVEX_Initialise call.
68fd22883a345b2e04d0bdb4d4b9ed64ceebdc0601John McCall
69bd3c5ecd37e760f0430c9cbd1fda5740eb7c0e27John McCall   - eqIRFoo is a structural equality predicate for IRFoos.
70bd3c5ecd37e760f0430c9cbd1fda5740eb7c0e27John McCall
71bd3c5ecd37e760f0430c9cbd1fda5740eb7c0e27John McCall   - dopyIRFoo is a deep copy constructor for IRFoos.
727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin     It recursively traverses the entire argument tree and
737d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin     produces a complete new tree.
747d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
757d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   - sopyIRFoo is the shallow copy constructor for IRFoos.
767d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin     It creates a new top-level copy of the supplied object,
777d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin     but does not copy any sub-objects.
787d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin*/
797d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
807d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* ------------------ Types ------------------ */
817d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
827d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef
837d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   enum {
847d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_INVALID=0x10FFF,
857d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_I1=0x11000,
867d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_I8,
877d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_I16,
887d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_I32,
897d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_I64,
907d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_I128,  /* 128-bit scalar */
917d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_F32,   /* IEEE 754 float */
927d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_F64,   /* IEEE 754 double */
937d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ity_V128   /* 128-bit SIMD */
947d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   }
957d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   IRType;
967d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
977d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern void ppIRType ( IRType );
987d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern Int  sizeofIRType ( IRType );
997d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1007d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1017d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* ------------------ Endianness ------------------ */
1027d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1037d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef
1047d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   enum {
1057d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Iend_LE=22, /* little endian */
1067d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Iend_BE=33 /* big endian */
1077d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   }
1087d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   IREndness;
1097d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1107d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* ------------------ Constants ------------------ */
1127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef
1147d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   enum {
1157d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_U1=0x12000,
1167d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_U8,
1177d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_U16,
1187d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_U32,
1197d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_U64,
1207d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_F64,   /* 64-bit IEEE754 floating */
1217d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_F64i,  /* 64-bit unsigned int to be interpreted literally
1227d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin                    as a IEEE754 double value. */
1237d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Ico_V128   /* 128-bit restricted vector constant, with 1 bit for
1247d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin                    each of 16 byte lanes */
1257d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   }
1267d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   IRConstTag;
1277d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1287d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef
1297d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   struct _IRConst {
1307d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      IRConstTag tag;
1317d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      union {
1327d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         Bool   U1;
1337d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         UChar  U8;
1347d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         UShort U16;
1357d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         UInt   U32;
1367d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         ULong  U64;
1377d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         Double F64;
1387d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         ULong  F64i;
1397d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin         UShort V128;
1407d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      } Ico;
1417d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   }
1427d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   IRConst;
1437d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1447d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_U1   ( Bool );
1457d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_U8   ( UChar );
1467d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_U16  ( UShort );
1477d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_U32  ( UInt );
1487d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_U64  ( ULong );
1497d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_F64  ( Double );
1507d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_F64i ( ULong );
1517d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* IRConst_V128 ( UShort );
1527d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1537d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRConst* dopyIRConst ( IRConst* );
1547d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1557d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern void ppIRConst ( IRConst* );
1567d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern Bool eqIRConst ( IRConst*, IRConst* );
1577d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1587d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1597d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* ------------------ Call targets ------------------ */
1607d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1617d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* Describes a helper function to call.  The name part is purely for
1627d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   pretty printing and not actually used.  regparms=n tells the back
1637d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   end that the callee has been declared
1647d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   "__attribute__((regparm(n)))".  On some targets (x86) the back end
1657d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   will need to construct a non-standard sequence to call a function
1667d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   declared like this.
1677d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1687d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   mcx_mask is a sop to Memcheck.  It indicates which args should be
1697d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   considered 'always defined' when lazily computing definedness of
1707d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   the result.  Bit 0 of mcx_mask corresponds to args[0], bit 1 to
1717d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   args[1], etc.  If a bit is set, the corresponding arg is excluded
1727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   (hence "x" in "mcx") from definedness checking.
1737d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin*/
1747d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1757d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef
1767d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   struct {
1777d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Int    regparms;
1787d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      HChar* name;
1797d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      void*  addr;
1807d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      UInt   mcx_mask;
1817d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   }
1827d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   IRCallee;
1837d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1847d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr );
1857d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1867d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRCallee* dopyIRCallee ( IRCallee* );
1877d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1887d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern void ppIRCallee ( IRCallee* );
1897d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1907d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1917d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* ------------------ Guest state arrays ------------------ */
1927d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1937d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef
1947d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   struct {
1957d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Int    base;
1967d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      IRType elemTy;
1977d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Int    nElems;
1987d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   }
1997d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   IRArray;
2007d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
2017d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRArray* mkIRArray ( Int, IRType, Int );
2027d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
2037d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern IRArray* dopyIRArray ( IRArray* );
2047d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
2057d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern void ppIRArray ( IRArray* );
2067d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinextern Bool eqIRArray ( IRArray*, IRArray* );
2077d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
2087d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
2097d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* ------------------ Temporaries ------------------ */
2107d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
2117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin/* The IR optimiser relies on the fact that IRTemps are 32-bit
2127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin   ints.  Do not change them to be ints of any other size. */
2137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golintypedef UInt IRTemp;
2147d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
215extern void ppIRTemp ( IRTemp );
216
217#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF)
218
219
220/* ------------------ Binary and unary ops ------------------ */
221
222typedef
223   enum {
224      /* -- Do not change this ordering.  The IR generators rely on
225            (eg) Iop_Add64 == IopAdd8 + 3. -- */
226
227      Iop_INVALID=0x13000,
228      Iop_Add8,  Iop_Add16,  Iop_Add32,  Iop_Add64,
229      Iop_Sub8,  Iop_Sub16,  Iop_Sub32,  Iop_Sub64,
230      /* Signless mul.  MullS/MullU is elsewhere. */
231      Iop_Mul8,  Iop_Mul16,  Iop_Mul32,  Iop_Mul64,
232      Iop_Or8,   Iop_Or16,   Iop_Or32,   Iop_Or64,
233      Iop_And8,  Iop_And16,  Iop_And32,  Iop_And64,
234      Iop_Xor8,  Iop_Xor16,  Iop_Xor32,  Iop_Xor64,
235      Iop_Shl8,  Iop_Shl16,  Iop_Shl32,  Iop_Shl64,
236      Iop_Shr8,  Iop_Shr16,  Iop_Shr32,  Iop_Shr64,
237      Iop_Sar8,  Iop_Sar16,  Iop_Sar32,  Iop_Sar64,
238      /* Integer comparisons. */
239      Iop_CmpEQ8,  Iop_CmpEQ16,  Iop_CmpEQ32,  Iop_CmpEQ64,
240      Iop_CmpNE8,  Iop_CmpNE16,  Iop_CmpNE32,  Iop_CmpNE64,
241      /* Tags for unary ops */
242      Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
243      Iop_Neg8,  Iop_Neg16,  Iop_Neg32,  Iop_Neg64,
244
245      /* -- Ordering not important after here. -- */
246
247      /* Widening multiplies */
248      Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
249      Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
250
251      /* Wierdo integer stuff */
252      Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
253      Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
254      /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
255         zero.  You must ensure they are never given a zero argument.
256      */
257
258      /* Standard integer comparisons */
259      Iop_CmpLT32S, Iop_CmpLT64S,
260      Iop_CmpLE32S, Iop_CmpLE64S,
261      Iop_CmpLT32U, Iop_CmpLT64U,
262      Iop_CmpLE32U, Iop_CmpLE64U,
263
264      /* As a sop to Valgrind-Memcheck, the following are useful. */
265      Iop_CmpNEZ8, Iop_CmpNEZ16,  Iop_CmpNEZ32,  Iop_CmpNEZ64,
266
267      /* PowerPC-style 3-way integer comparisons.  Without them it is difficult
268         to simulate PPC efficiently.
269         op(x,y) | x < y  = 0x8 else
270                 | x > y  = 0x4 else
271                 | x == y = 0x2
272      */
273      Iop_CmpORD32U, Iop_CmpORD32S,
274
275      /* Division */
276      /* TODO: clarify semantics wrt rounding, negative values, whatever */
277      Iop_DivU32,   // :: I32,I32 -> I32 (simple div, no mod)
278      Iop_DivS32,   // ditto, signed
279
280      Iop_DivModU64to32, // :: I64,I32 -> I64
281                         // of which lo half is div and hi half is mod
282      Iop_DivModS64to32, // ditto, signed
283
284      Iop_DivModU128to64, // :: V128,I64 -> V128
285                          // of which lo half is div and hi half is mod
286      Iop_DivModS128to64, // ditto, signed
287
288      /* Integer conversions.  Some of these are redundant (eg
289         Iop_64to8 is the same as Iop_64to32 and then Iop_32to8), but
290         having a complete set reduces the typical dynamic size of IR
291         and makes the instruction selectors easier to write. */
292
293      /* Widening conversions */
294      Iop_8Uto16, Iop_8Uto32,  Iop_8Uto64,
295                  Iop_16Uto32, Iop_16Uto64,
296                               Iop_32Uto64,
297      Iop_8Sto16, Iop_8Sto32,  Iop_8Sto64,
298                  Iop_16Sto32, Iop_16Sto64,
299                               Iop_32Sto64,
300
301      /* Narrowing conversions */
302      Iop_64to8, Iop_32to8, Iop_64to16,
303      /* 8 <-> 16 bit conversions */
304      Iop_16to8,      // :: I16 -> I8, low half
305      Iop_16HIto8,    // :: I16 -> I8, high half
306      Iop_8HLto16,    // :: (I8,I8) -> I16
307      /* 16 <-> 32 bit conversions */
308      Iop_32to16,     // :: I32 -> I16, low half
309      Iop_32HIto16,   // :: I32 -> I16, high half
310      Iop_16HLto32,   // :: (I16,I16) -> I32
311      /* 32 <-> 64 bit conversions */
312      Iop_64to32,     // :: I64 -> I32, low half
313      Iop_64HIto32,   // :: I64 -> I32, high half
314      Iop_32HLto64,   // :: (I32,I32) -> I64
315      /* 64 <-> 128 bit conversions */
316      Iop_128to64,    // :: I128 -> I64, low half
317      Iop_128HIto64,  // :: I128 -> I64, high half
318      Iop_64HLto128,  // :: (I64,I64) -> I128
319      /* 1-bit stuff */
320      Iop_Not1,   /* :: Ity_Bit -> Ity_Bit */
321      Iop_32to1,  /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
322      Iop_64to1,  /* :: Ity_I64 -> Ity_Bit, just select bit[0] */
323      Iop_1Uto8,  /* :: Ity_Bit -> Ity_I8,  unsigned widen */
324      Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */
325      Iop_1Uto64, /* :: Ity_Bit -> Ity_I64, unsigned widen */
326      Iop_1Sto8,  /* :: Ity_Bit -> Ity_I8,  signed widen */
327      Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */
328      Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */
329      Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */
330
331      /* ------ Floating point.  We try and be IEEE754 compliant. ------ */
332
333      /* Binary operations mandated by IEEE754. */
334      Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */
335
336      /* Binary ops supported by IA32 but not mandated by 754. */
337      Iop_AtanF64,       /* FPATAN,  arctan(arg1/arg2)       */
338      Iop_Yl2xF64,       /* FYL2X,   arg1 * log2(arg2)       */
339      Iop_Yl2xp1F64,     /* FYL2XP1, arg1 * log2(arg2+1.0)   */
340      Iop_PRemF64,       /* FPREM,   non-IEEE remainder(arg1/arg2)    */
341      Iop_PRemC3210F64,  /* C3210 flags resulting from FPREM, :: I32 */
342      Iop_PRem1F64,      /* FPREM1,  IEEE remainder(arg1/arg2)    */
343      Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */
344      Iop_ScaleF64,      /* FSCALE,  arg1 * (2^RoundTowardsZero(arg2)) */
345      /* Note that on x86 guest, PRem1{C3210} has the same behaviour
346         as the IEEE mandated RemF64, except it is limited in the
347         range of its operand.  Hence the partialness. */
348
349      /* Unary operations mandated by IEEE754. */
350      Iop_NegF64, Iop_SqrtF64,
351
352      /* Unary ops supported by IA32 but not mandated by 754. */
353      Iop_AbsF64,    /* FABS */
354      Iop_SinF64,    /* FSIN */
355      Iop_CosF64,    /* FCOS */
356      Iop_TanF64,    /* FTAN */
357      Iop_2xm1F64,   /* (2^arg - 1.0) */
358
359      /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following:
360            0x45 Unordered
361            0x01 LT
362            0x00 GT
363            0x40 EQ
364         This just happens to be the Intel encoding.  The values
365         are recorded in the type IRCmpF64Result.
366      */
367      Iop_CmpF64,
368
369      /* --- Int to/from FP conversions. --- */
370      /* For the most part, these take a first argument :: Ity_I32
371         (as IRRoundingMode) which is an indication of the rounding
372         mode to use, as per the following encoding:
373            00b  to nearest (the default)
374            01b  to -infinity
375            10b  to +infinity
376            11b  to zero
377         This just happens to be the Intel encoding.  For reference only,
378         the PPC encoding is:
379            00b  to nearest (the default)
380            01b  to zero
381            10b  to +infinity
382            11b  to -infinity
383         Any PPC -> IR front end will have to translate these PPC
384         encodings to the standard encodings.
385
386         If one of these conversions gets an out-of-range condition,
387         or a NaN, as an argument, the result is host-defined.  On x86
388         the "integer indefinite" value 0x80..00 is produced.
389         On PPC it is either 0x80..00 or 0x7F..FF depending on the sign
390         of the argument.
391
392         Rounding is required whenever the destination type cannot
393         represent exactly all values of the source type.
394      */
395      Iop_F64toI16,  /* IRRoundingMode(I32) x F64 -> I16 */
396      Iop_F64toI32,  /* IRRoundingMode(I32) x F64 -> I32 */
397      Iop_F64toI64,  /* IRRoundingMode(I32) x F64 -> I64 */
398
399      Iop_I16toF64,  /*                       I16 -> F64 */
400      Iop_I32toF64,  /*                       I32 -> F64 */
401      Iop_I64toF64,  /* IRRoundingMode(I32) x I64 -> F64 */
402
403      Iop_F32toF64,  /*                       F32 -> F64 */
404      Iop_F64toF32,  /* IRRoundingMode(I32) x F64 -> F32 */
405
406      /* F64 -> F64, also takes an I32 first argument encoding the
407         rounding mode. */
408      Iop_RoundF64,
409
410      /* Reinterpretation.  Take an F64 and produce an I64 with
411         the same bit pattern, or vice versa. */
412      Iop_ReinterpF64asI64, Iop_ReinterpI64asF64,
413      Iop_ReinterpF32asI32, Iop_ReinterpI32asF32,
414
415      /* ------------------ 64-bit SIMD Integer. ------------------ */
416
417      /* MISC (vector integer cmp != 0) */
418      Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2,
419
420      /* ADDITION (normal / unsigned sat / signed sat) */
421      Iop_Add8x8,   Iop_Add16x4,   Iop_Add32x2,
422      Iop_QAdd8Ux8, Iop_QAdd16Ux4,
423      Iop_QAdd8Sx8, Iop_QAdd16Sx4,
424
425      /* SUBTRACTION (normal / unsigned sat / signed sat) */
426      Iop_Sub8x8,   Iop_Sub16x4,   Iop_Sub32x2,
427      Iop_QSub8Ux8, Iop_QSub16Ux4,
428      Iop_QSub8Sx8, Iop_QSub16Sx4,
429
430      /* MULTIPLICATION (normal / high half of signed/unsigned) */
431      Iop_Mul16x4,
432      Iop_MulHi16Ux4,
433      Iop_MulHi16Sx4,
434
435      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
436      Iop_Avg8Ux8,
437      Iop_Avg16Ux4,
438
439      /* MIN/MAX */
440      Iop_Max16Sx4,
441      Iop_Max8Ux8,
442      Iop_Min16Sx4,
443      Iop_Min8Ux8,
444
445      /* COMPARISON */
446      Iop_CmpEQ8x8,  Iop_CmpEQ16x4,  Iop_CmpEQ32x2,
447      Iop_CmpGT8Sx8, Iop_CmpGT16Sx4, Iop_CmpGT32Sx2,
448
449      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
450      Iop_ShlN16x4, Iop_ShlN32x2,
451      Iop_ShrN16x4, Iop_ShrN32x2,
452      Iop_SarN16x4, Iop_SarN32x2,
453
454      /* NARROWING -- narrow 2xI64 into 1xI64, hi half from left arg */
455      Iop_QNarrow16Ux4,
456      Iop_QNarrow16Sx4,
457      Iop_QNarrow32Sx2,
458
459      /* INTERLEAVING -- interleave lanes from low or high halves of
460         operands.  Most-significant result lane is from the left
461         arg. */
462      Iop_InterleaveHI8x8, Iop_InterleaveHI16x4, Iop_InterleaveHI32x2,
463      Iop_InterleaveLO8x8, Iop_InterleaveLO16x4, Iop_InterleaveLO32x2,
464
465      /* ------------------ 128-bit SIMD FP. ------------------ */
466
467      /* --- 32x4 vector FP --- */
468
469      /* binary */
470      Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4,
471      Iop_Max32Fx4, Iop_Min32Fx4,
472      Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4,
473      Iop_CmpGT32Fx4, Iop_CmpGE32Fx4,
474
475      /* unary */
476      Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4,
477
478      /* --- 32x4 lowest-lane-only scalar FP --- */
479
480      /* In binary cases, upper 3/4 is copied from first operand.  In
481         unary cases, upper 3/4 is copied from the operand. */
482
483      /* binary */
484      Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4,
485      Iop_Max32F0x4, Iop_Min32F0x4,
486      Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4,
487
488      /* unary */
489      Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4,
490
491      /* --- 64x2 vector FP --- */
492
493      /* binary */
494      Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2,
495      Iop_Max64Fx2, Iop_Min64Fx2,
496      Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2,
497
498      /* unary */
499      Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2,
500
501      /* --- 64x2 lowest-lane-only scalar FP --- */
502
503      /* In binary cases, upper half is copied from first operand.  In
504         unary cases, upper half is copied from the operand. */
505
506      /* binary */
507      Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2,
508      Iop_Max64F0x2, Iop_Min64F0x2,
509      Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2,
510
511      /* unary */
512      Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2,
513
514      /* --- pack / unpack --- */
515
516      /* 64 <-> 128 bit vector */
517      Iop_V128to64,     // :: V128 -> I64, low half
518      Iop_V128HIto64,   // :: V128 -> I64, high half
519      Iop_64HLtoV128,   // :: (I64,I64) -> V128
520
521      Iop_64UtoV128,
522      Iop_SetV128lo64,
523
524      /* 32 <-> 128 bit vector */
525      Iop_32UtoV128,
526      Iop_V128to32,     // :: V128 -> I32, lowest lane
527      Iop_SetV128lo32,  // :: (V128,I32) -> V128
528
529      /* ------------------ 128-bit SIMD Integer. ------------------ */
530
531      /* BITWISE OPS */
532      Iop_NotV128,
533      Iop_AndV128, Iop_OrV128, Iop_XorV128,
534
535      /* VECTOR SHIFT (shift amt :: Ity_I8) */
536      Iop_ShlV128, Iop_ShrV128,
537
538      /* MISC (vector integer cmp != 0) */
539      Iop_CmpNEZ8x16, Iop_CmpNEZ16x8, Iop_CmpNEZ32x4, Iop_CmpNEZ64x2,
540
541      /* ADDITION (normal / unsigned sat / signed sat) */
542      Iop_Add8x16,   Iop_Add16x8,   Iop_Add32x4,  Iop_Add64x2,
543      Iop_QAdd8Ux16, Iop_QAdd16Ux8, Iop_QAdd32Ux4,
544      Iop_QAdd8Sx16, Iop_QAdd16Sx8, Iop_QAdd32Sx4,
545
546      /* SUBTRACTION (normal / unsigned sat / signed sat) */
547      Iop_Sub8x16,   Iop_Sub16x8,   Iop_Sub32x4,  Iop_Sub64x2,
548      Iop_QSub8Ux16, Iop_QSub16Ux8, Iop_QSub32Ux4,
549      Iop_QSub8Sx16, Iop_QSub16Sx8, Iop_QSub32Sx4,
550
551      /* MULTIPLICATION (normal / high half of signed/unsigned) */
552      Iop_Mul16x8,
553      Iop_MulLo16Ux8, Iop_MulLo32Ux4,
554      Iop_MulLo16Sx8, Iop_MulLo32Sx4,
555      Iop_MulHi16Ux8, Iop_MulHi32Ux4,
556      Iop_MulHi16Sx8, Iop_MulHi32Sx4,
557      /* (widening signed/unsigned of even lanes, with lowest lane=zero) */
558      Iop_MullEven8Ux16, Iop_MullEven16Ux8,
559      Iop_MullEven8Sx16, Iop_MullEven16Sx8,
560
561      /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
562      Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4,
563      Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4,
564
565      /* MIN/MAX */
566      Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4,
567      Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4,
568      Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4,
569      Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4,
570
571      /* COMPARISON */
572      Iop_CmpEQ8x16,  Iop_CmpEQ16x8,  Iop_CmpEQ32x4,
573      Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
574      Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
575
576      /* VECTOR x SCALAR SHIFT (shift amt :: Ity_I8) */
577      Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2,
578      Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2,
579      Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4,
580
581      /* VECTOR x VECTOR SHIFT / ROTATE */
582      Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4,
583      Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4,
584      Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4,
585      Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4,
586
587      /* NARROWING -- narrow 2xV128 into 1xV128, hi half from left arg */
588      /* Note: the 16{U,S} and 32{U,S} are the pre-narrow lane widths. */
589      Iop_QNarrow16Ux8, Iop_QNarrow32Ux4,
590      Iop_QNarrow16Sx8, Iop_QNarrow32Sx4,
591      Iop_Narrow16x8, Iop_Narrow32x4,
592
593      /* INTERLEAVING -- interleave lanes from low or high halves of
594         operands.  Most-significant result lane is from the left
595         arg. */
596      Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
597      Iop_InterleaveHI32x4, Iop_InterleaveHI64x2,
598      Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
599      Iop_InterleaveLO32x4, Iop_InterleaveLO64x2,
600
601      /* DUPLICATING -- copy value to all lanes */
602      Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
603
604      /* PERMUTING -- copy src bytes to dst,
605         as indexed by control vector bytes:
606            for i in 0 .. 15 . result[i] = argL[ argR[i] ]
607         argR[i] values may only be in the range 0 .. 15, else behaviour
608         is undefined. */
609      Iop_Perm8x16
610   }
611   IROp;
612
613extern void ppIROp ( IROp );
614
615
616/* Encoding of IEEE754-specified rounding modes in Float -> Int
617   conversions.  This is the same as the encoding used by Intel IA32
618   to indicate x87 rounding mode. */
619typedef
620   enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 }
621   IRRoundingMode;
622
623/* Floating point comparison result values, as created by Iop_CmpF64.
624   This is also derived from what IA32 does. */
625typedef
626   enum {
627      Ircr_UN = 0x45,
628      Ircr_LT = 0x01,
629      Ircr_GT = 0x00,
630      Ircr_EQ = 0x40
631   }
632   IRCmpF64Result;
633
634
635/* ------------------ Expressions ------------------ */
636/*
637   Some details of expression semantics:
638
639   IRExpr_GetI (also IRStmt_PutI)
640   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
641   These allow circular indexing into parts of the guest state, which
642   is essential for modelling situations where the identity of guest
643   registers is not known until run time.  One example is the x87 FP
644   register stack.
645
646   The part of the guest state to be treated as a circular array is
647   described in an IRArray structure attached to the GetI/PutI.
648   IRArray holds the offset of the first element in the array, the
649   type of each element, and the number of elements.
650
651   The array index is indicated rather indirectly, in a way which
652   makes optimisation easy: as the sum of variable part (the 'ix'
653   field) and a constant offset (the 'bias' field).
654
655   Since the indexing is circular, the actual array index to use
656   is computed as (ix + bias) % number-of-elements-in-the-array.
657
658   Here's an example.  The description
659
660      (96:8xF64)[t39,-7]
661
662   describes an array of 8 F64-typed values, the guest-state-offset
663   of the first being 96.  This array is being indexed at
664   (t39 - 7) % 8.
665
666   It is important to get the array size/type exactly correct since IR
667   optimisation looks closely at such info in order to establish
668   aliasing/non-aliasing between seperate GetI and PutI events, which
669   is used to establish when they can be reordered, etc.  Putting
670   incorrect info in will lead to obscure IR optimisation bugs.
671
672   IRExpr_CCall
673   ~~~~~~~~~~~~
674   The name is the C helper function; the backends will call back to
675   the front ends to get the address of a host-code helper function to
676   be called.
677
678   The args are a NULL-terminated array of arguments.  The stated
679   return IRType, and the implied argument types, must match that of
680   the function being called well enough so that the back end can
681   actually generate correct code for the call.
682
683   The called function **must** satisfy the following:
684
685   * no side effects -- must be a pure function, the result of which
686     depends only on the passed parameters.
687
688   * it may not look at, nor modify, any of the guest state since that
689     would hide guest state transitions from instrumenters
690
691   * it may not access guest memory, since that would hide guest
692     memory transactions from the instrumenters
693
694   This is restrictive, but makes the semantics clean, and does
695   not interfere with IR optimisation.
696
697   If you want to call a helper which can mess with guest state and/or
698   memory, instead use IRStmt_Dirty.  This is a lot more flexible, but
699   you pay for that flexibility in that you have to give a bunch of
700   details about what the helper does (and you better be telling the
701   truth, otherwise any derived instrumentation will be wrong).  Also
702   IRStmt_Dirty inhibits various IR optimisations and so can cause
703   quite poor code to be generated.  Try to avoid it.  */
704
705/* The possible kinds of expressions are as follows: */
706typedef
707   enum {
708      Iex_Binder,  /* Used only in pattern matching.
709                      Not an expression. */
710      Iex_Get,     /* read guest state, fixed offset */
711      Iex_GetI,    /* read guest state, run-time offset */
712      Iex_Tmp,     /* value of temporary */
713      Iex_Binop,   /* binary operation */
714      Iex_Unop,    /* unary operation */
715      Iex_Load,    /* read from memory */
716      Iex_Const,   /* constant-valued expression */
717      Iex_Mux0X,   /* ternary if-then-else operator (STRICT) */
718      Iex_CCall    /* call to pure (side-effect-free) helper fn */
719   }
720   IRExprTag;
721
722typedef
723   struct _IRExpr {
724      IRExprTag tag;
725      union {
726         struct {
727            Int binder;
728         } Binder;
729         struct {
730            Int    offset;
731            IRType ty;
732         } Get;
733         struct {
734            IRArray* descr;
735            struct _IRExpr* ix;
736            Int bias;
737         } GetI;
738         struct {
739            IRTemp tmp;
740         } Tmp;
741         struct {
742            IROp op;
743            struct _IRExpr* arg1;
744            struct _IRExpr* arg2;
745         } Binop;
746         struct {
747            IROp op;
748            struct _IRExpr* arg;
749         } Unop;
750         struct {
751            IREndness end;
752            IRType ty;
753            struct _IRExpr* addr;
754         } Load;
755         struct {
756            IRConst* con;
757         } Const;
758         struct {
759            IRCallee* cee;
760            IRType    retty;
761            struct _IRExpr** args;
762         }  CCall;
763         struct {
764            struct _IRExpr* cond;
765            struct _IRExpr* expr0;
766            struct _IRExpr* exprX;
767         } Mux0X;
768      } Iex;
769   }
770   IRExpr;
771
772extern IRExpr* IRExpr_Binder ( Int binder );
773extern IRExpr* IRExpr_Get    ( Int off, IRType ty );
774extern IRExpr* IRExpr_GetI   ( IRArray* descr, IRExpr* ix, Int bias );
775extern IRExpr* IRExpr_Tmp    ( IRTemp tmp );
776extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
777extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
778extern IRExpr* IRExpr_Load   ( IREndness end, IRType ty, IRExpr* addr );
779extern IRExpr* IRExpr_Const  ( IRConst* con );
780extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
781extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
782
783extern IRExpr* dopyIRExpr ( IRExpr* );
784
785extern void ppIRExpr ( IRExpr* );
786
787/* NULL-terminated IRExpr expression vectors, suitable for use as arg
788   lists in clean/dirty helper calls. */
789
790extern IRExpr** mkIRExprVec_0 ( void );
791extern IRExpr** mkIRExprVec_1 ( IRExpr* );
792extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* );
793extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* );
794extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* );
795extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*,
796                                IRExpr*, IRExpr*, IRExpr* );
797
798extern IRExpr** sopyIRExprVec ( IRExpr** );
799extern IRExpr** dopyIRExprVec ( IRExpr** );
800
801/* Make a constant expression from the given host word taking into
802   account of course the host word size. */
803extern IRExpr* mkIRExpr_HWord ( HWord );
804
805/* Convenience function for constructing clean helper calls. */
806extern
807IRExpr* mkIRExprCCall ( IRType retty,
808                        Int regparms, HChar* name, void* addr,
809                        IRExpr** args );
810
811
812/* Convenience functions for atoms, that is, IRExprs which
813   are either Iex_Tmp or Iex_Const. */
814static inline Bool isIRAtom ( IRExpr* e ) {
815   return toBool(e->tag == Iex_Tmp || e->tag == Iex_Const);
816}
817
818/* Are these two IR atoms identical?  Causes an assertion
819   failure if they are passed non-atoms. */
820extern Bool eqIRAtom ( IRExpr*, IRExpr* );
821
822
823/* ------------------ Jump kinds ------------------ */
824
825/* This describes hints which can be passed to the dispatcher at guest
826   control-flow transfer points.
827
828   Re Ijk_Invalidate: the guest state _must_ have two
829   pseudo-registers, guest_TISTART and guest_TILEN, which specify the
830   start and length of the region to be invalidated.  These are both
831   the size of a guest word. It is the responsibility of the relevant
832   toIR.c to ensure that these are filled in with suitable values
833   before issuing a jump of kind Ijk_TInval.
834*/
835typedef
836   enum {
837      Ijk_Boring=0x14000, /* not interesting; just goto next */
838      Ijk_Call,           /* guest is doing a call */
839      Ijk_Ret,            /* guest is doing a return */
840      Ijk_ClientReq,      /* do guest client req before continuing */
841      Ijk_Yield,          /* client is yielding to thread scheduler */
842      Ijk_EmWarn,         /* report emulation warning before continuing */
843      Ijk_NoDecode,       /* next instruction cannot be decoded */
844      Ijk_MapFail,        /* Vex-provided address translation failed */
845      Ijk_TInval,         /* Invalidate translations before continuing. */
846      /* Unfortunately, various guest-dependent syscall kinds.  They
847	 all mean: do a syscall before continuing. */
848      Ijk_Sys_syscall,    /* amd64 'syscall', ppc32 'sc' */
849      Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
850      Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
851      Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes
852                             invalid at the point this happens. */
853   }
854   IRJumpKind;
855
856extern void ppIRJumpKind ( IRJumpKind );
857
858
859/* ------------------ Dirty helper calls ------------------ */
860
861/* A dirty call is a flexible mechanism for calling a helper function
862   or procedure.  The helper function may read, write or modify client
863   memory, and may read, write or modify client state.  It can take
864   arguments and optionally return a value.  It may return different
865   results and/or do different things when called repeated with the
866   same arguments, by means of storing private state.
867
868   If a value is returned, it is assigned to the nominated return
869   temporary.
870
871   Dirty calls are statements rather than expressions for obvious
872   reasons.  If a dirty call is stated as writing guest state, any
873   values derived from the written parts of the guest state are
874   invalid.  Similarly, if the dirty call is stated as writing
875   memory, any loaded values are invalidated by it.
876
877   In order that instrumentation is possible, the call must state, and
878   state correctly
879
880   * whether it reads, writes or modifies memory, and if so where
881     (only one chunk can be stated)
882
883   * whether it reads, writes or modifies guest state, and if so which
884     pieces (several pieces may be stated, and currently their extents
885     must be known at translation-time).
886
887   Normally, code is generated to pass just the args to the helper.
888   However, if .needsBBP is set, then an extra first argument is
889   passed, which is the baseblock pointer, so that the callee can
890   access the guest state.  It is invalid for .nFxState to be zero
891   but .needsBBP to be True, since .nFxState==0 is a claim that the
892   call does not access guest state.
893
894   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
895   arguments are evaluated REGARDLESS of the guard value.  It is
896   unspecified the relative order of arg evaluation and guard
897   evaluation.
898*/
899
900#define VEX_N_FXSTATE  7   /* enough for FXSAVE/FXRSTOR on x86 */
901
902typedef
903   enum {
904      Ifx_None = 0x15000,   /* no effect */
905      Ifx_Read,             /* reads the resource */
906      Ifx_Write,            /* writes the resource */
907      Ifx_Modify,           /* modifies the resource */
908   }
909   IREffect;
910
911extern void ppIREffect ( IREffect );
912
913
914typedef
915   struct {
916      /* What to call, and details of args/results */
917      IRCallee* cee;    /* where to call */
918      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
919      IRExpr**  args;   /* arg list, ends in NULL */
920      IRTemp    tmp;    /* to assign result to, or IRTemp_INVALID if none */
921
922      /* Mem effects; we allow only one R/W/M region to be stated */
923      IREffect  mFx;    /* indicates memory effects, if any */
924      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
925      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
926
927      /* Guest state effects; up to N allowed */
928      Bool needsBBP; /* True => also pass guest state ptr to callee */
929      Int  nFxState; /* must be 0 .. VEX_N_FXSTATE */
930      struct {
931         IREffect fx;   /* read, write or modify?  Ifx_None is invalid. */
932         Int      offset;
933         Int      size;
934      } fxState[VEX_N_FXSTATE];
935   }
936   IRDirty;
937
938extern void     ppIRDirty ( IRDirty* );
939extern IRDirty* emptyIRDirty ( void );
940
941extern IRDirty* dopyIRDirty ( IRDirty* );
942
943/* A handy function which takes some of the tedium out of constructing
944   dirty helper calls.  The called function impliedly does not return
945   any value and has a constant-True guard.  The call is marked as
946   accessing neither guest state nor memory (hence the "unsafe"
947   designation) -- you can mess with this later if need be.  A
948   suitable IRCallee is constructed from the supplied bits. */
949extern
950IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr,
951                             IRExpr** args );
952
953/* Similarly, make a zero-annotation dirty call which returns a value,
954   and assign that to the given temp. */
955extern
956IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
957                             Int regparms, HChar* name, void* addr,
958                             IRExpr** args );
959
960
961/* ------------------ Statements ------------------ */
962
963/* The possible kinds of statements are as follows.  Those marked
964   OPTIONAL are hints of one kind or another, and as such do not
965   denote any change in the guest state or of IR temporaries.  They
966   can therefore be omitted without changing the meaning denoted by
967   the IR.
968
969   At the moment, the only AbiHint is one which indicates that a given
970   chunk of address space has become undefined.  This is used on
971   amd64-linux to pass stack-redzoning hints to whoever wants to see
972   them.
973*/
974typedef
975   enum {
976      Ist_NoOp,    /* OPTIONAL: no-op (usually resulting from IR
977                      optimisation) */
978      Ist_IMark,   /* OPTIONAL: instruction mark: describe addr/len of
979                      guest insn whose IR follows.  */
980      Ist_AbiHint, /* OPTIONAL: tell me something about this
981                      platform's ABI */
982      Ist_Put,     /* write guest state, fixed offset */
983      Ist_PutI,    /* write guest state, run-time offset */
984      Ist_Tmp,     /* assign value to temporary */
985      Ist_Store,   /* write to memory */
986      Ist_Dirty,   /* call complex ("dirty") helper function */
987      Ist_MFence,  /* memory fence */
988      Ist_Exit     /* conditional exit from BB */
989   }
990   IRStmtTag;
991
992typedef
993   struct _IRStmt {
994      IRStmtTag tag;
995      union {
996         struct {
997	 } NoOp;
998         struct {
999            Addr64 addr;
1000            Int    len;
1001         } IMark;
1002         struct {
1003            /* [base .. base+len-1] has become uninitialised */
1004            IRExpr* base;
1005            Int     len;
1006         } AbiHint;
1007         struct {
1008            Int     offset;
1009            IRExpr* data;
1010         } Put;
1011         struct {
1012            IRArray* descr;
1013            IRExpr*  ix;
1014            Int      bias;
1015            IRExpr*  data;
1016         } PutI;
1017         struct {
1018            IRTemp  tmp;
1019            IRExpr* data;
1020         } Tmp;
1021         struct {
1022            IREndness end;
1023            IRExpr*   addr;
1024            IRExpr*   data;
1025         } Store;
1026         struct {
1027            IRDirty* details;
1028         } Dirty;
1029         struct {
1030         } MFence;
1031         struct {
1032            IRExpr*    guard;
1033            IRJumpKind jk;
1034            IRConst*   dst;
1035         } Exit;
1036      } Ist;
1037   }
1038   IRStmt;
1039
1040extern IRStmt* IRStmt_NoOp    ( void );
1041extern IRStmt* IRStmt_IMark   ( Addr64 addr, Int len );
1042extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len );
1043extern IRStmt* IRStmt_Put     ( Int off, IRExpr* data );
1044extern IRStmt* IRStmt_PutI    ( IRArray* descr, IRExpr* ix, Int bias,
1045                                IRExpr* data );
1046extern IRStmt* IRStmt_Tmp     ( IRTemp tmp, IRExpr* data );
1047extern IRStmt* IRStmt_Store   ( IREndness end, IRExpr* addr, IRExpr* data );
1048extern IRStmt* IRStmt_Dirty   ( IRDirty* details );
1049extern IRStmt* IRStmt_MFence  ( void );
1050extern IRStmt* IRStmt_Exit    ( IRExpr* guard, IRJumpKind jk, IRConst* dst );
1051
1052extern IRStmt* dopyIRStmt ( IRStmt* );
1053
1054extern void ppIRStmt ( IRStmt* );
1055
1056
1057/* ------------------ Basic Blocks ------------------ */
1058
1059/* A bunch of statements, expressions, etc, are incomplete without an
1060   environment indicating the type of each IRTemp.  So this provides
1061   one.  IR temporaries are really just unsigned ints and so this
1062   provides an array, 0 .. n_types_used-1 of them.
1063*/
1064typedef
1065   struct {
1066      IRType* types;
1067      Int     types_size;
1068      Int     types_used;
1069   }
1070   IRTypeEnv;
1071
1072extern IRTemp     newIRTemp     ( IRTypeEnv*, IRType );
1073extern IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* );
1074
1075extern void ppIRTypeEnv ( IRTypeEnv* );
1076
1077
1078/* Basic blocks contain:
1079   - A table giving a type for each temp
1080   - An expandable array of statements
1081   - An expression of type 32 or 64 bits, depending on the
1082     guest's word size, indicating the next destination.
1083   - An indication of any special actions (JumpKind) needed
1084     for this final jump.
1085*/
1086typedef
1087   struct _IRBB {
1088      IRTypeEnv* tyenv;
1089      IRStmt**   stmts;
1090      Int        stmts_size;
1091      Int        stmts_used;
1092      IRExpr*    next;
1093      IRJumpKind jumpkind;
1094   }
1095   IRBB;
1096
1097extern IRBB* emptyIRBB ( void );
1098
1099extern IRBB* dopyIRBB ( IRBB* );
1100
1101extern void ppIRBB ( IRBB* );
1102
1103extern void addStmtToIRBB ( IRBB*, IRStmt* );
1104
1105
1106/*---------------------------------------------------------------*/
1107/*--- Helper functions for the IR                             ---*/
1108/*---------------------------------------------------------------*/
1109
1110/* For messing with IR type environments */
1111extern IRTypeEnv* emptyIRTypeEnv  ( void );
1112
1113/* What is the type of this expression? */
1114extern IRType typeOfIRConst ( IRConst* );
1115extern IRType typeOfIRTemp  ( IRTypeEnv*, IRTemp );
1116extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
1117
1118/* Sanity check a BB of IR */
1119extern void sanityCheckIRBB ( IRBB*  bb,
1120                              HChar* caller,
1121                              Bool   require_flatness,
1122                              IRType guest_word_size );
1123extern Bool isFlatIRStmt ( IRStmt* );
1124
1125/* Is this any value actually in the enumeration 'IRType' ? */
1126extern Bool isPlausibleIRType ( IRType ty );
1127
1128#endif /* ndef __LIBVEX_IR_H */
1129
1130
1131/*---------------------------------------------------------------*/
1132/*---                                             libvex_ir.h ---*/
1133/*---------------------------------------------------------------*/
1134