blob: 1a1f90217b3f6b44978201e98b5ed70c97040e74 [file] [log] [blame]
cerionbcf8c3e2005-02-04 16:17:07 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin host_ppc_defs.h ---*/
cerionbcf8c3e2005-02-04 16:17:07 +00004/*---------------------------------------------------------------*/
5
6/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
cerionbcf8c3e2005-02-04 16:17:07 +00009
sewardje6c53e02011-10-23 07:33:43 +000010 Copyright (C) 2004-2011 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
cerionbcf8c3e2005-02-04 16:17:07 +000012
sewardj752f9062010-05-03 21:38:49 +000013 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
cerionbcf8c3e2005-02-04 16:17:07 +000017
sewardj752f9062010-05-03 21:38:49 +000018 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
cerionbcf8c3e2005-02-04 16:17:07 +000029
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
cerionbcf8c3e2005-02-04 16:17:07 +000034*/
35
sewardjcef7d3e2009-07-02 12:21:59 +000036#ifndef __VEX_HOST_PPC_DEFS_H
37#define __VEX_HOST_PPC_DEFS_H
cerionbcf8c3e2005-02-04 16:17:07 +000038
cerion2c49e032005-02-09 17:29:49 +000039/* Num registers used for function calls */
cerionf0de28c2005-12-13 20:21:11 +000040#define PPC_N_REGPARMS 8
cerion2c49e032005-02-09 17:29:49 +000041
cerionbcf8c3e2005-02-04 16:17:07 +000042
43/* --------- Registers. --------- */
44
45/* The usual HReg abstraction. There are 32 real int regs,
cerion225a0342005-09-12 20:49:09 +000046 32 real float regs, and 32 real vector regs.
cerionbcf8c3e2005-02-04 16:17:07 +000047*/
48
cerion5b2325f2005-12-23 00:55:09 +000049extern void ppHRegPPC ( HReg );
cerionbcf8c3e2005-02-04 16:17:07 +000050
cerionf0de28c2005-12-13 20:21:11 +000051extern HReg hregPPC_GPR0 ( Bool mode64 ); // scratch reg / zero reg
52extern HReg hregPPC_GPR1 ( Bool mode64 ); // Stack Frame Pointer
53extern HReg hregPPC_GPR2 ( Bool mode64 ); // not used: TOC pointer
54extern HReg hregPPC_GPR3 ( Bool mode64 );
55extern HReg hregPPC_GPR4 ( Bool mode64 );
56extern HReg hregPPC_GPR5 ( Bool mode64 );
57extern HReg hregPPC_GPR6 ( Bool mode64 );
58extern HReg hregPPC_GPR7 ( Bool mode64 );
59extern HReg hregPPC_GPR8 ( Bool mode64 );
60extern HReg hregPPC_GPR9 ( Bool mode64 );
61extern HReg hregPPC_GPR10 ( Bool mode64 );
cerion5b2325f2005-12-23 00:55:09 +000062extern HReg hregPPC_GPR11 ( Bool mode64 );
63extern HReg hregPPC_GPR12 ( Bool mode64 );
64extern HReg hregPPC_GPR13 ( Bool mode64 );
cerionf0de28c2005-12-13 20:21:11 +000065extern HReg hregPPC_GPR14 ( Bool mode64 );
66extern HReg hregPPC_GPR15 ( Bool mode64 );
67extern HReg hregPPC_GPR16 ( Bool mode64 );
68extern HReg hregPPC_GPR17 ( Bool mode64 );
69extern HReg hregPPC_GPR18 ( Bool mode64 );
70extern HReg hregPPC_GPR19 ( Bool mode64 );
71extern HReg hregPPC_GPR20 ( Bool mode64 );
72extern HReg hregPPC_GPR21 ( Bool mode64 );
73extern HReg hregPPC_GPR22 ( Bool mode64 );
74extern HReg hregPPC_GPR23 ( Bool mode64 );
75extern HReg hregPPC_GPR24 ( Bool mode64 );
76extern HReg hregPPC_GPR25 ( Bool mode64 );
77extern HReg hregPPC_GPR26 ( Bool mode64 );
78extern HReg hregPPC_GPR27 ( Bool mode64 );
79extern HReg hregPPC_GPR28 ( Bool mode64 );
sewardjb8a8dba2005-12-15 21:33:50 +000080extern HReg hregPPC_GPR29 ( Bool mode64 ); // reserved for dispatcher
cerion5b2325f2005-12-23 00:55:09 +000081extern HReg hregPPC_GPR30 ( Bool mode64 ); // used as VMX spill temp
sewardjb8a8dba2005-12-15 21:33:50 +000082extern HReg hregPPC_GPR31 ( Bool mode64 ); // GuestStatePtr (callee-saved)
cerionbcf8c3e2005-02-04 16:17:07 +000083
cerion5b2325f2005-12-23 00:55:09 +000084extern HReg hregPPC_FPR0 ( void );
85extern HReg hregPPC_FPR1 ( void );
86extern HReg hregPPC_FPR2 ( void );
87extern HReg hregPPC_FPR3 ( void );
88extern HReg hregPPC_FPR4 ( void );
89extern HReg hregPPC_FPR5 ( void );
90extern HReg hregPPC_FPR6 ( void );
91extern HReg hregPPC_FPR7 ( void );
92extern HReg hregPPC_FPR8 ( void );
93extern HReg hregPPC_FPR9 ( void );
94extern HReg hregPPC_FPR10 ( void );
95extern HReg hregPPC_FPR11 ( void );
96extern HReg hregPPC_FPR12 ( void );
97extern HReg hregPPC_FPR13 ( void );
98extern HReg hregPPC_FPR14 ( void );
99extern HReg hregPPC_FPR15 ( void );
100extern HReg hregPPC_FPR16 ( void );
101extern HReg hregPPC_FPR17 ( void );
102extern HReg hregPPC_FPR18 ( void );
103extern HReg hregPPC_FPR19 ( void );
104extern HReg hregPPC_FPR20 ( void );
105extern HReg hregPPC_FPR21 ( void );
106extern HReg hregPPC_FPR22 ( void );
107extern HReg hregPPC_FPR23 ( void );
108extern HReg hregPPC_FPR24 ( void );
109extern HReg hregPPC_FPR25 ( void );
110extern HReg hregPPC_FPR26 ( void );
111extern HReg hregPPC_FPR27 ( void );
112extern HReg hregPPC_FPR28 ( void );
113extern HReg hregPPC_FPR29 ( void );
114extern HReg hregPPC_FPR30 ( void );
115extern HReg hregPPC_FPR31 ( void );
cerionbcf8c3e2005-02-04 16:17:07 +0000116
cerion5b2325f2005-12-23 00:55:09 +0000117extern HReg hregPPC_VR0 ( void );
118extern HReg hregPPC_VR1 ( void );
119extern HReg hregPPC_VR2 ( void );
120extern HReg hregPPC_VR3 ( void );
121extern HReg hregPPC_VR4 ( void );
122extern HReg hregPPC_VR5 ( void );
123extern HReg hregPPC_VR6 ( void );
124extern HReg hregPPC_VR7 ( void );
125extern HReg hregPPC_VR8 ( void );
126extern HReg hregPPC_VR9 ( void );
127extern HReg hregPPC_VR10 ( void );
128extern HReg hregPPC_VR11 ( void );
129extern HReg hregPPC_VR12 ( void );
130extern HReg hregPPC_VR13 ( void );
131extern HReg hregPPC_VR14 ( void );
132extern HReg hregPPC_VR15 ( void );
133extern HReg hregPPC_VR16 ( void );
134extern HReg hregPPC_VR17 ( void );
135extern HReg hregPPC_VR18 ( void );
136extern HReg hregPPC_VR19 ( void );
137extern HReg hregPPC_VR20 ( void );
138extern HReg hregPPC_VR21 ( void );
139extern HReg hregPPC_VR22 ( void );
140extern HReg hregPPC_VR23 ( void );
141extern HReg hregPPC_VR24 ( void );
142extern HReg hregPPC_VR25 ( void );
143extern HReg hregPPC_VR26 ( void );
144extern HReg hregPPC_VR27 ( void );
145extern HReg hregPPC_VR28 ( void );
146extern HReg hregPPC_VR29 ( void );
147extern HReg hregPPC_VR30 ( void );
148extern HReg hregPPC_VR31 ( void );
cerionbcf8c3e2005-02-04 16:17:07 +0000149
cerionf0de28c2005-12-13 20:21:11 +0000150#define StackFramePtr(_mode64) hregPPC_GPR1(_mode64)
151#define GuestStatePtr(_mode64) hregPPC_GPR31(_mode64)
cerionbcf8c3e2005-02-04 16:17:07 +0000152
cerion2c49e032005-02-09 17:29:49 +0000153
154
sewardjb51f0f42005-07-18 11:38:02 +0000155/* --------- Condition codes --------- */
cerion2c49e032005-02-09 17:29:49 +0000156
sewardjb51f0f42005-07-18 11:38:02 +0000157/* This gives names from bitfields in CR; hence it names BI numbers */
158/* Using IBM/hardware indexing convention */
cerion2c49e032005-02-09 17:29:49 +0000159typedef
sewardjb51f0f42005-07-18 11:38:02 +0000160 enum {
161 // CR7, which we use for integer compares
162 Pcf_7LT = 28, /* neg | lt */
163 Pcf_7GT = 29, /* pos | gt */
164 Pcf_7EQ = 30, /* zero | equal */
sewardj7e308072011-05-04 09:50:48 +0000165 Pcf_7SO = 31, /* summary overflow */
166 Pcf_NONE = 32 /* no condition; used with Pct_ALWAYS */
cerionab9132d2005-02-15 15:46:59 +0000167 }
cerion5b2325f2005-12-23 00:55:09 +0000168 PPCCondFlag;
cerion2c49e032005-02-09 17:29:49 +0000169
cerionab9132d2005-02-15 15:46:59 +0000170typedef
cerion7cf8e4e2005-02-16 16:08:17 +0000171 enum { /* Maps bc bitfield BO */
sewardj7e308072011-05-04 09:50:48 +0000172 Pct_FALSE = 0x4, /* associated PPCCondFlag must not be Pcf_NONE */
173 Pct_TRUE = 0xC, /* associated PPCCondFlag must not be Pcf_NONE */
174 Pct_ALWAYS = 0x14 /* associated PPCCondFlag must be Pcf_NONE */
cerionab9132d2005-02-15 15:46:59 +0000175 }
cerion5b2325f2005-12-23 00:55:09 +0000176 PPCCondTest;
cerionab9132d2005-02-15 15:46:59 +0000177
178typedef
179 struct {
cerion5b2325f2005-12-23 00:55:09 +0000180 PPCCondFlag flag;
181 PPCCondTest test;
cerion2c49e032005-02-09 17:29:49 +0000182 }
cerion5b2325f2005-12-23 00:55:09 +0000183 PPCCondCode;
cerion2c49e032005-02-09 17:29:49 +0000184
cerion5b2325f2005-12-23 00:55:09 +0000185extern HChar* showPPCCondCode ( PPCCondCode );
cerionbcf8c3e2005-02-04 16:17:07 +0000186
cerion7cf8e4e2005-02-16 16:08:17 +0000187/* constructor */
cerion5b2325f2005-12-23 00:55:09 +0000188extern PPCCondCode mk_PPCCondCode ( PPCCondTest, PPCCondFlag );
cerion7cf8e4e2005-02-16 16:08:17 +0000189
190/* false->true, true->false */
cerion5b2325f2005-12-23 00:55:09 +0000191extern PPCCondTest invertCondTest ( PPCCondTest );
cerionbcf8c3e2005-02-04 16:17:07 +0000192
cerionab9132d2005-02-15 15:46:59 +0000193
194
cerion33aa6da2005-02-16 10:25:26 +0000195
cerionbcf8c3e2005-02-04 16:17:07 +0000196/* --------- Memory address expressions (amodes). --------- */
197
198typedef
199 enum {
sewardj92923de2006-01-25 21:29:48 +0000200 Pam_IR=1, /* Immediate (signed 16-bit) + Reg */
201 Pam_RR=2 /* Reg1 + Reg2 */
cerionbcf8c3e2005-02-04 16:17:07 +0000202 }
cerion5b2325f2005-12-23 00:55:09 +0000203 PPCAModeTag;
cerionbcf8c3e2005-02-04 16:17:07 +0000204
205typedef
206 struct {
cerion5b2325f2005-12-23 00:55:09 +0000207 PPCAModeTag tag;
cerionbcf8c3e2005-02-04 16:17:07 +0000208 union {
209 struct {
210 HReg base;
sewardja5f957d2005-07-02 01:29:32 +0000211 Int index;
cerionbcf8c3e2005-02-04 16:17:07 +0000212 } IR;
213 struct {
214 HReg base;
215 HReg index;
216 } RR;
217 } Pam;
218 }
cerion5b2325f2005-12-23 00:55:09 +0000219 PPCAMode;
cerionbcf8c3e2005-02-04 16:17:07 +0000220
cerion5b2325f2005-12-23 00:55:09 +0000221extern PPCAMode* PPCAMode_IR ( Int, HReg );
222extern PPCAMode* PPCAMode_RR ( HReg, HReg );
cerionbcf8c3e2005-02-04 16:17:07 +0000223
cerion5b2325f2005-12-23 00:55:09 +0000224extern PPCAMode* dopyPPCAMode ( PPCAMode* );
cerionbcf8c3e2005-02-04 16:17:07 +0000225
cerion5b2325f2005-12-23 00:55:09 +0000226extern void ppPPCAMode ( PPCAMode* );
cerionbcf8c3e2005-02-04 16:17:07 +0000227
228
sewardjb51f0f42005-07-18 11:38:02 +0000229/* --------- Operand, which can be a reg or a u16/s16. --------- */
230/* ("RH" == "Register or Halfword immediate") */
cerionbcf8c3e2005-02-04 16:17:07 +0000231typedef
232 enum {
sewardj92923de2006-01-25 21:29:48 +0000233 Prh_Imm=3,
234 Prh_Reg=4
cerionbcf8c3e2005-02-04 16:17:07 +0000235 }
cerion5b2325f2005-12-23 00:55:09 +0000236 PPCRHTag;
sewardjb51f0f42005-07-18 11:38:02 +0000237
238typedef
239 struct {
cerion5b2325f2005-12-23 00:55:09 +0000240 PPCRHTag tag;
sewardjb51f0f42005-07-18 11:38:02 +0000241 union {
242 struct {
243 Bool syned;
244 UShort imm16;
245 } Imm;
246 struct {
247 HReg reg;
248 } Reg;
249 }
250 Prh;
251 }
cerion5b2325f2005-12-23 00:55:09 +0000252 PPCRH;
sewardjb51f0f42005-07-18 11:38:02 +0000253
cerion5b2325f2005-12-23 00:55:09 +0000254extern PPCRH* PPCRH_Imm ( Bool, UShort );
255extern PPCRH* PPCRH_Reg ( HReg );
sewardjb51f0f42005-07-18 11:38:02 +0000256
cerion5b2325f2005-12-23 00:55:09 +0000257extern void ppPPCRH ( PPCRH* );
sewardjb51f0f42005-07-18 11:38:02 +0000258
259
cerionf0de28c2005-12-13 20:21:11 +0000260/* --------- Operand, which can be a reg or a u32/64. --------- */
sewardjb51f0f42005-07-18 11:38:02 +0000261
262typedef
263 enum {
sewardj92923de2006-01-25 21:29:48 +0000264 Pri_Imm=5,
265 Pri_Reg=6
sewardjb51f0f42005-07-18 11:38:02 +0000266 }
cerion5b2325f2005-12-23 00:55:09 +0000267 PPCRITag;
cerionbcf8c3e2005-02-04 16:17:07 +0000268
269typedef
270 struct {
cerion5b2325f2005-12-23 00:55:09 +0000271 PPCRITag tag;
cerionbcf8c3e2005-02-04 16:17:07 +0000272 union {
cerionf0de28c2005-12-13 20:21:11 +0000273 ULong Imm;
274 HReg Reg;
cerionbcf8c3e2005-02-04 16:17:07 +0000275 }
276 Pri;
277 }
cerion5b2325f2005-12-23 00:55:09 +0000278 PPCRI;
cerionbcf8c3e2005-02-04 16:17:07 +0000279
cerion5b2325f2005-12-23 00:55:09 +0000280extern PPCRI* PPCRI_Imm ( ULong );
sewardj478646f2008-05-01 20:13:04 +0000281extern PPCRI* PPCRI_Reg( HReg );
cerionbcf8c3e2005-02-04 16:17:07 +0000282
cerion5b2325f2005-12-23 00:55:09 +0000283extern void ppPPCRI ( PPCRI* );
cerionbcf8c3e2005-02-04 16:17:07 +0000284
285
cerion27b3d7e2005-09-14 20:35:47 +0000286/* --------- Operand, which can be a vector reg or a s6. --------- */
287/* ("VI" == "Vector Register or Immediate") */
288typedef
289 enum {
sewardj92923de2006-01-25 21:29:48 +0000290 Pvi_Imm=7,
291 Pvi_Reg=8
cerion27b3d7e2005-09-14 20:35:47 +0000292 }
cerion5b2325f2005-12-23 00:55:09 +0000293 PPCVI5sTag;
cerion27b3d7e2005-09-14 20:35:47 +0000294
295typedef
296 struct {
cerion5b2325f2005-12-23 00:55:09 +0000297 PPCVI5sTag tag;
cerion27b3d7e2005-09-14 20:35:47 +0000298 union {
299 Char Imm5s;
300 HReg Reg;
301 }
302 Pvi;
303 }
cerion5b2325f2005-12-23 00:55:09 +0000304 PPCVI5s;
cerion27b3d7e2005-09-14 20:35:47 +0000305
cerion5b2325f2005-12-23 00:55:09 +0000306extern PPCVI5s* PPCVI5s_Imm ( Char );
307extern PPCVI5s* PPCVI5s_Reg ( HReg );
cerion27b3d7e2005-09-14 20:35:47 +0000308
cerion5b2325f2005-12-23 00:55:09 +0000309extern void ppPPCVI5s ( PPCVI5s* );
cerion27b3d7e2005-09-14 20:35:47 +0000310
311
cerioncd304492005-02-08 19:40:24 +0000312/* --------- Instructions. --------- */
cerionbcf8c3e2005-02-04 16:17:07 +0000313
cerion2c49e032005-02-09 17:29:49 +0000314/* --------- */
315typedef
316 enum {
317 Pun_NEG,
cerione13bb312005-02-10 19:51:03 +0000318 Pun_NOT,
cerion07b07a92005-12-22 14:32:35 +0000319 Pun_CLZ32,
sewardj7fd5bb02006-01-26 02:24:17 +0000320 Pun_CLZ64,
321 Pun_EXTSW
cerion2c49e032005-02-09 17:29:49 +0000322 }
cerion5b2325f2005-12-23 00:55:09 +0000323 PPCUnaryOp;
cerion2c49e032005-02-09 17:29:49 +0000324
cerion5b2325f2005-12-23 00:55:09 +0000325extern HChar* showPPCUnaryOp ( PPCUnaryOp );
cerioncd304492005-02-08 19:40:24 +0000326
327
328/* --------- */
329typedef
330 enum {
331 Palu_INVALID,
sewardjb51f0f42005-07-18 11:38:02 +0000332 Palu_ADD, Palu_SUB,
333 Palu_AND, Palu_OR, Palu_XOR,
cerioncd304492005-02-08 19:40:24 +0000334 }
cerion5b2325f2005-12-23 00:55:09 +0000335 PPCAluOp;
cerioncd304492005-02-08 19:40:24 +0000336
sewardjb51f0f42005-07-18 11:38:02 +0000337extern
cerion5b2325f2005-12-23 00:55:09 +0000338HChar* showPPCAluOp ( PPCAluOp,
339 Bool /* is the 2nd operand an immediate? */);
cerionbb01b7c2005-12-16 13:40:18 +0000340
341
342/* --------- */
343typedef
344 enum {
345 Pshft_INVALID,
346 Pshft_SHL, Pshft_SHR, Pshft_SAR,
347 }
cerion5b2325f2005-12-23 00:55:09 +0000348 PPCShftOp;
cerionbb01b7c2005-12-16 13:40:18 +0000349
350extern
cerion5b2325f2005-12-23 00:55:09 +0000351HChar* showPPCShftOp ( PPCShftOp,
352 Bool /* is the 2nd operand an immediate? */,
353 Bool /* is this a 32bit or 64bit op? */ );
cerionab9132d2005-02-15 15:46:59 +0000354
355
cerion094d1392005-06-20 13:45:57 +0000356/* --------- */
357typedef
358 enum {
359 Pfp_INVALID,
sewardj40c80262006-02-08 19:30:46 +0000360
361 /* Ternary */
sewardjc6bbd472012-04-02 10:20:48 +0000362 Pfp_MADDD, Pfp_MSUBD,
363 Pfp_MADDS, Pfp_MSUBS,
364 Pfp_DFPADD, Pfp_DFPADDQ,
365 Pfp_DFPSUB, Pfp_DFPSUBQ,
366 Pfp_DFPMUL, Pfp_DFPMULQ,
367 Pfp_DFPDIV, Pfp_DFPDIVQ,
368 Pfp_DQUAQ, Pfp_DRRNDQ,
sewardj40c80262006-02-08 19:30:46 +0000369
cerion094d1392005-06-20 13:45:57 +0000370 /* Binary */
sewardj26217b02012-04-12 17:19:48 +0000371 Pfp_ADDD, Pfp_SUBD, Pfp_MULD, Pfp_DIVD,
372 Pfp_ADDS, Pfp_SUBS, Pfp_MULS, Pfp_DIVS,
373 Pfp_DRSP, Pfp_DCTFIX, Pfp_DCTFIXQ, Pfp_DCFFIX,
cerion094d1392005-06-20 13:45:57 +0000374
375 /* Unary */
sewardj0f1ef862008-08-08 08:37:06 +0000376 Pfp_SQRT, Pfp_ABS, Pfp_NEG, Pfp_MOV, Pfp_RES, Pfp_RSQRTE,
sewardj26217b02012-04-12 17:19:48 +0000377 Pfp_FRIN, Pfp_FRIM, Pfp_FRIP, Pfp_FRIZ,
378 Pfp_DSCLI, Pfp_DSCRI, Pfp_DSCLIQ, Pfp_DSCRIQ, Pfp_DCTDP, Pfp_DCTQPQ,
379 Pfp_DRDPQ, Pfp_DCFFIXQ
cerion094d1392005-06-20 13:45:57 +0000380 }
cerion5b2325f2005-12-23 00:55:09 +0000381 PPCFpOp;
cerion094d1392005-06-20 13:45:57 +0000382
cerion5b2325f2005-12-23 00:55:09 +0000383extern HChar* showPPCFpOp ( PPCFpOp );
cerionbcf8c3e2005-02-04 16:17:07 +0000384
385
386/* --------- */
387typedef
388 enum {
cerionc3d8bdc2005-06-28 18:06:23 +0000389 Pav_INVALID,
390
391 /* Integer Unary */
392 Pav_MOV, /* Mov */
393 Pav_NOT, /* Bitwise */
394 Pav_UNPCKH8S, Pav_UNPCKH16S, /* Unpack */
395 Pav_UNPCKL8S, Pav_UNPCKL16S,
396 Pav_UNPCKHPIX, Pav_UNPCKLPIX,
397
398 /* Integer Binary */
cerion8ea0d3e2005-11-14 00:44:47 +0000399 Pav_AND, Pav_OR, Pav_XOR, /* Bitwise */
cerionf34ccc42005-09-16 08:55:50 +0000400 Pav_ADDU, Pav_QADDU, Pav_QADDS,
cerionf34ccc42005-09-16 08:55:50 +0000401 Pav_SUBU, Pav_QSUBU, Pav_QSUBS,
cerion6b6f59e2005-06-28 20:59:18 +0000402 Pav_OMULU, Pav_OMULS, Pav_EMULU, Pav_EMULS,
cerion6b6f59e2005-06-28 20:59:18 +0000403 Pav_AVGU, Pav_AVGS,
404 Pav_MAXU, Pav_MAXS,
405 Pav_MINU, Pav_MINS,
cerionc3d8bdc2005-06-28 18:06:23 +0000406
407 /* Compare (always affects CR field 6) */
cerion6b6f59e2005-06-28 20:59:18 +0000408 Pav_CMPEQU, Pav_CMPGTU, Pav_CMPGTS,
cerionc3d8bdc2005-06-28 18:06:23 +0000409
410 /* Shift */
cerion6b6f59e2005-06-28 20:59:18 +0000411 Pav_SHL, Pav_SHR, Pav_SAR, Pav_ROTL,
cerionc3d8bdc2005-06-28 18:06:23 +0000412
413 /* Pack */
cerionf34ccc42005-09-16 08:55:50 +0000414 Pav_PACKUU, Pav_QPACKUU, Pav_QPACKSU, Pav_QPACKSS,
cerion6b6f59e2005-06-28 20:59:18 +0000415 Pav_PACKPXL,
cerionc3d8bdc2005-06-28 18:06:23 +0000416
417 /* Merge */
cerion6b6f59e2005-06-28 20:59:18 +0000418 Pav_MRGHI, Pav_MRGLO,
cerionc3d8bdc2005-06-28 18:06:23 +0000419 }
cerion5b2325f2005-12-23 00:55:09 +0000420 PPCAvOp;
cerionc3d8bdc2005-06-28 18:06:23 +0000421
cerion5b2325f2005-12-23 00:55:09 +0000422extern HChar* showPPCAvOp ( PPCAvOp );
cerionc3d8bdc2005-06-28 18:06:23 +0000423
424
425/* --------- */
426typedef
427 enum {
cerion8ea0d3e2005-11-14 00:44:47 +0000428 Pavfp_INVALID,
429
430 /* Floating point binary */
431 Pavfp_ADDF, Pavfp_SUBF, Pavfp_MULF,
432 Pavfp_MAXF, Pavfp_MINF,
433 Pavfp_CMPEQF, Pavfp_CMPGTF, Pavfp_CMPGEF,
434
435 /* Floating point unary */
436 Pavfp_RCPF, Pavfp_RSQRTF,
ceriond963eb42005-11-16 18:02:58 +0000437 Pavfp_CVTU2F, Pavfp_CVTS2F, Pavfp_QCVTF2U, Pavfp_QCVTF2S,
438 Pavfp_ROUNDM, Pavfp_ROUNDP, Pavfp_ROUNDN, Pavfp_ROUNDZ,
cerion8ea0d3e2005-11-14 00:44:47 +0000439 }
cerion5b2325f2005-12-23 00:55:09 +0000440 PPCAvFpOp;
cerion8ea0d3e2005-11-14 00:44:47 +0000441
cerion5b2325f2005-12-23 00:55:09 +0000442extern HChar* showPPCAvFpOp ( PPCAvFpOp );
cerion8ea0d3e2005-11-14 00:44:47 +0000443
444
445/* --------- */
446typedef
447 enum {
cerionf0de28c2005-12-13 20:21:11 +0000448 Pin_LI, /* load word (32/64-bit) immediate (fake insn) */
cerionbb01b7c2005-12-16 13:40:18 +0000449 Pin_Alu, /* word add/sub/and/or/xor */
450 Pin_Shft, /* word shl/shr/sar */
cerion5b2325f2005-12-23 00:55:09 +0000451 Pin_AddSubC, /* add/sub with read/write carry */
cerionf0de28c2005-12-13 20:21:11 +0000452 Pin_Cmp, /* word compare */
453 Pin_Unary, /* not, neg, clz */
cerioned623db2005-06-20 12:42:04 +0000454 Pin_MulL, /* widening multiply */
455 Pin_Div, /* div */
456 Pin_Call, /* call to address in register */
sewardj3dee8492012-04-20 00:13:28 +0000457 Pin_XDirect, /* direct transfer to GA */
458 Pin_XIndir, /* indirect transfer to GA */
459 Pin_XAssisted, /* assisted transfer to GA */
cerionf0de28c2005-12-13 20:21:11 +0000460 Pin_CMov, /* conditional move */
sewardj7fd5bb02006-01-26 02:24:17 +0000461 Pin_Load, /* zero-extending load a 8|16|32|64 bit value from mem */
sewardje9d8a262009-07-01 08:06:34 +0000462 Pin_LoadL, /* load-linked (lwarx/ldarx) 32|64 bit value from mem */
cerion5b2325f2005-12-23 00:55:09 +0000463 Pin_Store, /* store a 8|16|32|64 bit value to mem */
sewardje9d8a262009-07-01 08:06:34 +0000464 Pin_StoreC, /* store-conditional (stwcx./stdcx.) 32|64 bit val */
cerion5b2325f2005-12-23 00:55:09 +0000465 Pin_Set, /* convert condition code to value 0 or 1 */
sewardjb51f0f42005-07-18 11:38:02 +0000466 Pin_MfCR, /* move from condition register to GPR */
467 Pin_MFence, /* mem fence */
cerionc3d8bdc2005-06-28 18:06:23 +0000468
cerion094d1392005-06-20 13:45:57 +0000469 Pin_FpUnary, /* FP unary op */
470 Pin_FpBinary, /* FP binary op */
sewardj40c80262006-02-08 19:30:46 +0000471 Pin_FpMulAcc, /* FP multipy-accumulate style op */
cerion094d1392005-06-20 13:45:57 +0000472 Pin_FpLdSt, /* FP load/store */
sewardj92923de2006-01-25 21:29:48 +0000473 Pin_FpSTFIW, /* stfiwx */
474 Pin_FpRSP, /* FP round IEEE754 double to IEEE754 single */
sewardj7d810d72011-05-08 22:05:10 +0000475 Pin_FpCftI, /* fcfid[u,s,us]/fctid[u]/fctiw[u] */
cerion094d1392005-06-20 13:45:57 +0000476 Pin_FpCMov, /* FP floating point conditional move */
477 Pin_FpLdFPSCR, /* mtfsf */
478 Pin_FpCmp, /* FP compare, generating value into int reg */
sewardj92923de2006-01-25 21:29:48 +0000479
cerionc3d8bdc2005-06-28 18:06:23 +0000480 Pin_RdWrLR, /* Read/Write Link Register */
481
cerionc3d8bdc2005-06-28 18:06:23 +0000482 Pin_AvLdSt, /* AV load/store (kludging for AMode_IR) */
483 Pin_AvUnary, /* AV unary general reg=>reg */
cerion6b6f59e2005-06-28 20:59:18 +0000484
cerionc3d8bdc2005-06-28 18:06:23 +0000485 Pin_AvBinary, /* AV binary general reg,reg=>reg */
cerion6b6f59e2005-06-28 20:59:18 +0000486 Pin_AvBin8x16, /* AV binary, 8x4 */
487 Pin_AvBin16x8, /* AV binary, 16x4 */
488 Pin_AvBin32x4, /* AV binary, 32x4 */
489
490 Pin_AvBin32Fx4, /* AV FP binary, 32Fx4 */
cerion8ea0d3e2005-11-14 00:44:47 +0000491 Pin_AvUn32Fx4, /* AV FP unary, 32Fx4 */
cerionc3d8bdc2005-06-28 18:06:23 +0000492
493 Pin_AvPerm, /* AV permute (shuffle) */
494 Pin_AvSel, /* AV select */
495 Pin_AvShlDbl, /* AV shift-left double by imm */
496 Pin_AvSplat, /* One elem repeated throughout dst */
cerion6b6f59e2005-06-28 20:59:18 +0000497 Pin_AvLdVSCR, /* mtvscr */
sewardjc6bbd472012-04-02 10:20:48 +0000498 Pin_AvCMov, /* AV conditional move */
499 Pin_Dfp64Unary, /* DFP64 unary op */
sewardj26217b02012-04-12 17:19:48 +0000500 Pin_Dfp128Unary, /* DFP128 unary op */
501 Pin_DfpShift, /* Decimal floating point shift by immediate value */
sewardjc6bbd472012-04-02 10:20:48 +0000502 Pin_Dfp64Binary, /* DFP64 binary op */
sewardj26217b02012-04-12 17:19:48 +0000503 Pin_Dfp128Binary, /* DFP128 binary op */
504 Pin_DfpShift128, /* 128-bit Decimal floating point shift by
505 * immediate value */
506 Pin_DfpD128toD64, /* DFP 128 to DFP 64 op */
507 Pin_DfpI64StoD128, /* DFP signed integer to DFP 128 */
sewardj3dee8492012-04-20 00:13:28 +0000508 Pin_EvCheck, /* Event check */
509 Pin_ProfInc /* 64-bit profile counter increment */
cerionbcf8c3e2005-02-04 16:17:07 +0000510 }
cerion5b2325f2005-12-23 00:55:09 +0000511 PPCInstrTag;
cerionbcf8c3e2005-02-04 16:17:07 +0000512
cerioncd304492005-02-08 19:40:24 +0000513/* Destinations are on the LEFT (first operand) */
cerionbcf8c3e2005-02-04 16:17:07 +0000514
515typedef
516 struct {
cerion5b2325f2005-12-23 00:55:09 +0000517 PPCInstrTag tag;
cerioncd304492005-02-08 19:40:24 +0000518 union {
cerion5b2325f2005-12-23 00:55:09 +0000519 /* Get a 32/64-bit literal into a register.
520 May turn into a number of real insns. */
sewardjb51f0f42005-07-18 11:38:02 +0000521 struct {
522 HReg dst;
cerionf0de28c2005-12-13 20:21:11 +0000523 ULong imm64;
524 } LI;
cerionbb01b7c2005-12-16 13:40:18 +0000525 /* Integer add/sub/and/or/xor. Limitations:
sewardjb51f0f42005-07-18 11:38:02 +0000526 - For add, the immediate, if it exists, is a signed 16.
527 - For sub, the immediate, if it exists, is a signed 16
528 which may not be -32768, since no such instruction
529 exists, and so we have to emit addi with +32768, but
530 that is not possible.
531 - For and/or/xor, the immediate, if it exists,
532 is an unsigned 16.
sewardjb51f0f42005-07-18 11:38:02 +0000533 */
cerioncd304492005-02-08 19:40:24 +0000534 struct {
cerion5b2325f2005-12-23 00:55:09 +0000535 PPCAluOp op;
536 HReg dst;
537 HReg srcL;
538 PPCRH* srcR;
cerionf0de28c2005-12-13 20:21:11 +0000539 } Alu;
cerionbb01b7c2005-12-16 13:40:18 +0000540 /* Integer shl/shr/sar.
541 Limitations: the immediate, if it exists,
542 is a signed 5-bit value between 1 and 31 inclusive.
543 */
544 struct {
cerion5b2325f2005-12-23 00:55:09 +0000545 PPCShftOp op;
546 Bool sz32; /* mode64 has both 32 and 64bit shft */
547 HReg dst;
548 HReg srcL;
549 PPCRH* srcR;
cerionbb01b7c2005-12-16 13:40:18 +0000550 } Shft;
cerion4a49b032005-11-08 16:23:07 +0000551 /* */
552 struct {
553 Bool isAdd; /* else sub */
554 Bool setC; /* else read carry */
555 HReg dst;
556 HReg srcL;
557 HReg srcR;
cerion5b2325f2005-12-23 00:55:09 +0000558 } AddSubC;
sewardjb51f0f42005-07-18 11:38:02 +0000559 /* If signed, the immediate, if it exists, is a signed 16,
560 else it is an unsigned 16. */
cerioncd304492005-02-08 19:40:24 +0000561 struct {
cerion5b2325f2005-12-23 00:55:09 +0000562 Bool syned;
563 Bool sz32; /* mode64 has both 32 and 64bit cmp */
564 UInt crfD;
565 HReg srcL;
566 PPCRH* srcR;
cerionf0de28c2005-12-13 20:21:11 +0000567 } Cmp;
sewardj7fd5bb02006-01-26 02:24:17 +0000568 /* Not, Neg, Clz32/64, Extsw */
cerion2c49e032005-02-09 17:29:49 +0000569 struct {
cerion5b2325f2005-12-23 00:55:09 +0000570 PPCUnaryOp op;
571 HReg dst;
572 HReg src;
573 } Unary;
cerion92f5dc72005-02-10 16:11:35 +0000574 struct {
sewardjb51f0f42005-07-18 11:38:02 +0000575 Bool syned; /* meaningless if hi32==False */
cerionf0de28c2005-12-13 20:21:11 +0000576 Bool hi; /* False=>low, True=>high */
cerionbb01b7c2005-12-16 13:40:18 +0000577 Bool sz32; /* mode64 has both 32 & 64bit mull */
sewardjb51f0f42005-07-18 11:38:02 +0000578 HReg dst;
579 HReg srcL;
580 HReg srcR;
cerion92f5dc72005-02-10 16:11:35 +0000581 } MulL;
cerion9e263e32005-03-03 17:21:51 +0000582 /* ppc32 div/divu instruction. */
cerionc0e707e2005-02-10 22:35:34 +0000583 struct {
sewardj4aa412a2011-07-24 14:13:21 +0000584 Bool extended;
cerion33aa6da2005-02-16 10:25:26 +0000585 Bool syned;
cerionbb01b7c2005-12-16 13:40:18 +0000586 Bool sz32; /* mode64 has both 32 & 64bit div */
cerion33aa6da2005-02-16 10:25:26 +0000587 HReg dst;
ceriona2f75882005-03-15 16:33:38 +0000588 HReg srcL;
589 HReg srcR;
cerionc0e707e2005-02-10 22:35:34 +0000590 } Div;
cerion2c49e032005-02-09 17:29:49 +0000591 /* Pseudo-insn. Call target (an absolute address), on given
sewardj6a64a9f2005-08-21 00:48:37 +0000592 condition (which could be Pct_ALWAYS). argiregs indicates
593 which of r3 .. r10 carries argument values for this call,
594 using a bit mask (1<<N is set if rN holds an arg, for N in
595 3 .. 10 inclusive). */
cerion2c49e032005-02-09 17:29:49 +0000596 struct {
cerion5b2325f2005-12-23 00:55:09 +0000597 PPCCondCode cond;
598 Addr64 target;
599 UInt argiregs;
cerion2c49e032005-02-09 17:29:49 +0000600 } Call;
sewardj3dee8492012-04-20 00:13:28 +0000601 /* Update the guest CIA value, then exit requesting to chain
602 to it. May be conditional. Use of Addr64 in order to cope
603 with 64-bit hosts. */
cerion2c49e032005-02-09 17:29:49 +0000604 struct {
sewardj3dee8492012-04-20 00:13:28 +0000605 Addr64 dstGA; /* next guest address */
606 PPCAMode* amCIA; /* amode in guest state for CIA */
607 PPCCondCode cond; /* can be ALWAYS */
608 Bool toFastEP; /* chain to the slow or fast point? */
609 } XDirect;
610 /* Boring transfer to a guest address not known at JIT time.
611 Not chainable. May be conditional. */
612 struct {
613 HReg dstGA;
614 PPCAMode* amCIA;
615 PPCCondCode cond; /* can be ALWAYS */
616 } XIndir;
617 /* Assisted transfer to a guest address, most general case.
618 Not chainable. May be conditional. */
619 struct {
620 HReg dstGA;
621 PPCAMode* amCIA;
622 PPCCondCode cond; /* can be ALWAYS */
cerion5b2325f2005-12-23 00:55:09 +0000623 IRJumpKind jk;
sewardj3dee8492012-04-20 00:13:28 +0000624 } XAssisted;
cerionb536af92005-02-10 15:03:19 +0000625 /* Mov src to dst on the given condition, which may not
cerion9abfcbc2005-02-25 11:16:58 +0000626 be the bogus Pct_ALWAYS. */
cerionb536af92005-02-10 15:03:19 +0000627 struct {
cerion5b2325f2005-12-23 00:55:09 +0000628 PPCCondCode cond;
cerioncd304492005-02-08 19:40:24 +0000629 HReg dst;
cerion5b2325f2005-12-23 00:55:09 +0000630 PPCRI* src;
631 } CMov;
sewardj7fd5bb02006-01-26 02:24:17 +0000632 /* Zero extending loads. Dst size is host word size */
cerion5b2325f2005-12-23 00:55:09 +0000633 struct {
634 UChar sz; /* 1|2|4|8 */
cerion5b2325f2005-12-23 00:55:09 +0000635 HReg dst;
636 PPCAMode* src;
cerion7cf8e4e2005-02-16 16:08:17 +0000637 } Load;
sewardje9d8a262009-07-01 08:06:34 +0000638 /* Load-and-reserve (lwarx, ldarx) */
639 struct {
640 UChar sz; /* 4|8 */
641 HReg dst;
642 HReg src;
643 } LoadL;
cerion5b2325f2005-12-23 00:55:09 +0000644 /* 64/32/16/8 bit stores */
cerioncd304492005-02-08 19:40:24 +0000645 struct {
cerion5b2325f2005-12-23 00:55:09 +0000646 UChar sz; /* 1|2|4|8 */
647 PPCAMode* dst;
648 HReg src;
cerioncd304492005-02-08 19:40:24 +0000649 } Store;
sewardje9d8a262009-07-01 08:06:34 +0000650 /* Store-conditional (stwcx., stdcx.) */
651 struct {
652 UChar sz; /* 4|8 */
653 HReg dst;
654 HReg src;
655 } StoreC;
cerion5b2325f2005-12-23 00:55:09 +0000656 /* Convert a ppc condition code to value 0 or 1. */
cerionb536af92005-02-10 15:03:19 +0000657 struct {
cerion5b2325f2005-12-23 00:55:09 +0000658 PPCCondCode cond;
659 HReg dst;
660 } Set;
sewardjb51f0f42005-07-18 11:38:02 +0000661 /* Move the entire CR to a GPR */
662 struct {
663 HReg dst;
664 } MfCR;
cerion98411db2005-02-16 14:14:49 +0000665 /* Mem fence. In short, an insn which flushes all preceding
666 loads and stores as much as possible before continuing.
cerion5b2325f2005-12-23 00:55:09 +0000667 On PPC we emit a "sync". */
cerion92f5dc72005-02-10 16:11:35 +0000668 struct {
cerion92f5dc72005-02-10 16:11:35 +0000669 } MFence;
cerioncd304492005-02-08 19:40:24 +0000670
cerion5b2325f2005-12-23 00:55:09 +0000671 /* PPC Floating point */
cerion094d1392005-06-20 13:45:57 +0000672 struct {
cerion5b2325f2005-12-23 00:55:09 +0000673 PPCFpOp op;
674 HReg dst;
675 HReg src;
cerion094d1392005-06-20 13:45:57 +0000676 } FpUnary;
677 struct {
cerion5b2325f2005-12-23 00:55:09 +0000678 PPCFpOp op;
679 HReg dst;
680 HReg srcL;
681 HReg srcR;
cerion094d1392005-06-20 13:45:57 +0000682 } FpBinary;
683 struct {
sewardj40c80262006-02-08 19:30:46 +0000684 PPCFpOp op;
685 HReg dst;
686 HReg srcML;
687 HReg srcMR;
688 HReg srcAcc;
689 } FpMulAcc;
690 struct {
cerion5b2325f2005-12-23 00:55:09 +0000691 Bool isLoad;
692 UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */
693 HReg reg;
694 PPCAMode* addr;
cerion094d1392005-06-20 13:45:57 +0000695 } FpLdSt;
sewardj92923de2006-01-25 21:29:48 +0000696 struct {
697 HReg addr; /* int reg */
698 HReg data; /* float reg */
699 } FpSTFIW;
700 /* Round 64-bit FP value to 32-bit FP value in an FP reg. */
cerion094d1392005-06-20 13:45:57 +0000701 struct {
702 HReg src;
703 HReg dst;
sewardj92923de2006-01-25 21:29:48 +0000704 } FpRSP;
sewardj7d810d72011-05-08 22:05:10 +0000705 /* fcfid[u,s,us]/fctid[u]/fctiw[u]. Only some combinations
706 of the various fields are allowed. This is asserted for
707 and documented in the code for the constructor,
708 PPCInstr_FpCftI, in host_ppc_defs.c. */
cerion094d1392005-06-20 13:45:57 +0000709 struct {
sewardj7d810d72011-05-08 22:05:10 +0000710 Bool fromI; /* True== I->F, False== F->I */
711 Bool int32; /* True== I is 32, False== I is 64 */
sewardj66d5ef22011-04-15 11:55:00 +0000712 Bool syned;
sewardj7d810d72011-05-08 22:05:10 +0000713 Bool flt64; /* True== F is 64, False== F is 32 */
cerion094d1392005-06-20 13:45:57 +0000714 HReg src;
715 HReg dst;
sewardj92923de2006-01-25 21:29:48 +0000716 } FpCftI;
717 /* FP mov src to dst on the given condition. */
cerion094d1392005-06-20 13:45:57 +0000718 struct {
cerion5b2325f2005-12-23 00:55:09 +0000719 PPCCondCode cond;
720 HReg dst;
721 HReg src;
cerion094d1392005-06-20 13:45:57 +0000722 } FpCMov;
723 /* Load FP Status & Control Register */
724 struct {
725 HReg src;
sewardjc6bbd472012-04-02 10:20:48 +0000726 UInt dfp_rm;
cerion094d1392005-06-20 13:45:57 +0000727 } FpLdFPSCR;
sewardjb51f0f42005-07-18 11:38:02 +0000728 /* Do a compare, generating result into an int register. */
cerion094d1392005-06-20 13:45:57 +0000729 struct {
730 UChar crfD;
731 HReg dst;
732 HReg srcL;
733 HReg srcR;
734 } FpCmp;
cerioncd304492005-02-08 19:40:24 +0000735
cerion7f000af2005-02-22 20:36:49 +0000736 /* Read/Write Link Register */
737 struct {
738 Bool wrLR;
739 HReg gpr;
740 } RdWrLR;
cerionc3d8bdc2005-06-28 18:06:23 +0000741
742 /* Simplistic AltiVec */
743 struct {
cerion5b2325f2005-12-23 00:55:09 +0000744 Bool isLoad;
745 UChar sz; /* 8|16|32|128 */
746 HReg reg;
747 PPCAMode* addr;
cerionc3d8bdc2005-06-28 18:06:23 +0000748 } AvLdSt;
749 struct {
cerion5b2325f2005-12-23 00:55:09 +0000750 PPCAvOp op;
751 HReg dst;
752 HReg src;
cerionc3d8bdc2005-06-28 18:06:23 +0000753 } AvUnary;
754 struct {
cerion5b2325f2005-12-23 00:55:09 +0000755 PPCAvOp op;
756 HReg dst;
757 HReg srcL;
758 HReg srcR;
cerionc3d8bdc2005-06-28 18:06:23 +0000759 } AvBinary;
cerion6b6f59e2005-06-28 20:59:18 +0000760 struct {
cerion5b2325f2005-12-23 00:55:09 +0000761 PPCAvOp op;
762 HReg dst;
763 HReg srcL;
764 HReg srcR;
cerion6b6f59e2005-06-28 20:59:18 +0000765 } AvBin8x16;
766 struct {
cerion5b2325f2005-12-23 00:55:09 +0000767 PPCAvOp op;
768 HReg dst;
769 HReg srcL;
770 HReg srcR;
cerion6b6f59e2005-06-28 20:59:18 +0000771 } AvBin16x8;
772 struct {
cerion5b2325f2005-12-23 00:55:09 +0000773 PPCAvOp op;
774 HReg dst;
775 HReg srcL;
776 HReg srcR;
cerion6b6f59e2005-06-28 20:59:18 +0000777 } AvBin32x4;
778 struct {
cerion5b2325f2005-12-23 00:55:09 +0000779 PPCAvFpOp op;
cerion6b6f59e2005-06-28 20:59:18 +0000780 HReg dst;
781 HReg srcL;
782 HReg srcR;
783 } AvBin32Fx4;
cerion8ea0d3e2005-11-14 00:44:47 +0000784 struct {
cerion5b2325f2005-12-23 00:55:09 +0000785 PPCAvFpOp op;
cerion8ea0d3e2005-11-14 00:44:47 +0000786 HReg dst;
787 HReg src;
788 } AvUn32Fx4;
cerionc3d8bdc2005-06-28 18:06:23 +0000789 /* Perm,Sel,SlDbl,Splat are all weird AV permutations */
790 struct {
cerionc3d8bdc2005-06-28 18:06:23 +0000791 HReg dst;
792 HReg srcL;
793 HReg srcR;
cerion92d9d872005-09-15 21:58:50 +0000794 HReg ctl;
cerionc3d8bdc2005-06-28 18:06:23 +0000795 } AvPerm;
796 struct {
cerionc3d8bdc2005-06-28 18:06:23 +0000797 HReg dst;
798 HReg srcL;
799 HReg srcR;
cerion92d9d872005-09-15 21:58:50 +0000800 HReg ctl;
cerionc3d8bdc2005-06-28 18:06:23 +0000801 } AvSel;
802 struct {
803 UChar shift;
804 HReg dst;
805 HReg srcL;
806 HReg srcR;
807 } AvShlDbl;
808 struct {
809 UChar sz; /* 8,16,32 */
810 HReg dst;
cerion5b2325f2005-12-23 00:55:09 +0000811 PPCVI5s* src;
cerionc3d8bdc2005-06-28 18:06:23 +0000812 } AvSplat;
cerion6b6f59e2005-06-28 20:59:18 +0000813 /* Mov src to dst on the given condition, which may not
814 be the bogus Xcc_ALWAYS. */
815 struct {
cerion5b2325f2005-12-23 00:55:09 +0000816 PPCCondCode cond;
817 HReg dst;
818 HReg src;
cerion6b6f59e2005-06-28 20:59:18 +0000819 } AvCMov;
sewardjb51f0f42005-07-18 11:38:02 +0000820 /* Load AltiVec Status & Control Register */
cerionc3d8bdc2005-06-28 18:06:23 +0000821 struct {
822 HReg src;
823 } AvLdVSCR;
sewardjc6bbd472012-04-02 10:20:48 +0000824 struct {
825 PPCFpOp op;
826 HReg dst;
827 HReg src;
828 } Dfp64Unary;
829 struct {
830 PPCFpOp op;
831 HReg dst;
832 HReg srcL;
833 HReg srcR;
834 } Dfp64Binary;
835 struct {
836 PPCFpOp op;
sewardj26217b02012-04-12 17:19:48 +0000837 HReg dst;
838 HReg src;
839 PPCRI* shift;
840 } DfpShift;
841 struct {
842 PPCFpOp op;
sewardjc6bbd472012-04-02 10:20:48 +0000843 HReg dst_hi;
844 HReg dst_lo;
845 HReg src_hi;
846 HReg src_lo;
847 } Dfp128Unary;
848 struct {
849 /* The dst is used to pass the left source operand in and return
850 * the result.
851 */
852 PPCFpOp op;
853 HReg dst_hi;
854 HReg dst_lo;
855 HReg srcR_hi;
856 HReg srcR_lo;
857 } Dfp128Binary;
sewardj26217b02012-04-12 17:19:48 +0000858 struct {
859 PPCFpOp op;
860 HReg dst_hi;
861 HReg dst_lo;
862 HReg src_hi;
863 HReg src_lo;
864 PPCRI* shift;
865 } DfpShift128;
866 struct {
867 PPCFpOp op;
868 HReg dst;
869 HReg src_hi;
870 HReg src_lo;
871 } DfpD128toD64;
872 struct {
873 PPCFpOp op;
874 HReg dst_hi;
875 HReg dst_lo;
876 HReg src;
877 } DfpI64StoD128;
sewardj3dee8492012-04-20 00:13:28 +0000878 struct {
879 PPCAMode* amCounter;
880 PPCAMode* amFailAddr;
881 } EvCheck;
882 struct {
883 /* No fields. The address of the counter to inc is
884 installed later, post-translation, by patching it in,
885 as it is not known at translation time. */
886 } ProfInc;
sewardjc6bbd472012-04-02 10:20:48 +0000887 } Pin;
cerionbcf8c3e2005-02-04 16:17:07 +0000888 }
cerion5b2325f2005-12-23 00:55:09 +0000889 PPCInstr;
cerionbcf8c3e2005-02-04 16:17:07 +0000890
cerioncd304492005-02-08 19:40:24 +0000891
cerion5b2325f2005-12-23 00:55:09 +0000892extern PPCInstr* PPCInstr_LI ( HReg, ULong, Bool );
893extern PPCInstr* PPCInstr_Alu ( PPCAluOp, HReg, HReg, PPCRH* );
894extern PPCInstr* PPCInstr_Shft ( PPCShftOp, Bool sz32, HReg, HReg, PPCRH* );
895extern PPCInstr* PPCInstr_AddSubC ( Bool, Bool, HReg, HReg, HReg );
896extern PPCInstr* PPCInstr_Cmp ( Bool, Bool, UInt, HReg, PPCRH* );
897extern PPCInstr* PPCInstr_Unary ( PPCUnaryOp op, HReg dst, HReg src );
898extern PPCInstr* PPCInstr_MulL ( Bool syned, Bool hi32, Bool sz32, HReg, HReg, HReg );
sewardj4aa412a2011-07-24 14:13:21 +0000899extern PPCInstr* PPCInstr_Div ( Bool extended, Bool syned, Bool sz32, HReg dst, HReg srcL, HReg srcR );
cerion5b2325f2005-12-23 00:55:09 +0000900extern PPCInstr* PPCInstr_Call ( PPCCondCode, Addr64, UInt );
sewardj3dee8492012-04-20 00:13:28 +0000901extern PPCInstr* PPCInstr_XDirect ( Addr64 dstGA, PPCAMode* amCIA,
902 PPCCondCode cond, Bool toFastEP );
903extern PPCInstr* PPCInstr_XIndir ( HReg dstGA, PPCAMode* amCIA,
904 PPCCondCode cond );
905extern PPCInstr* PPCInstr_XAssisted ( HReg dstGA, PPCAMode* amCIA,
906 PPCCondCode cond, IRJumpKind jk );
cerion5b2325f2005-12-23 00:55:09 +0000907extern PPCInstr* PPCInstr_CMov ( PPCCondCode, HReg dst, PPCRI* src );
sewardj7fd5bb02006-01-26 02:24:17 +0000908extern PPCInstr* PPCInstr_Load ( UChar sz,
cerion5b2325f2005-12-23 00:55:09 +0000909 HReg dst, PPCAMode* src, Bool mode64 );
sewardje9d8a262009-07-01 08:06:34 +0000910extern PPCInstr* PPCInstr_LoadL ( UChar sz,
911 HReg dst, HReg src, Bool mode64 );
cerion5b2325f2005-12-23 00:55:09 +0000912extern PPCInstr* PPCInstr_Store ( UChar sz, PPCAMode* dst,
913 HReg src, Bool mode64 );
sewardje9d8a262009-07-01 08:06:34 +0000914extern PPCInstr* PPCInstr_StoreC ( UChar sz, HReg dst, HReg src,
915 Bool mode64 );
cerion5b2325f2005-12-23 00:55:09 +0000916extern PPCInstr* PPCInstr_Set ( PPCCondCode cond, HReg dst );
917extern PPCInstr* PPCInstr_MfCR ( HReg dst );
918extern PPCInstr* PPCInstr_MFence ( void );
cerioned623db2005-06-20 12:42:04 +0000919
cerion5b2325f2005-12-23 00:55:09 +0000920extern PPCInstr* PPCInstr_FpUnary ( PPCFpOp op, HReg dst, HReg src );
921extern PPCInstr* PPCInstr_FpBinary ( PPCFpOp op, HReg dst, HReg srcL, HReg srcR );
sewardj40c80262006-02-08 19:30:46 +0000922extern PPCInstr* PPCInstr_FpMulAcc ( PPCFpOp op, HReg dst, HReg srcML,
923 HReg srcMR, HReg srcAcc );
cerion5b2325f2005-12-23 00:55:09 +0000924extern PPCInstr* PPCInstr_FpLdSt ( Bool isLoad, UChar sz, HReg, PPCAMode* );
sewardj92923de2006-01-25 21:29:48 +0000925extern PPCInstr* PPCInstr_FpSTFIW ( HReg addr, HReg data );
926extern PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src );
sewardj66d5ef22011-04-15 11:55:00 +0000927extern PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, Bool syned,
928 Bool dst64, HReg dst, HReg src );
cerion5b2325f2005-12-23 00:55:09 +0000929extern PPCInstr* PPCInstr_FpCMov ( PPCCondCode, HReg dst, HReg src );
sewardjc6bbd472012-04-02 10:20:48 +0000930extern PPCInstr* PPCInstr_FpLdFPSCR ( HReg src, Bool dfp_rm );
cerion5b2325f2005-12-23 00:55:09 +0000931extern PPCInstr* PPCInstr_FpCmp ( HReg dst, HReg srcL, HReg srcR );
cerionbcf8c3e2005-02-04 16:17:07 +0000932
cerion5b2325f2005-12-23 00:55:09 +0000933extern PPCInstr* PPCInstr_RdWrLR ( Bool wrLR, HReg gpr );
cerion7f000af2005-02-22 20:36:49 +0000934
cerion5b2325f2005-12-23 00:55:09 +0000935extern PPCInstr* PPCInstr_AvLdSt ( Bool isLoad, UChar sz, HReg, PPCAMode* );
936extern PPCInstr* PPCInstr_AvUnary ( PPCAvOp op, HReg dst, HReg src );
937extern PPCInstr* PPCInstr_AvBinary ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
938extern PPCInstr* PPCInstr_AvBin8x16 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
939extern PPCInstr* PPCInstr_AvBin16x8 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
940extern PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
sewardje522d4b2011-04-26 21:36:09 +0000941extern PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst, HReg srcL, HReg srcR );
942extern PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op, HReg dst, HReg src );
cerion5b2325f2005-12-23 00:55:09 +0000943extern PPCInstr* PPCInstr_AvPerm ( HReg dst, HReg srcL, HReg srcR, HReg ctl );
944extern PPCInstr* PPCInstr_AvSel ( HReg ctl, HReg dst, HReg srcL, HReg srcR );
945extern PPCInstr* PPCInstr_AvShlDbl ( UChar shift, HReg dst, HReg srcL, HReg srcR );
946extern PPCInstr* PPCInstr_AvSplat ( UChar sz, HReg dst, PPCVI5s* src );
947extern PPCInstr* PPCInstr_AvCMov ( PPCCondCode, HReg dst, HReg src );
948extern PPCInstr* PPCInstr_AvLdVSCR ( HReg src );
cerionbcf8c3e2005-02-04 16:17:07 +0000949
sewardjc6bbd472012-04-02 10:20:48 +0000950extern PPCInstr* PPCInstr_Dfp64Unary ( PPCFpOp op, HReg dst, HReg src );
951extern PPCInstr* PPCInstr_Dfp64Binary ( PPCFpOp op, HReg dst, HReg srcL,
952 HReg srcR );
sewardj26217b02012-04-12 17:19:48 +0000953extern PPCInstr* PPCInstr_DfpShift ( PPCFpOp op, HReg dst, HReg src,
954 PPCRI* shift );
955extern PPCInstr* PPCInstr_Dfp128Unary ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
956 HReg srcR_hi, HReg srcR_lo );
957extern PPCInstr* PPCInstr_Dfp128Binary ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
958 HReg srcR_hi, HReg srcR_lo );
959extern PPCInstr* PPCInstr_DfpShift128 ( PPCFpOp op, HReg dst_hi, HReg src_hi,
960 HReg dst_lo, HReg src_lo,
961 PPCRI* shift );
962extern PPCInstr* PPCInstr_DfpD128toD64 ( PPCFpOp op, HReg dst,
963 HReg dst_lo, HReg src_lo);
964extern PPCInstr* PPCInstr_DfpI64StoD128 ( PPCFpOp op, HReg dst_hi,
965 HReg dst_lo, HReg src);
sewardj3dee8492012-04-20 00:13:28 +0000966extern PPCInstr* PPCInstr_EvCheck ( PPCAMode* amCounter,
967 PPCAMode* amFailAddr );
968extern PPCInstr* PPCInstr_ProfInc ( void );
sewardjc6bbd472012-04-02 10:20:48 +0000969
970extern void ppPPCInstr(PPCInstr*, Bool mode64);
971
cerionbcf8c3e2005-02-04 16:17:07 +0000972
973/* Some functions that insulate the register allocator from details
974 of the underlying instruction set. */
cerion5b2325f2005-12-23 00:55:09 +0000975extern void getRegUsage_PPCInstr ( HRegUsage*, PPCInstr*, Bool mode64 );
976extern void mapRegs_PPCInstr ( HRegRemap*, PPCInstr* , Bool mode64);
977extern Bool isMove_PPCInstr ( PPCInstr*, HReg*, HReg* );
sewardj3dee8492012-04-20 00:13:28 +0000978extern Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc,
979 UChar* buf, Int nbuf, PPCInstr* i,
sewardj010ac542011-05-29 09:29:18 +0000980 Bool mode64,
sewardj3dee8492012-04-20 00:13:28 +0000981 void* disp_cp_chain_me_to_slowEP,
982 void* disp_cp_chain_me_to_fastEP,
983 void* disp_cp_xindir,
984 void* disp_cp_xassisted );
sewardj2a0cc852010-01-02 13:23:54 +0000985
986extern void genSpill_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
987 HReg rreg, Int offsetB, Bool mode64 );
988extern void genReload_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
989 HReg rreg, Int offsetB, Bool mode64 );
990
cerion5b2325f2005-12-23 00:55:09 +0000991extern void getAllocableRegs_PPC ( Int*, HReg**, Bool mode64 );
sewardj3dee8492012-04-20 00:13:28 +0000992extern HInstrArray* iselSB_PPC ( IRSB*,
993 VexArch,
994 VexArchInfo*,
995 VexAbiInfo*,
996 Int offs_Host_EvC_Counter,
997 Int offs_Host_EvC_FailAddr,
998 Bool chainingAllowed,
999 Bool addProfInc,
1000 Addr64 max_ga );
1001
1002/* How big is an event check? This is kind of a kludge because it
1003 depends on the offsets of host_EvC_FAILADDR and
1004 host_EvC_COUNTER. */
1005extern Int evCheckSzB_PPC ( void );
1006
1007/* Perform a chaining and unchaining of an XDirect jump. */
1008extern VexInvalRange chainXDirect_PPC ( void* place_to_chain,
1009 void* disp_cp_chain_me_EXPECTED,
1010 void* place_to_jump_to,
1011 Bool mode64 );
1012
1013extern VexInvalRange unchainXDirect_PPC ( void* place_to_unchain,
1014 void* place_to_jump_to_EXPECTED,
1015 void* disp_cp_chain_me,
1016 Bool mode64 );
1017
1018/* Patch the counter location into an existing ProfInc point. */
1019extern VexInvalRange patchProfInc_PPC ( void* place_to_patch,
1020 ULong* location_of_counter,
1021 Bool mode64 );
1022
cerionbcf8c3e2005-02-04 16:17:07 +00001023
sewardjcef7d3e2009-07-02 12:21:59 +00001024#endif /* ndef __VEX_HOST_PPC_DEFS_H */
cerionbcf8c3e2005-02-04 16:17:07 +00001025
1026/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001027/*--- end host_ppc_defs.h ---*/
cerionbcf8c3e2005-02-04 16:17:07 +00001028/*---------------------------------------------------------------*/