blob: c91ac5e1c2d1da3f73e593dc93138cb4e402eb5d [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin host_s390_defs.h ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj89ae8472013-10-18 14:12:58 +000011 Copyright IBM Corp. 2010-2013
sewardj2019a972011-03-07 16:04:07 +000012
13 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.
17
18 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
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm */
32
33#ifndef __VEX_HOST_S390_DEFS_H
34#define __VEX_HOST_S390_DEFS_H
35
36#include "libvex_basictypes.h" /* Bool */
37#include "libvex.h" /* VexArchInfo */
sewardj2019a972011-03-07 16:04:07 +000038#include "host_generic_regs.h" /* HReg */
florianb0b67102012-12-24 00:14:31 +000039#include "s390_defs.h" /* s390_cc_t */
sewardj2019a972011-03-07 16:04:07 +000040
41/* --------- Registers --------- */
42const HChar *s390_hreg_as_string(HReg);
43
sewardj2019a972011-03-07 16:04:07 +000044/* Dedicated registers */
45HReg s390_hreg_guest_state_pointer(void);
46
47
48/* Given the index of a function argument, return the number of the
49 general purpose register in which it is being passed. Arguments are
50 counted 0, 1, 2, ... and they are being passed in r2, r3, r4, ... */
florianffbd84d2012-12-09 02:06:29 +000051static __inline__ UInt
52s390_gprno_from_arg_index(UInt ix)
sewardj2019a972011-03-07 16:04:07 +000053{
54 return ix + 2;
55}
56
57/* --------- Memory address expressions (amodes). --------- */
58
59/* These are the address modes:
60 (1) b12: base register + 12-bit unsigned offset (e.g. RS)
61 (2) b20: base register + 20-bit signed offset (e.g. RSY)
62 (3) bx12: base register + index register + 12-bit unsigned offset (e.g. RX)
63 (4) bx20: base register + index register + 20-bit signed offset (e.g. RXY)
64 fixs390: There is also pc-relative stuff.. e.g. LARL
65*/
66
67typedef enum {
68 S390_AMODE_B12,
69 S390_AMODE_B20,
70 S390_AMODE_BX12,
71 S390_AMODE_BX20
72} s390_amode_t;
73
florianb4df7682011-07-05 02:09:01 +000074typedef struct {
sewardj2019a972011-03-07 16:04:07 +000075 s390_amode_t tag;
76 HReg b;
77 HReg x; /* hregNumber(x) == 0 for S390_AMODE_B12/B20 kinds */
78 Int d; /* 12 bit unsigned or 20 bit signed */
79} s390_amode;
80
81
82s390_amode *s390_amode_b12(Int d, HReg b);
83s390_amode *s390_amode_b20(Int d, HReg b);
84s390_amode *s390_amode_bx12(Int d, HReg b, HReg x);
85s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
86s390_amode *s390_amode_for_guest_state(Int d);
87Bool s390_amode_is_sane(const s390_amode *);
sewardj2019a972011-03-07 16:04:07 +000088
89const HChar *s390_amode_as_string(const s390_amode *);
90
sewardj2019a972011-03-07 16:04:07 +000091/* ------------- 2nd (right) operand of binary operation ---------------- */
92
93typedef enum {
94 S390_OPND_REG,
95 S390_OPND_IMMEDIATE,
96 S390_OPND_AMODE
97} s390_opnd_t;
98
99
100/* Naming convention for operand locations:
101 R - GPR
102 I - immediate value
103 M - memory (any Amode may be used)
104*/
105
106/* An operand that is either in a GPR or is addressable via a BX20 amode */
107typedef struct {
108 s390_opnd_t tag;
109 union {
110 HReg reg;
111 s390_amode *am;
112 ULong imm;
113 } variant;
114} s390_opnd_RMI;
115
116
117/* The kind of instructions */
118typedef enum {
119 S390_INSN_LOAD, /* load register from memory */
120 S390_INSN_STORE, /* store register to memory */
121 S390_INSN_MOVE, /* from register to register */
floriancec3a8a2013-02-02 00:16:58 +0000122 S390_INSN_MEMCPY, /* from memory to memory */
sewardj2019a972011-03-07 16:04:07 +0000123 S390_INSN_COND_MOVE, /* conditonal "move" to register */
124 S390_INSN_LOAD_IMMEDIATE,
125 S390_INSN_ALU,
florianc4aa7ed2012-12-22 15:01:04 +0000126 S390_INSN_SMUL, /* signed multiply; n-bit operands; 2n-bit result */
127 S390_INSN_UMUL, /* unsigned multiply; n-bit operands; 2n-bit result */
128 S390_INSN_SDIV, /* signed division; 2n-bit / n-bit -> n-bit quot/rem */
129 S390_INSN_UDIV, /* unsigned division; 2n-bit / n-bit -> n-bit quot/rem */
sewardj2019a972011-03-07 16:04:07 +0000130 S390_INSN_DIVS, /* n-bit dividend; n-bit divisor; n-bit quot/rem */
sewardj611b06e2011-03-24 08:57:29 +0000131 S390_INSN_CLZ, /* count left-most zeroes */
sewardj2019a972011-03-07 16:04:07 +0000132 S390_INSN_UNOP,
133 S390_INSN_TEST, /* test operand and set cc */
134 S390_INSN_CC2BOOL,/* convert condition code to 0/1 */
135 S390_INSN_COMPARE,
sewardj2019a972011-03-07 16:04:07 +0000136 S390_INSN_HELPER_CALL,
137 S390_INSN_CAS, /* compare and swap */
florian448cbba2012-06-06 02:26:01 +0000138 S390_INSN_CDAS, /* compare double and swap */
floriancc491a62012-09-10 23:44:37 +0000139 S390_INSN_BFP_BINOP, /* Binary floating point */
sewardj2019a972011-03-07 16:04:07 +0000140 S390_INSN_BFP_UNOP,
141 S390_INSN_BFP_TRIOP,
142 S390_INSN_BFP_COMPARE,
florian9fcff4c2012-09-10 03:09:04 +0000143 S390_INSN_BFP_CONVERT,
florian12390202012-11-10 22:34:14 +0000144 S390_INSN_DFP_BINOP, /* Decimal floating point */
floriance9e3db2012-12-27 20:14:03 +0000145 S390_INSN_DFP_UNOP,
florian1b901d42013-01-01 22:19:24 +0000146 S390_INSN_DFP_INTOP,
floriane38f6412012-12-21 17:32:12 +0000147 S390_INSN_DFP_COMPARE,
148 S390_INSN_DFP_CONVERT,
florian5c539732013-02-14 14:27:12 +0000149 S390_INSN_DFP_REROUND,
florian78d5ef72013-05-11 15:02:58 +0000150 S390_INSN_FP_CONVERT,
florianad43b3a2012-02-20 15:01:14 +0000151 S390_INSN_MFENCE,
florianb93348d2012-12-27 00:59:43 +0000152 S390_INSN_MIMM, /* Assign an immediate constant to a memory location */
florianf85fe3e2012-12-22 02:28:25 +0000153 S390_INSN_MADD, /* Add a value to a memory location */
florian125e20d2012-10-07 15:42:37 +0000154 S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
florianc8e4f562012-10-27 16:19:31 +0000155 S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
florian8844a632012-04-13 04:04:06 +0000156 /* The following 5 insns are mandated by translation chaining */
157 S390_INSN_XDIRECT, /* direct transfer to guest address */
158 S390_INSN_XINDIR, /* indirect transfer to guest address */
159 S390_INSN_XASSISTED, /* assisted transfer to guest address */
160 S390_INSN_EVCHECK, /* Event check */
161 S390_INSN_PROFINC /* 64-bit profile counter increment */
sewardj2019a972011-03-07 16:04:07 +0000162} s390_insn_tag;
163
164
165/* The kind of ALU instructions */
166typedef enum {
167 S390_ALU_ADD,
168 S390_ALU_SUB,
169 S390_ALU_MUL, /* n-bit operands; result is lower n-bit of product */
170 S390_ALU_AND,
171 S390_ALU_OR,
172 S390_ALU_XOR,
173 S390_ALU_LSH,
174 S390_ALU_RSH,
175 S390_ALU_RSHA /* arithmetic */
176} s390_alu_t;
177
178
179/* The kind of unary integer operations */
180typedef enum {
181 S390_ZERO_EXTEND_8,
182 S390_ZERO_EXTEND_16,
183 S390_ZERO_EXTEND_32,
184 S390_SIGN_EXTEND_8,
185 S390_SIGN_EXTEND_16,
186 S390_SIGN_EXTEND_32,
187 S390_NEGATE
188} s390_unop_t;
189
190/* The kind of ternary BFP operations */
191typedef enum {
192 S390_BFP_MADD,
193 S390_BFP_MSUB,
194} s390_bfp_triop_t;
195
196/* The kind of binary BFP operations */
197typedef enum {
198 S390_BFP_ADD,
199 S390_BFP_SUB,
200 S390_BFP_MUL,
201 S390_BFP_DIV
202} s390_bfp_binop_t;
203
sewardj2019a972011-03-07 16:04:07 +0000204/* The kind of unary BFP operations */
205typedef enum {
206 S390_BFP_ABS,
207 S390_BFP_NABS,
208 S390_BFP_NEG,
florian9fcff4c2012-09-10 03:09:04 +0000209 S390_BFP_SQRT
210} s390_bfp_unop_t;
211
floriane38f6412012-12-21 17:32:12 +0000212/* Type conversion operations: to and/or from binary floating point */
florian9fcff4c2012-09-10 03:09:04 +0000213typedef enum {
sewardj2019a972011-03-07 16:04:07 +0000214 S390_BFP_I32_TO_F32,
215 S390_BFP_I32_TO_F64,
216 S390_BFP_I32_TO_F128,
217 S390_BFP_I64_TO_F32,
218 S390_BFP_I64_TO_F64,
219 S390_BFP_I64_TO_F128,
florian1c8f7ff2012-09-01 00:12:11 +0000220 S390_BFP_U32_TO_F32,
221 S390_BFP_U32_TO_F64,
222 S390_BFP_U32_TO_F128,
223 S390_BFP_U64_TO_F32,
224 S390_BFP_U64_TO_F64,
225 S390_BFP_U64_TO_F128,
sewardj2019a972011-03-07 16:04:07 +0000226 S390_BFP_F32_TO_I32,
227 S390_BFP_F32_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000228 S390_BFP_F32_TO_U32,
229 S390_BFP_F32_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000230 S390_BFP_F32_TO_F64,
231 S390_BFP_F32_TO_F128,
232 S390_BFP_F64_TO_I32,
233 S390_BFP_F64_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000234 S390_BFP_F64_TO_U32,
235 S390_BFP_F64_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000236 S390_BFP_F64_TO_F32,
237 S390_BFP_F64_TO_F128,
238 S390_BFP_F128_TO_I32,
239 S390_BFP_F128_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000240 S390_BFP_F128_TO_U32,
241 S390_BFP_F128_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000242 S390_BFP_F128_TO_F32,
243 S390_BFP_F128_TO_F64
florian6dc90242012-12-21 21:43:00 +0000244} s390_bfp_conv_t;
sewardj2019a972011-03-07 16:04:07 +0000245
floriane38f6412012-12-21 17:32:12 +0000246/* Type conversion operations: to and/or from decimal floating point */
247typedef enum {
248 S390_DFP_D32_TO_D64,
249 S390_DFP_D64_TO_D32,
250 S390_DFP_D64_TO_D128,
florian5f034622013-01-13 02:29:05 +0000251 S390_DFP_D128_TO_D64,
252 S390_DFP_I32_TO_D64,
253 S390_DFP_I32_TO_D128,
floriana887acd2013-02-08 23:32:54 +0000254 S390_DFP_I64_TO_D64,
255 S390_DFP_I64_TO_D128,
florian5f034622013-01-13 02:29:05 +0000256 S390_DFP_U32_TO_D64,
257 S390_DFP_U32_TO_D128,
258 S390_DFP_U64_TO_D64,
259 S390_DFP_U64_TO_D128,
260 S390_DFP_D64_TO_I32,
floriana887acd2013-02-08 23:32:54 +0000261 S390_DFP_D64_TO_I64,
florian5f034622013-01-13 02:29:05 +0000262 S390_DFP_D64_TO_U32,
263 S390_DFP_D64_TO_U64,
264 S390_DFP_D128_TO_I32,
floriana887acd2013-02-08 23:32:54 +0000265 S390_DFP_D128_TO_I64,
florian5f034622013-01-13 02:29:05 +0000266 S390_DFP_D128_TO_U32,
267 S390_DFP_D128_TO_U64
floriane38f6412012-12-21 17:32:12 +0000268} s390_dfp_conv_t;
sewardj2019a972011-03-07 16:04:07 +0000269
florian78d5ef72013-05-11 15:02:58 +0000270typedef enum {
florian7ab421d2013-06-17 21:03:56 +0000271 S390_FP_F32_TO_D32,
272 S390_FP_F32_TO_D64,
273 S390_FP_F32_TO_D128,
274 S390_FP_F64_TO_D32,
florian78d5ef72013-05-11 15:02:58 +0000275 S390_FP_F64_TO_D64,
florian78d5ef72013-05-11 15:02:58 +0000276 S390_FP_F64_TO_D128,
florian7ab421d2013-06-17 21:03:56 +0000277 S390_FP_F128_TO_D32,
278 S390_FP_F128_TO_D64,
florian78d5ef72013-05-11 15:02:58 +0000279 S390_FP_F128_TO_D128,
florian7ab421d2013-06-17 21:03:56 +0000280 S390_FP_D32_TO_F32,
281 S390_FP_D32_TO_F64,
282 S390_FP_D32_TO_F128,
283 S390_FP_D64_TO_F32,
284 S390_FP_D64_TO_F64,
285 S390_FP_D64_TO_F128,
286 S390_FP_D128_TO_F32,
287 S390_FP_D128_TO_F64,
florian78d5ef72013-05-11 15:02:58 +0000288 S390_FP_D128_TO_F128
289} s390_fp_conv_t;
290
florian12390202012-11-10 22:34:14 +0000291/* The kind of binary DFP operations */
292typedef enum {
293 S390_DFP_ADD,
294 S390_DFP_SUB,
295 S390_DFP_MUL,
florian5c539732013-02-14 14:27:12 +0000296 S390_DFP_DIV,
297 S390_DFP_QUANTIZE
florian12390202012-11-10 22:34:14 +0000298} s390_dfp_binop_t;
299
floriance9e3db2012-12-27 20:14:03 +0000300/* The kind of unary DFP operations */
301typedef enum {
florian5c539732013-02-14 14:27:12 +0000302 S390_DFP_EXTRACT_EXP_D64,
303 S390_DFP_EXTRACT_EXP_D128,
floriance9e3db2012-12-27 20:14:03 +0000304 S390_DFP_EXTRACT_SIG_D64,
305 S390_DFP_EXTRACT_SIG_D128,
306} s390_dfp_unop_t;
307
florian1b901d42013-01-01 22:19:24 +0000308/* The DFP operations with 2 operands one of them being integer */
309typedef enum {
310 S390_DFP_SHIFT_LEFT,
florian5c539732013-02-14 14:27:12 +0000311 S390_DFP_SHIFT_RIGHT,
312 S390_DFP_INSERT_EXP
florian1b901d42013-01-01 22:19:24 +0000313} s390_dfp_intop_t;
314
florian20c6bca2012-12-26 17:47:19 +0000315/* The kind of DFP compare operations */
316typedef enum {
317 S390_DFP_COMPARE,
318 S390_DFP_COMPARE_EXP,
319} s390_dfp_cmp_t;
320
florianc4aa7ed2012-12-22 15:01:04 +0000321/* The details of a CDAS insn. Carved out to keep the size of
322 s390_insn low */
323typedef struct {
324 HReg op1_high;
325 HReg op1_low;
326 s390_amode *op2;
327 HReg op3_high;
328 HReg op3_low;
329 HReg old_mem_high;
330 HReg old_mem_low;
331 HReg scratch;
332} s390_cdas;
333
334/* The details of a binary DFP insn. Carved out to keep the size of
335 s390_insn low */
336typedef struct {
337 s390_dfp_binop_t tag;
338 s390_dfp_round_t rounding_mode;
339 HReg dst_hi; /* 128-bit result high part; 64-bit result */
340 HReg dst_lo; /* 128-bit result low part */
341 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
342 HReg op2_lo; /* 128-bit operand low part */
343 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
344 HReg op3_lo; /* 128-bit operand low part */
345} s390_dfp_binop;
346
florianb4df7682011-07-05 02:09:01 +0000347typedef struct {
florian78d5ef72013-05-11 15:02:58 +0000348 s390_fp_conv_t tag;
349 s390_dfp_round_t rounding_mode;
350 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
351 HReg dst_lo; /* 128-bit result low part */
352 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
353 HReg op_lo; /* 128-bit operand low part */
354 HReg r1; /* clobbered register GPR #1 */
355} s390_fp_convert;
356
sewardj74142b82013-08-08 10:28:59 +0000357/* Pseudo-insn for representing a helper call.
358 TARGET is the absolute address of the helper function
359 NUM_ARGS says how many arguments are being passed.
360 All arguments have integer type and are being passed according to ABI,
361 i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
362 passed in r2 and so forth. */
363typedef struct {
364 s390_cc_t cond : 16;
365 UInt num_args : 16;
366 RetLoc rloc; /* where the return value will be */
367 Addr64 target;
368 const HChar *name; /* callee's name (for debugging) */
369} s390_helper_call;
370
florian78d5ef72013-05-11 15:02:58 +0000371typedef struct {
sewardj2019a972011-03-07 16:04:07 +0000372 s390_insn_tag tag;
floriancc491a62012-09-10 23:44:37 +0000373 /* Usually, this is the size of the result of an operation.
374 Exceptions are:
375 - for comparisons it is the size of the operand
376 */
377 UChar size;
sewardj2019a972011-03-07 16:04:07 +0000378 union {
379 struct {
380 HReg dst;
381 s390_amode *src;
382 } load;
383 struct {
384 s390_amode *dst;
385 HReg src;
386 } store;
387 struct {
388 HReg dst;
389 HReg src;
390 } move;
391 struct {
floriancec3a8a2013-02-02 00:16:58 +0000392 s390_amode *dst;
393 s390_amode *src;
394 } memcpy;
395 struct {
sewardj2019a972011-03-07 16:04:07 +0000396 s390_cc_t cond;
397 HReg dst;
398 s390_opnd_RMI src;
399 } cond_move;
400 struct {
401 HReg dst;
402 ULong value; /* not sign extended */
403 } load_immediate;
404 /* add, and, or, xor */
405 struct {
406 s390_alu_t tag;
407 HReg dst; /* op1 */
408 s390_opnd_RMI op2;
409 } alu;
410 struct {
sewardj2019a972011-03-07 16:04:07 +0000411 HReg dst_hi; /* r10 */
412 HReg dst_lo; /* also op1 r11 */
413 s390_opnd_RMI op2;
414 } mul;
415 struct {
sewardj2019a972011-03-07 16:04:07 +0000416 HReg op1_hi; /* also remainder r10 */
417 HReg op1_lo; /* also quotient r11 */
418 s390_opnd_RMI op2;
419 } div;
420 struct {
421 HReg rem; /* remainder r10 */
422 HReg op1; /* also quotient r11 */
423 s390_opnd_RMI op2;
424 } divs;
425 struct {
sewardj611b06e2011-03-24 08:57:29 +0000426 HReg num_bits; /* number of leftmost '0' bits r10 */
427 HReg clobber; /* unspecified r11 */
sewardj2019a972011-03-07 16:04:07 +0000428 s390_opnd_RMI src;
sewardj611b06e2011-03-24 08:57:29 +0000429 } clz;
sewardj2019a972011-03-07 16:04:07 +0000430 struct {
431 s390_unop_t tag;
432 HReg dst;
433 s390_opnd_RMI src;
434 } unop;
435 struct {
436 Bool signed_comparison;
437 HReg src1;
438 s390_opnd_RMI src2;
439 } compare;
440 struct {
sewardj2019a972011-03-07 16:04:07 +0000441 s390_opnd_RMI src;
442 } test;
443 /* Convert the condition code to a boolean value. */
444 struct {
445 s390_cc_t cond;
446 HReg dst;
447 } cc2bool;
448 struct {
449 HReg op1;
450 s390_amode *op2;
451 HReg op3;
452 HReg old_mem;
453 } cas;
florian448cbba2012-06-06 02:26:01 +0000454 struct {
florianc4aa7ed2012-12-22 15:01:04 +0000455 s390_cdas *details;
florian448cbba2012-06-06 02:26:01 +0000456 } cdas;
sewardj2019a972011-03-07 16:04:07 +0000457 struct {
sewardj74142b82013-08-08 10:28:59 +0000458 s390_helper_call *details;
sewardj2019a972011-03-07 16:04:07 +0000459 } helper_call;
floriancc491a62012-09-10 23:44:37 +0000460
461 /* Floating point instructions (including conversion to/from floating
462 point
463
464 128-bit floating point requires register pairs. As the registers
465 in a register pair cannot be chosen independently it would suffice
466 to store only one register of the pair in order to represent it.
467 We chose not to do that as being explicit about all registers
468 helps with debugging and does not require special handling in
florian2c74d242012-09-12 19:38:42 +0000469 e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
floriancc491a62012-09-10 23:44:37 +0000470 the "other" register in a pair if it is implicit.
471
472 The convention for all fp s390_insn is that the _hi register will
473 be used to store the result / operand of a 32/64-bit operation.
474 The _hi register holds the 8 bytes of HIgher significance of a
475 128-bit value (hence the suffix). However, it is the lower numbered
476 register of a register pair. POP says that the lower numbered
477 register is used to identify the pair in an insn encoding. So,
478 when an insn is emitted, only the _hi registers need to be looked
479 at. Nothing special is needed for 128-bit BFP which is nice.
480 */
481
482 /* There are currently no ternary 128-bit BFP operations. */
sewardj2019a972011-03-07 16:04:07 +0000483 struct {
484 s390_bfp_triop_t tag;
floriancc491a62012-09-10 23:44:37 +0000485 HReg dst;
486 HReg op2;
487 HReg op3;
sewardj2019a972011-03-07 16:04:07 +0000488 } bfp_triop;
489 struct {
490 s390_bfp_binop_t tag;
floriancc491a62012-09-10 23:44:37 +0000491 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
492 HReg dst_lo; /* 128-bit result low part */
493 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
494 HReg op2_lo; /* 128-bit operand low part */
sewardj2019a972011-03-07 16:04:07 +0000495 } bfp_binop;
496 struct {
sewardj2019a972011-03-07 16:04:07 +0000497 s390_bfp_unop_t tag;
floriancc491a62012-09-10 23:44:37 +0000498 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
499 HReg dst_lo; /* 128-bit result low part */
500 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
501 HReg op_lo; /* 128-bit operand low part */
502 } bfp_unop;
sewardj2019a972011-03-07 16:04:07 +0000503 struct {
florian6dc90242012-12-21 21:43:00 +0000504 s390_bfp_conv_t tag;
florian125e20d2012-10-07 15:42:37 +0000505 s390_bfp_round_t rounding_mode;
florian9fcff4c2012-09-10 03:09:04 +0000506 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
507 HReg dst_lo; /* 128-bit result low part */
508 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
509 HReg op_lo; /* 128-bit operand low part */
floriancc491a62012-09-10 23:44:37 +0000510 } bfp_convert;
florian9fcff4c2012-09-10 03:09:04 +0000511 struct {
floriancc491a62012-09-10 23:44:37 +0000512 HReg dst; /* condition code in s390 encoding */
513 HReg op1_hi; /* 128-bit operand high part; 32/64-bit opnd */
514 HReg op1_lo; /* 128-bit operand low part */
515 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
516 HReg op2_lo; /* 128-bit operand low part */
517 } bfp_compare;
florian12390202012-11-10 22:34:14 +0000518 struct {
florianc4aa7ed2012-12-22 15:01:04 +0000519 s390_dfp_binop *details;
florian12390202012-11-10 22:34:14 +0000520 } dfp_binop;
floriane38f6412012-12-21 17:32:12 +0000521 struct {
floriance9e3db2012-12-27 20:14:03 +0000522 s390_dfp_unop_t tag;
523 HReg dst_hi; /* 128-bit result high part; 64-bit result */
524 HReg dst_lo; /* 128-bit result low part */
525 HReg op_hi; /* 128-bit operand high part; 64-bit opnd */
526 HReg op_lo; /* 128-bit operand low part */
527 } dfp_unop;
528 struct {
florian1b901d42013-01-01 22:19:24 +0000529 s390_dfp_intop_t tag;
530 HReg dst_hi; /* 128-bit result high part; 64-bit result */
531 HReg dst_lo; /* 128-bit result low part */
532 HReg op2; /* integer operand */
533 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd */
534 HReg op3_lo; /* 128-bit operand low part */
535 } dfp_intop;
536 struct {
floriane38f6412012-12-21 17:32:12 +0000537 s390_dfp_conv_t tag;
538 s390_dfp_round_t rounding_mode;
539 HReg dst_hi; /* 128-bit result high part; 64-bit result */
540 HReg dst_lo; /* 128-bit result low part */
541 HReg op_hi; /* 128-bit operand high part; 64-bit opnd */
542 HReg op_lo; /* 128-bit operand low part */
543 } dfp_convert;
544 struct {
florian78d5ef72013-05-11 15:02:58 +0000545 s390_fp_convert *details;
546 } fp_convert;
547 struct {
florian20c6bca2012-12-26 17:47:19 +0000548 s390_dfp_cmp_t tag;
floriane38f6412012-12-21 17:32:12 +0000549 HReg dst; /* condition code in s390 encoding */
550 HReg op1_hi; /* 128-bit operand high part; 64-bit opnd 1 */
551 HReg op1_lo; /* 128-bit operand low part */
552 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 2 */
553 HReg op2_lo; /* 128-bit operand low part */
554 } dfp_compare;
florian5c539732013-02-14 14:27:12 +0000555 struct {
556 s390_dfp_round_t rounding_mode;
557 HReg dst_hi; /* 128-bit result high part; 64-bit result */
558 HReg dst_lo; /* 128-bit result low part */
559 HReg op2; /* integer operand */
560 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd */
561 HReg op3_lo; /* 128-bit operand low part */
562 } dfp_reround;
floriancc491a62012-09-10 23:44:37 +0000563
564 /* Miscellaneous */
florianad43b3a2012-02-20 15:01:14 +0000565 struct {
florian09bbba82012-12-11 04:09:43 +0000566 s390_amode *dst;
florianb93348d2012-12-27 00:59:43 +0000567 ULong value; /* sign extended */
568 } mimm;
florianad43b3a2012-02-20 15:01:14 +0000569 struct {
florianf85fe3e2012-12-22 02:28:25 +0000570 s390_amode *dst;
florianad43b3a2012-02-20 15:01:14 +0000571 UChar delta;
572 ULong value; /* for debugging only */
florianf85fe3e2012-12-22 02:28:25 +0000573 } madd;
florian2c74d242012-09-12 19:38:42 +0000574 struct {
575 HReg mode;
florian125e20d2012-10-07 15:42:37 +0000576 } set_fpc_bfprm;
florianc8e4f562012-10-27 16:19:31 +0000577 struct {
578 HReg mode;
579 } set_fpc_dfprm;
florian8844a632012-04-13 04:04:06 +0000580
581 /* The next 5 entries are generic to support translation chaining */
582
583 /* Update the guest IA value, then exit requesting to chain
584 to it. May be conditional. */
585 struct {
586 s390_cc_t cond;
587 Bool to_fast_entry; /* chain to the what entry point? */
588 Addr64 dst; /* next guest address */
589 s390_amode *guest_IA;
590 } xdirect;
591 /* Boring transfer to a guest address not known at JIT time.
592 Not chainable. May be conditional. */
593 struct {
594 s390_cc_t cond;
595 HReg dst;
596 s390_amode *guest_IA;
597 } xindir;
598 /* Assisted transfer to a guest address, most general case.
599 Not chainable. May be conditional. */
600 struct {
601 s390_cc_t cond;
602 IRJumpKind kind;
603 HReg dst;
604 s390_amode *guest_IA;
605 } xassisted;
606 struct {
607 /* fixs390: I don't think these are really needed
608 as the gsp and the offset are fixed no ? */
609 s390_amode *counter; /* dispatch counter */
610 s390_amode *fail_addr;
611 } evcheck;
612 struct {
613 /* No fields. The address of the counter to increment is
614 installed later, post-translation, by patching it in,
615 as it is not known at translation time. */
616 } profinc;
617
sewardj2019a972011-03-07 16:04:07 +0000618 } variant;
619} s390_insn;
620
621s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
622s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
623s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
floriancec3a8a2013-02-02 00:16:58 +0000624s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src);
sewardj2019a972011-03-07 16:04:07 +0000625s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
626 s390_opnd_RMI src);
627s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
628s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
629 s390_opnd_RMI op2);
630s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
631 s390_opnd_RMI op2, Bool signed_multiply);
632s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
633 s390_opnd_RMI op2, Bool signed_divide);
634s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
sewardj611b06e2011-03-24 08:57:29 +0000635s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
636 s390_opnd_RMI op);
sewardj2019a972011-03-07 16:04:07 +0000637s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
638 HReg old);
florian448cbba2012-06-06 02:26:01 +0000639s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
640 s390_amode *op2, HReg op3_high, HReg op3_low,
641 HReg old_high, HReg old_low, HReg scratch);
sewardj2019a972011-03-07 16:04:07 +0000642s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
643 s390_opnd_RMI opnd);
644s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
645s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
646s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
647 Bool signed_comparison);
sewardj2019a972011-03-07 16:04:07 +0000648s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
sewardj74142b82013-08-08 10:28:59 +0000649 const HChar *name, RetLoc rloc);
florian2c74d242012-09-12 19:38:42 +0000650s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
651 HReg op2, HReg op3);
652s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
653 HReg op2);
sewardj2019a972011-03-07 16:04:07 +0000654s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
florian2c74d242012-09-12 19:38:42 +0000655 HReg op);
sewardj2019a972011-03-07 16:04:07 +0000656s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
florian6dc90242012-12-21 21:43:00 +0000657s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
florian125e20d2012-10-07 15:42:37 +0000658 HReg op, s390_bfp_round_t);
sewardj2019a972011-03-07 16:04:07 +0000659s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
florian2c74d242012-09-12 19:38:42 +0000660 HReg dst_lo, HReg op2_hi, HReg op2_lo);
sewardja970c402011-04-28 18:38:42 +0000661s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
florian2c74d242012-09-12 19:38:42 +0000662 HReg dst_lo, HReg op_hi, HReg op_lo);
sewardj2019a972011-03-07 16:04:07 +0000663s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
664 HReg op1_lo, HReg op2_hi, HReg op2_lo);
florian6dc90242012-12-21 21:43:00 +0000665s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
sewardj2019a972011-03-07 16:04:07 +0000666 HReg dst_hi, HReg dst_lo, HReg op);
florian6dc90242012-12-21 21:43:00 +0000667s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t,
floriana2039c52013-12-10 16:51:15 +0000668 HReg dst_hi, HReg dst_lo, HReg op_hi,
669 HReg op_lo, s390_bfp_round_t);
florian12390202012-11-10 22:34:14 +0000670s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
671 HReg op2, HReg op3,
672 s390_dfp_round_t rounding_mode);
floriance9e3db2012-12-27 20:14:03 +0000673s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op);
florian1b901d42013-01-01 22:19:24 +0000674s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst,
675 HReg op2, HReg op3);
florian20c6bca2012-12-26 17:47:19 +0000676s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst,
677 HReg op1, HReg op2);
floriane38f6412012-12-21 17:32:12 +0000678s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
679 HReg op, s390_dfp_round_t);
florian5c539732013-02-14 14:27:12 +0000680s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
681 s390_dfp_round_t);
florian78d5ef72013-05-11 15:02:58 +0000682s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag,
683 HReg dst, HReg op, HReg r1, s390_dfp_round_t);
684s390_insn *s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag,
685 HReg dst_hi, HReg dst_lo, HReg op_hi,
686 HReg op_lo, HReg r1, s390_dfp_round_t);
floriane38f6412012-12-21 17:32:12 +0000687s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
688 HReg dst_lo, HReg op2_hi, HReg op2_lo,
689 HReg op3_hi, HReg op3_lo,
690 s390_dfp_round_t rounding_mode);
floriance9e3db2012-12-27 20:14:03 +0000691s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst,
692 HReg op_hi, HReg op_lo);
florian1b901d42013-01-01 22:19:24 +0000693s390_insn *s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t, HReg dst_hi,
694 HReg dst_lo, HReg op2,
695 HReg op3_hi, HReg op3_lo);
florian20c6bca2012-12-26 17:47:19 +0000696s390_insn *s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t, HReg dst,
697 HReg op1_hi, HReg op1_lo, HReg op2_hi,
698 HReg op2_lo);
floriane38f6412012-12-21 17:32:12 +0000699s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
700 HReg dst_hi, HReg dst_lo, HReg op);
701s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
floriana2039c52013-12-10 16:51:15 +0000702 HReg dst_hi, HReg dst_lo, HReg op_hi,
703 HReg op_lo, s390_dfp_round_t);
florian5c539732013-02-14 14:27:12 +0000704s390_insn *s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo,
705 HReg op2, HReg op3_hi, HReg op3_lo,
706 s390_dfp_round_t);
sewardja52e37e2011-04-28 18:48:06 +0000707s390_insn *s390_insn_mfence(void);
florianb93348d2012-12-27 00:59:43 +0000708s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value);
florianf85fe3e2012-12-22 02:28:25 +0000709s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
710 ULong value);
florian125e20d2012-10-07 15:42:37 +0000711s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
florianc8e4f562012-10-27 16:19:31 +0000712s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
sewardj2019a972011-03-07 16:04:07 +0000713
florian8844a632012-04-13 04:04:06 +0000714/* Five for translation chaining */
715s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
716 Bool to_fast_entry);
717s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
718s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
719 IRJumpKind kind);
720s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
721s390_insn *s390_insn_profinc(void);
722
sewardj2019a972011-03-07 16:04:07 +0000723const HChar *s390_insn_as_string(const s390_insn *);
724
725/*--------------------------------------------------------*/
726/* --- Interface exposed to VEX --- */
727/*--------------------------------------------------------*/
728
floriancacba8e2014-12-15 18:58:07 +0000729void ppS390AMode(const s390_amode *);
floriand8c64e02014-10-08 08:54:44 +0000730void ppS390Instr(const s390_insn *, Bool mode64);
sewardj2019a972011-03-07 16:04:07 +0000731void ppHRegS390(HReg);
732
733/* Some functions that insulate the register allocator from details
734 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +0000735void getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool );
florianb4df7682011-07-05 02:09:01 +0000736void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool );
floriand8c64e02014-10-08 08:54:44 +0000737Bool isMove_S390Instr ( const s390_insn *, HReg *, HReg * );
738Int emit_S390Instr ( Bool *, UChar *, Int, const s390_insn *, Bool,
florian8462d112014-09-24 15:18:09 +0000739 VexEndness, const void *, const void *,
740 const void *, const void *);
sewardj2019a972011-03-07 16:04:07 +0000741void getAllocableRegs_S390( Int *, HReg **, Bool );
742void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
743void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
floriancacba8e2014-12-15 18:58:07 +0000744HInstrArray *iselSB_S390 ( const IRSB *, VexArch, const VexArchInfo *,
floriandcd6d232015-01-02 17:32:21 +0000745 const VexAbiInfo *, Int, Int, Bool, Bool, Addr);
florian8844a632012-04-13 04:04:06 +0000746
747/* Return the number of bytes of code needed for an event check */
sewardj9b769162014-07-24 12:42:03 +0000748Int evCheckSzB_S390(VexEndness endness_host);
florian8844a632012-04-13 04:04:06 +0000749
750/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +0000751VexInvalRange chainXDirect_S390(VexEndness endness_host,
752 void *place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +0000753 const void *disp_cp_chain_me_EXPECTED,
754 const void *place_to_jump_to);
florian8844a632012-04-13 04:04:06 +0000755
sewardj9b769162014-07-24 12:42:03 +0000756VexInvalRange unchainXDirect_S390(VexEndness endness_host,
757 void *place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +0000758 const void *place_to_jump_to_EXPECTED,
759 const void *disp_cp_chain_me);
florian8844a632012-04-13 04:04:06 +0000760
761/* Patch the counter location into an existing ProfInc point. */
sewardj9b769162014-07-24 12:42:03 +0000762VexInvalRange patchProfInc_S390(VexEndness endness_host,
763 void *code_to_patch,
florian7d6f81d2014-09-22 21:43:37 +0000764 const ULong *location_of_counter);
sewardj2019a972011-03-07 16:04:07 +0000765
766/* KLUDGE: See detailled comment in host_s390_defs.c. */
florianf26994a2012-04-21 03:34:54 +0000767extern UInt s390_host_hwcaps;
sewardj2019a972011-03-07 16:04:07 +0000768
769/* Convenience macros to test installed facilities */
sewardj652b56a2011-04-13 15:38:17 +0000770#define s390_host_has_ldisp \
florianf26994a2012-04-21 03:34:54 +0000771 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
sewardj2019a972011-03-07 16:04:07 +0000772#define s390_host_has_eimm \
florianf26994a2012-04-21 03:34:54 +0000773 (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
sewardj2019a972011-03-07 16:04:07 +0000774#define s390_host_has_gie \
florianf26994a2012-04-21 03:34:54 +0000775 (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
sewardj2019a972011-03-07 16:04:07 +0000776#define s390_host_has_dfp \
florianf26994a2012-04-21 03:34:54 +0000777 (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
sewardjd07b8562011-04-27 11:58:22 +0000778#define s390_host_has_fgx \
florianf26994a2012-04-21 03:34:54 +0000779 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
florian9af37692012-01-15 21:01:16 +0000780#define s390_host_has_etf2 \
florianf26994a2012-04-21 03:34:54 +0000781 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
florian90ece042012-04-21 15:41:51 +0000782#define s390_host_has_stfle \
783 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
florian79bee4b2012-05-03 01:30:48 +0000784#define s390_host_has_etf3 \
785 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
floriana4c36692012-08-26 04:22:33 +0000786#define s390_host_has_stckf \
787 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
florian60b665b2012-08-30 20:28:00 +0000788#define s390_host_has_fpext \
789 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
florianaec8e052012-12-09 17:26:32 +0000790#define s390_host_has_lsc \
791 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
florian78d5ef72013-05-11 15:02:58 +0000792#define s390_host_has_pfpo \
793 (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO))
sewardj2019a972011-03-07 16:04:07 +0000794
795#endif /* ndef __VEX_HOST_S390_DEFS_H */
796
797/*---------------------------------------------------------------*/
798/*--- end host_s390_defs.h ---*/
799/*---------------------------------------------------------------*/