blob: 2e93b2fd6a8ee3bc0414d985aebdd41445152706 [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
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
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 */
39
40/* --------- Registers --------- */
41const HChar *s390_hreg_as_string(HReg);
42
sewardj2019a972011-03-07 16:04:07 +000043/* Dedicated registers */
44HReg s390_hreg_guest_state_pointer(void);
45
46
47/* Given the index of a function argument, return the number of the
48 general purpose register in which it is being passed. Arguments are
49 counted 0, 1, 2, ... and they are being passed in r2, r3, r4, ... */
florianffbd84d2012-12-09 02:06:29 +000050static __inline__ UInt
51s390_gprno_from_arg_index(UInt ix)
sewardj2019a972011-03-07 16:04:07 +000052{
53 return ix + 2;
54}
55
56/* --------- Memory address expressions (amodes). --------- */
57
58/* These are the address modes:
59 (1) b12: base register + 12-bit unsigned offset (e.g. RS)
60 (2) b20: base register + 20-bit signed offset (e.g. RSY)
61 (3) bx12: base register + index register + 12-bit unsigned offset (e.g. RX)
62 (4) bx20: base register + index register + 20-bit signed offset (e.g. RXY)
63 fixs390: There is also pc-relative stuff.. e.g. LARL
64*/
65
66typedef enum {
67 S390_AMODE_B12,
68 S390_AMODE_B20,
69 S390_AMODE_BX12,
70 S390_AMODE_BX20
71} s390_amode_t;
72
florianb4df7682011-07-05 02:09:01 +000073typedef struct {
sewardj2019a972011-03-07 16:04:07 +000074 s390_amode_t tag;
75 HReg b;
76 HReg x; /* hregNumber(x) == 0 for S390_AMODE_B12/B20 kinds */
77 Int d; /* 12 bit unsigned or 20 bit signed */
78} s390_amode;
79
80
81s390_amode *s390_amode_b12(Int d, HReg b);
82s390_amode *s390_amode_b20(Int d, HReg b);
83s390_amode *s390_amode_bx12(Int d, HReg b, HReg x);
84s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
85s390_amode *s390_amode_for_guest_state(Int d);
86Bool s390_amode_is_sane(const s390_amode *);
sewardj2019a972011-03-07 16:04:07 +000087
88const HChar *s390_amode_as_string(const s390_amode *);
89
sewardj2019a972011-03-07 16:04:07 +000090/* ------------- 2nd (right) operand of binary operation ---------------- */
91
92typedef enum {
93 S390_OPND_REG,
94 S390_OPND_IMMEDIATE,
95 S390_OPND_AMODE
96} s390_opnd_t;
97
98
99/* Naming convention for operand locations:
100 R - GPR
101 I - immediate value
102 M - memory (any Amode may be used)
103*/
104
105/* An operand that is either in a GPR or is addressable via a BX20 amode */
106typedef struct {
107 s390_opnd_t tag;
108 union {
109 HReg reg;
110 s390_amode *am;
111 ULong imm;
112 } variant;
113} s390_opnd_RMI;
114
115
116/* The kind of instructions */
117typedef enum {
118 S390_INSN_LOAD, /* load register from memory */
119 S390_INSN_STORE, /* store register to memory */
120 S390_INSN_MOVE, /* from register to register */
121 S390_INSN_COND_MOVE, /* conditonal "move" to register */
122 S390_INSN_LOAD_IMMEDIATE,
123 S390_INSN_ALU,
124 S390_INSN_MUL, /* n-bit operands; 2n-bit result */
125 S390_INSN_DIV, /* 2n-bit dividend; n-bit divisor; n-bit quot/rem */
126 S390_INSN_DIVS, /* n-bit dividend; n-bit divisor; n-bit quot/rem */
sewardj611b06e2011-03-24 08:57:29 +0000127 S390_INSN_CLZ, /* count left-most zeroes */
sewardj2019a972011-03-07 16:04:07 +0000128 S390_INSN_UNOP,
129 S390_INSN_TEST, /* test operand and set cc */
130 S390_INSN_CC2BOOL,/* convert condition code to 0/1 */
131 S390_INSN_COMPARE,
sewardj2019a972011-03-07 16:04:07 +0000132 S390_INSN_HELPER_CALL,
133 S390_INSN_CAS, /* compare and swap */
florian448cbba2012-06-06 02:26:01 +0000134 S390_INSN_CDAS, /* compare double and swap */
floriancc491a62012-09-10 23:44:37 +0000135 S390_INSN_BFP_BINOP, /* Binary floating point */
sewardj2019a972011-03-07 16:04:07 +0000136 S390_INSN_BFP_UNOP,
137 S390_INSN_BFP_TRIOP,
138 S390_INSN_BFP_COMPARE,
florian9fcff4c2012-09-10 03:09:04 +0000139 S390_INSN_BFP_CONVERT,
florian12390202012-11-10 22:34:14 +0000140 S390_INSN_DFP_BINOP, /* Decimal floating point */
florianad43b3a2012-02-20 15:01:14 +0000141 S390_INSN_MFENCE,
florian09bbba82012-12-11 04:09:43 +0000142 S390_INSN_MZERO, /* Assign zero to a memory location */
florian8844a632012-04-13 04:04:06 +0000143 S390_INSN_GADD, /* Add a value to a guest register */
florian125e20d2012-10-07 15:42:37 +0000144 S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
florianc8e4f562012-10-27 16:19:31 +0000145 S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
florian8844a632012-04-13 04:04:06 +0000146 /* The following 5 insns are mandated by translation chaining */
147 S390_INSN_XDIRECT, /* direct transfer to guest address */
148 S390_INSN_XINDIR, /* indirect transfer to guest address */
149 S390_INSN_XASSISTED, /* assisted transfer to guest address */
150 S390_INSN_EVCHECK, /* Event check */
151 S390_INSN_PROFINC /* 64-bit profile counter increment */
sewardj2019a972011-03-07 16:04:07 +0000152} s390_insn_tag;
153
154
155/* The kind of ALU instructions */
156typedef enum {
157 S390_ALU_ADD,
158 S390_ALU_SUB,
159 S390_ALU_MUL, /* n-bit operands; result is lower n-bit of product */
160 S390_ALU_AND,
161 S390_ALU_OR,
162 S390_ALU_XOR,
163 S390_ALU_LSH,
164 S390_ALU_RSH,
165 S390_ALU_RSHA /* arithmetic */
166} s390_alu_t;
167
168
169/* The kind of unary integer operations */
170typedef enum {
171 S390_ZERO_EXTEND_8,
172 S390_ZERO_EXTEND_16,
173 S390_ZERO_EXTEND_32,
174 S390_SIGN_EXTEND_8,
175 S390_SIGN_EXTEND_16,
176 S390_SIGN_EXTEND_32,
177 S390_NEGATE
178} s390_unop_t;
179
180/* The kind of ternary BFP operations */
181typedef enum {
182 S390_BFP_MADD,
183 S390_BFP_MSUB,
184} s390_bfp_triop_t;
185
186/* The kind of binary BFP operations */
187typedef enum {
188 S390_BFP_ADD,
189 S390_BFP_SUB,
190 S390_BFP_MUL,
191 S390_BFP_DIV
192} s390_bfp_binop_t;
193
sewardj2019a972011-03-07 16:04:07 +0000194/* The kind of unary BFP operations */
195typedef enum {
196 S390_BFP_ABS,
197 S390_BFP_NABS,
198 S390_BFP_NEG,
florian9fcff4c2012-09-10 03:09:04 +0000199 S390_BFP_SQRT
200} s390_bfp_unop_t;
201
202/* Type conversion operations: to and/or from floating point */
203typedef enum {
sewardj2019a972011-03-07 16:04:07 +0000204 S390_BFP_I32_TO_F32,
205 S390_BFP_I32_TO_F64,
206 S390_BFP_I32_TO_F128,
207 S390_BFP_I64_TO_F32,
208 S390_BFP_I64_TO_F64,
209 S390_BFP_I64_TO_F128,
florian1c8f7ff2012-09-01 00:12:11 +0000210 S390_BFP_U32_TO_F32,
211 S390_BFP_U32_TO_F64,
212 S390_BFP_U32_TO_F128,
213 S390_BFP_U64_TO_F32,
214 S390_BFP_U64_TO_F64,
215 S390_BFP_U64_TO_F128,
sewardj2019a972011-03-07 16:04:07 +0000216 S390_BFP_F32_TO_I32,
217 S390_BFP_F32_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000218 S390_BFP_F32_TO_U32,
219 S390_BFP_F32_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000220 S390_BFP_F32_TO_F64,
221 S390_BFP_F32_TO_F128,
222 S390_BFP_F64_TO_I32,
223 S390_BFP_F64_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000224 S390_BFP_F64_TO_U32,
225 S390_BFP_F64_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000226 S390_BFP_F64_TO_F32,
227 S390_BFP_F64_TO_F128,
228 S390_BFP_F128_TO_I32,
229 S390_BFP_F128_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000230 S390_BFP_F128_TO_U32,
231 S390_BFP_F128_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000232 S390_BFP_F128_TO_F32,
233 S390_BFP_F128_TO_F64
florian9fcff4c2012-09-10 03:09:04 +0000234} s390_conv_t;
sewardj2019a972011-03-07 16:04:07 +0000235
236
florian12390202012-11-10 22:34:14 +0000237/* The kind of binary DFP operations */
238typedef enum {
239 S390_DFP_ADD,
240 S390_DFP_SUB,
241 S390_DFP_MUL,
242 S390_DFP_DIV
243} s390_dfp_binop_t;
244
245
sewardj2019a972011-03-07 16:04:07 +0000246/* Condition code. The encoding of the enumerators matches the value of
247 the mask field in the various branch opcodes. */
248typedef enum {
249 S390_CC_NEVER= 0,
250 S390_CC_OVFL = 1, /* overflow */
251 S390_CC_H = 2, /* A > B ; high */
252 S390_CC_NLE = 3, /* not low or equal */
253 S390_CC_L = 4, /* A < B ; low */
254 S390_CC_NHE = 5, /* not high or equal */
255 S390_CC_LH = 6, /* low or high */
256 S390_CC_NE = 7, /* A != B ; not zero */
257 S390_CC_E = 8, /* A == B ; zero */
258 S390_CC_NLH = 9, /* not low or high */
259 S390_CC_HE = 10, /* A >= B ; high or equal*/
260 S390_CC_NL = 11, /* not low */
261 S390_CC_LE = 12, /* A <= B ; low or equal */
262 S390_CC_NH = 13, /* not high */
263 S390_CC_NO = 14, /* not overflow */
264 S390_CC_ALWAYS = 15
265} s390_cc_t;
266
267
florianc8e4f562012-10-27 16:19:31 +0000268/* BFP Rounding mode as it is encoded in the m3 field of certain
sewardj2019a972011-03-07 16:04:07 +0000269 instructions (e.g. CFEBR) */
270typedef enum {
florian125e20d2012-10-07 15:42:37 +0000271 S390_BFP_ROUND_PER_FPC = 0,
272 S390_BFP_ROUND_NEAREST_AWAY = 1,
florian847684d2012-09-05 04:19:09 +0000273 /* 2 is not allowed */
florian125e20d2012-10-07 15:42:37 +0000274 S390_BFP_ROUND_PREPARE_SHORT = 3,
275 S390_BFP_ROUND_NEAREST_EVEN = 4,
276 S390_BFP_ROUND_ZERO = 5,
277 S390_BFP_ROUND_POSINF = 6,
278 S390_BFP_ROUND_NEGINF = 7
279} s390_bfp_round_t;
sewardj2019a972011-03-07 16:04:07 +0000280
281
florianc8e4f562012-10-27 16:19:31 +0000282/* BFP Rounding mode as it is encoded in bits [29:31] of the FPC register.
florian2c74d242012-09-12 19:38:42 +0000283 Only rounding modes 0..3 are universally supported. Others require
284 additional hardware facilities. */
285typedef enum {
florian125e20d2012-10-07 15:42:37 +0000286 S390_FPC_BFP_ROUND_NEAREST_EVEN = 0,
287 S390_FPC_BFP_ROUND_ZERO = 1,
288 S390_FPC_BFP_ROUND_POSINF = 2,
289 S390_FPC_BFP_ROUND_NEGINF = 3,
florian2c74d242012-09-12 19:38:42 +0000290 /* 4,5,6 are not allowed */
florian125e20d2012-10-07 15:42:37 +0000291 S390_FPC_BFP_ROUND_PREPARE_SHORT = 7
292} s390_fpc_bfp_round_t;
florian2c74d242012-09-12 19:38:42 +0000293
294
florianc8e4f562012-10-27 16:19:31 +0000295/* DFP Rounding mode as it is encoded in the m3 field of certain
296 instructions (e.g. CGDTR) */
297typedef enum {
298 S390_DFP_ROUND_PER_FPC_0 = 0,
299 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1 = 1,
300 S390_DFP_ROUND_PER_FPC_2 = 2,
301 S390_DFP_ROUND_PREPARE_SHORT_3 = 3,
302 S390_DFP_ROUND_NEAREST_EVEN_4 = 4,
303 S390_DFP_ROUND_ZERO_5 = 5,
304 S390_DFP_ROUND_POSINF_6 = 6,
305 S390_DFP_ROUND_NEGINF_7 = 7,
306 S390_DFP_ROUND_NEAREST_EVEN_8 = 8,
307 S390_DFP_ROUND_ZERO_9 = 9,
308 S390_DFP_ROUND_POSINF_10 = 10,
309 S390_DFP_ROUND_NEGINF_11 = 11,
310 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12 = 12,
311 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0 = 13,
312 S390_DFP_ROUND_AWAY_0 = 14,
313 S390_DFP_ROUND_PREPARE_SHORT_15 = 15
314} s390_dfp_round_t;
315
316
317/* DFP Rounding mode as it is encoded in bits [25:27] of the FPC register. */
318typedef enum {
319 S390_FPC_DFP_ROUND_NEAREST_EVEN = 0,
320 S390_FPC_DFP_ROUND_ZERO = 1,
321 S390_FPC_DFP_ROUND_POSINF = 2,
322 S390_FPC_DFP_ROUND_NEGINF = 3,
323 S390_FPC_DFP_ROUND_NEAREST_AWAY_0 = 4,
324 S390_FPC_DFP_ROUND_NEAREST_TOWARD_0 = 5,
325 S390_FPC_DFP_ROUND_AWAY_ZERO = 6,
326 S390_FPC_DFP_ROUND_PREPARE_SHORT = 7
327} s390_fpc_dfp_round_t;
328
329
sewardj2019a972011-03-07 16:04:07 +0000330/* Invert the condition code */
331static __inline__ s390_cc_t
332s390_cc_invert(s390_cc_t cond)
333{
334 return S390_CC_ALWAYS - cond;
335}
336
337
florianb4df7682011-07-05 02:09:01 +0000338typedef struct {
sewardj2019a972011-03-07 16:04:07 +0000339 s390_insn_tag tag;
floriancc491a62012-09-10 23:44:37 +0000340 /* Usually, this is the size of the result of an operation.
341 Exceptions are:
342 - for comparisons it is the size of the operand
343 */
344 UChar size;
sewardj2019a972011-03-07 16:04:07 +0000345 union {
346 struct {
347 HReg dst;
348 s390_amode *src;
349 } load;
350 struct {
351 s390_amode *dst;
352 HReg src;
353 } store;
354 struct {
355 HReg dst;
356 HReg src;
357 } move;
358 struct {
359 s390_cc_t cond;
360 HReg dst;
361 s390_opnd_RMI src;
362 } cond_move;
363 struct {
364 HReg dst;
365 ULong value; /* not sign extended */
366 } load_immediate;
367 /* add, and, or, xor */
368 struct {
369 s390_alu_t tag;
370 HReg dst; /* op1 */
371 s390_opnd_RMI op2;
372 } alu;
373 struct {
374 Bool signed_multiply;
375 HReg dst_hi; /* r10 */
376 HReg dst_lo; /* also op1 r11 */
377 s390_opnd_RMI op2;
378 } mul;
379 struct {
380 Bool signed_divide;
381 HReg op1_hi; /* also remainder r10 */
382 HReg op1_lo; /* also quotient r11 */
383 s390_opnd_RMI op2;
384 } div;
385 struct {
386 HReg rem; /* remainder r10 */
387 HReg op1; /* also quotient r11 */
388 s390_opnd_RMI op2;
389 } divs;
390 struct {
sewardj611b06e2011-03-24 08:57:29 +0000391 HReg num_bits; /* number of leftmost '0' bits r10 */
392 HReg clobber; /* unspecified r11 */
sewardj2019a972011-03-07 16:04:07 +0000393 s390_opnd_RMI src;
sewardj611b06e2011-03-24 08:57:29 +0000394 } clz;
sewardj2019a972011-03-07 16:04:07 +0000395 struct {
396 s390_unop_t tag;
397 HReg dst;
398 s390_opnd_RMI src;
399 } unop;
400 struct {
401 Bool signed_comparison;
402 HReg src1;
403 s390_opnd_RMI src2;
404 } compare;
405 struct {
sewardj2019a972011-03-07 16:04:07 +0000406 s390_opnd_RMI src;
407 } test;
408 /* Convert the condition code to a boolean value. */
409 struct {
410 s390_cc_t cond;
411 HReg dst;
412 } cc2bool;
413 struct {
414 HReg op1;
415 s390_amode *op2;
416 HReg op3;
417 HReg old_mem;
418 } cas;
florian448cbba2012-06-06 02:26:01 +0000419 struct {
420 HReg op1_high;
421 HReg op1_low;
422 s390_amode *op2;
423 HReg op3_high;
424 HReg op3_low;
425 HReg old_mem_high;
426 HReg old_mem_low;
427 HReg scratch;
428 } cdas;
sewardj2019a972011-03-07 16:04:07 +0000429 /* Pseudo-insn for representing a helper call.
430 TARGET is the absolute address of the helper function
431 NUM_ARGS says how many arguments are being passed.
432 All arguments have integer type and are being passed according to ABI,
433 i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
434 passed in r2 and so forth. */
435 struct {
florian1ff47562012-10-21 02:09:51 +0000436 s390_cc_t cond;
437 Addr64 target;
438 UInt num_args;
439 HReg dst; /* if not INVALID_HREG, put return value here */
440 const HChar *name; /* callee's name (for debugging) */
sewardj2019a972011-03-07 16:04:07 +0000441 } helper_call;
floriancc491a62012-09-10 23:44:37 +0000442
443 /* Floating point instructions (including conversion to/from floating
444 point
445
446 128-bit floating point requires register pairs. As the registers
447 in a register pair cannot be chosen independently it would suffice
448 to store only one register of the pair in order to represent it.
449 We chose not to do that as being explicit about all registers
450 helps with debugging and does not require special handling in
florian2c74d242012-09-12 19:38:42 +0000451 e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
floriancc491a62012-09-10 23:44:37 +0000452 the "other" register in a pair if it is implicit.
453
454 The convention for all fp s390_insn is that the _hi register will
455 be used to store the result / operand of a 32/64-bit operation.
456 The _hi register holds the 8 bytes of HIgher significance of a
457 128-bit value (hence the suffix). However, it is the lower numbered
458 register of a register pair. POP says that the lower numbered
459 register is used to identify the pair in an insn encoding. So,
460 when an insn is emitted, only the _hi registers need to be looked
461 at. Nothing special is needed for 128-bit BFP which is nice.
462 */
463
464 /* There are currently no ternary 128-bit BFP operations. */
sewardj2019a972011-03-07 16:04:07 +0000465 struct {
466 s390_bfp_triop_t tag;
floriancc491a62012-09-10 23:44:37 +0000467 HReg dst;
468 HReg op2;
469 HReg op3;
sewardj2019a972011-03-07 16:04:07 +0000470 } bfp_triop;
471 struct {
472 s390_bfp_binop_t tag;
floriancc491a62012-09-10 23:44:37 +0000473 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
474 HReg dst_lo; /* 128-bit result low part */
475 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
476 HReg op2_lo; /* 128-bit operand low part */
sewardj2019a972011-03-07 16:04:07 +0000477 } bfp_binop;
478 struct {
sewardj2019a972011-03-07 16:04:07 +0000479 s390_bfp_unop_t tag;
floriancc491a62012-09-10 23:44:37 +0000480 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
481 HReg dst_lo; /* 128-bit result low part */
482 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
483 HReg op_lo; /* 128-bit operand low part */
484 } bfp_unop;
sewardj2019a972011-03-07 16:04:07 +0000485 struct {
florian9fcff4c2012-09-10 03:09:04 +0000486 s390_conv_t tag;
florian125e20d2012-10-07 15:42:37 +0000487 s390_bfp_round_t rounding_mode;
florian9fcff4c2012-09-10 03:09:04 +0000488 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
489 HReg dst_lo; /* 128-bit result low part */
490 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
491 HReg op_lo; /* 128-bit operand low part */
floriancc491a62012-09-10 23:44:37 +0000492 } bfp_convert;
florian9fcff4c2012-09-10 03:09:04 +0000493 struct {
floriancc491a62012-09-10 23:44:37 +0000494 HReg dst; /* condition code in s390 encoding */
495 HReg op1_hi; /* 128-bit operand high part; 32/64-bit opnd */
496 HReg op1_lo; /* 128-bit operand low part */
497 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
498 HReg op2_lo; /* 128-bit operand low part */
499 } bfp_compare;
florian12390202012-11-10 22:34:14 +0000500 struct {
501 s390_dfp_binop_t tag;
502 HReg dst_hi; /* 128-bit result high part; 64-bit result */
503 HReg dst_lo; /* 128-bit result low part */
504 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
505 HReg op2_lo; /* 128-bit operand low part */
506 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
507 HReg op3_lo; /* 128-bit operand low part */
508 s390_dfp_round_t rounding_mode;
509 } dfp_binop;
floriancc491a62012-09-10 23:44:37 +0000510
511 /* Miscellaneous */
florianad43b3a2012-02-20 15:01:14 +0000512 struct {
florian09bbba82012-12-11 04:09:43 +0000513 s390_amode *dst;
514 } mzero;
florianad43b3a2012-02-20 15:01:14 +0000515 struct {
516 UInt offset;
517 UChar delta;
518 ULong value; /* for debugging only */
519 } gadd;
florian2c74d242012-09-12 19:38:42 +0000520 struct {
521 HReg mode;
florian125e20d2012-10-07 15:42:37 +0000522 } set_fpc_bfprm;
florianc8e4f562012-10-27 16:19:31 +0000523 struct {
524 HReg mode;
525 } set_fpc_dfprm;
florian8844a632012-04-13 04:04:06 +0000526
527 /* The next 5 entries are generic to support translation chaining */
528
529 /* Update the guest IA value, then exit requesting to chain
530 to it. May be conditional. */
531 struct {
532 s390_cc_t cond;
533 Bool to_fast_entry; /* chain to the what entry point? */
534 Addr64 dst; /* next guest address */
535 s390_amode *guest_IA;
536 } xdirect;
537 /* Boring transfer to a guest address not known at JIT time.
538 Not chainable. May be conditional. */
539 struct {
540 s390_cc_t cond;
541 HReg dst;
542 s390_amode *guest_IA;
543 } xindir;
544 /* Assisted transfer to a guest address, most general case.
545 Not chainable. May be conditional. */
546 struct {
547 s390_cc_t cond;
548 IRJumpKind kind;
549 HReg dst;
550 s390_amode *guest_IA;
551 } xassisted;
552 struct {
553 /* fixs390: I don't think these are really needed
554 as the gsp and the offset are fixed no ? */
555 s390_amode *counter; /* dispatch counter */
556 s390_amode *fail_addr;
557 } evcheck;
558 struct {
559 /* No fields. The address of the counter to increment is
560 installed later, post-translation, by patching it in,
561 as it is not known at translation time. */
562 } profinc;
563
sewardj2019a972011-03-07 16:04:07 +0000564 } variant;
565} s390_insn;
566
567s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
568s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
569s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
570s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
571 s390_opnd_RMI src);
572s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
573s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
574 s390_opnd_RMI op2);
575s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
576 s390_opnd_RMI op2, Bool signed_multiply);
577s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
578 s390_opnd_RMI op2, Bool signed_divide);
579s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
sewardj611b06e2011-03-24 08:57:29 +0000580s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
581 s390_opnd_RMI op);
sewardj2019a972011-03-07 16:04:07 +0000582s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
583 HReg old);
florian448cbba2012-06-06 02:26:01 +0000584s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
585 s390_amode *op2, HReg op3_high, HReg op3_low,
586 HReg old_high, HReg old_low, HReg scratch);
sewardj2019a972011-03-07 16:04:07 +0000587s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
588 s390_opnd_RMI opnd);
589s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
590s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
591s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
592 Bool signed_comparison);
sewardj2019a972011-03-07 16:04:07 +0000593s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
florian1ff47562012-10-21 02:09:51 +0000594 const HChar *name, HReg dst);
florian2c74d242012-09-12 19:38:42 +0000595s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
596 HReg op2, HReg op3);
597s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
598 HReg op2);
sewardj2019a972011-03-07 16:04:07 +0000599s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
florian2c74d242012-09-12 19:38:42 +0000600 HReg op);
sewardj2019a972011-03-07 16:04:07 +0000601s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
florian9fcff4c2012-09-10 03:09:04 +0000602s390_insn *s390_insn_bfp_convert(UChar size, s390_conv_t tag, HReg dst,
florian125e20d2012-10-07 15:42:37 +0000603 HReg op, s390_bfp_round_t);
sewardj2019a972011-03-07 16:04:07 +0000604s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
florian2c74d242012-09-12 19:38:42 +0000605 HReg dst_lo, HReg op2_hi, HReg op2_lo);
sewardja970c402011-04-28 18:38:42 +0000606s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
florian2c74d242012-09-12 19:38:42 +0000607 HReg dst_lo, HReg op_hi, HReg op_lo);
sewardj2019a972011-03-07 16:04:07 +0000608s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
609 HReg op1_lo, HReg op2_hi, HReg op2_lo);
florian9fcff4c2012-09-10 03:09:04 +0000610s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_conv_t,
sewardj2019a972011-03-07 16:04:07 +0000611 HReg dst_hi, HReg dst_lo, HReg op);
florian9fcff4c2012-09-10 03:09:04 +0000612s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_conv_t,
sewardj2019a972011-03-07 16:04:07 +0000613 HReg dst, HReg op_hi, HReg op_lo,
florian125e20d2012-10-07 15:42:37 +0000614 s390_bfp_round_t);
florian12390202012-11-10 22:34:14 +0000615s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
616 HReg op2, HReg op3,
617 s390_dfp_round_t rounding_mode);
sewardja52e37e2011-04-28 18:48:06 +0000618s390_insn *s390_insn_mfence(void);
florian09bbba82012-12-11 04:09:43 +0000619s390_insn *s390_insn_mzero(UChar size, s390_amode *dst);
florianad43b3a2012-02-20 15:01:14 +0000620s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value);
florian125e20d2012-10-07 15:42:37 +0000621s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
florianc8e4f562012-10-27 16:19:31 +0000622s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
sewardj2019a972011-03-07 16:04:07 +0000623
florian8844a632012-04-13 04:04:06 +0000624/* Five for translation chaining */
625s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
626 Bool to_fast_entry);
627s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
628s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
629 IRJumpKind kind);
630s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
631s390_insn *s390_insn_profinc(void);
632
sewardj2019a972011-03-07 16:04:07 +0000633const HChar *s390_insn_as_string(const s390_insn *);
634
635/*--------------------------------------------------------*/
636/* --- Interface exposed to VEX --- */
637/*--------------------------------------------------------*/
638
florianb4df7682011-07-05 02:09:01 +0000639void ppS390AMode(s390_amode *);
640void ppS390Instr(s390_insn *, Bool mode64);
sewardj2019a972011-03-07 16:04:07 +0000641void ppHRegS390(HReg);
642
643/* Some functions that insulate the register allocator from details
644 of the underlying instruction set. */
florianb4df7682011-07-05 02:09:01 +0000645void getRegUsage_S390Instr( HRegUsage *, s390_insn *, Bool );
646void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool );
647Bool isMove_S390Instr ( s390_insn *, HReg *, HReg * );
florian8844a632012-04-13 04:04:06 +0000648Int emit_S390Instr ( Bool *, UChar *, Int, s390_insn *, Bool,
649 void *, void *, void *, void *);
sewardj2019a972011-03-07 16:04:07 +0000650void getAllocableRegs_S390( Int *, HReg **, Bool );
651void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
652void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
florianb4df7682011-07-05 02:09:01 +0000653s390_insn *directReload_S390 ( s390_insn *, HReg, Short );
florian8844a632012-04-13 04:04:06 +0000654HInstrArray *iselSB_S390 ( IRSB *, VexArch, VexArchInfo *, VexAbiInfo *,
655 Int, Int, Bool, Bool, Addr64);
656
657/* Return the number of bytes of code needed for an event check */
658Int evCheckSzB_S390(void);
659
660/* Perform a chaining and unchaining of an XDirect jump. */
661VexInvalRange chainXDirect_S390(void *place_to_chain,
662 void *disp_cp_chain_me_EXPECTED,
663 void *place_to_jump_to);
664
665VexInvalRange unchainXDirect_S390(void *place_to_unchain,
666 void *place_to_jump_to_EXPECTED,
667 void *disp_cp_chain_me);
668
669/* Patch the counter location into an existing ProfInc point. */
670VexInvalRange patchProfInc_S390(void *code_to_patch,
671 ULong *location_of_counter);
sewardj2019a972011-03-07 16:04:07 +0000672
673/* KLUDGE: See detailled comment in host_s390_defs.c. */
florianf26994a2012-04-21 03:34:54 +0000674extern UInt s390_host_hwcaps;
sewardj2019a972011-03-07 16:04:07 +0000675
676/* Convenience macros to test installed facilities */
sewardj652b56a2011-04-13 15:38:17 +0000677#define s390_host_has_ldisp \
florianf26994a2012-04-21 03:34:54 +0000678 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
sewardj2019a972011-03-07 16:04:07 +0000679#define s390_host_has_eimm \
florianf26994a2012-04-21 03:34:54 +0000680 (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
sewardj2019a972011-03-07 16:04:07 +0000681#define s390_host_has_gie \
florianf26994a2012-04-21 03:34:54 +0000682 (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
sewardj2019a972011-03-07 16:04:07 +0000683#define s390_host_has_dfp \
florianf26994a2012-04-21 03:34:54 +0000684 (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
sewardjd07b8562011-04-27 11:58:22 +0000685#define s390_host_has_fgx \
florianf26994a2012-04-21 03:34:54 +0000686 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
florian9af37692012-01-15 21:01:16 +0000687#define s390_host_has_etf2 \
florianf26994a2012-04-21 03:34:54 +0000688 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
florian90ece042012-04-21 15:41:51 +0000689#define s390_host_has_stfle \
690 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
florian79bee4b2012-05-03 01:30:48 +0000691#define s390_host_has_etf3 \
692 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
floriana4c36692012-08-26 04:22:33 +0000693#define s390_host_has_stckf \
694 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
florian60b665b2012-08-30 20:28:00 +0000695#define s390_host_has_fpext \
696 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
florianaec8e052012-12-09 17:26:32 +0000697#define s390_host_has_lsc \
698 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
sewardj2019a972011-03-07 16:04:07 +0000699
700#endif /* ndef __VEX_HOST_S390_DEFS_H */
701
702/*---------------------------------------------------------------*/
703/*--- end host_s390_defs.h ---*/
704/*---------------------------------------------------------------*/