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