blob: 75e91c77dd35315117fd19481ec40769bd377486 [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 */
floriane38f6412012-12-21 17:32:12 +0000141 S390_INSN_DFP_COMPARE,
142 S390_INSN_DFP_CONVERT,
florianad43b3a2012-02-20 15:01:14 +0000143 S390_INSN_MFENCE,
florian09bbba82012-12-11 04:09:43 +0000144 S390_INSN_MZERO, /* Assign zero to a memory location */
florian8844a632012-04-13 04:04:06 +0000145 S390_INSN_GADD, /* Add a value to a guest register */
florian125e20d2012-10-07 15:42:37 +0000146 S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
florianc8e4f562012-10-27 16:19:31 +0000147 S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
florian8844a632012-04-13 04:04:06 +0000148 /* The following 5 insns are mandated by translation chaining */
149 S390_INSN_XDIRECT, /* direct transfer to guest address */
150 S390_INSN_XINDIR, /* indirect transfer to guest address */
151 S390_INSN_XASSISTED, /* assisted transfer to guest address */
152 S390_INSN_EVCHECK, /* Event check */
153 S390_INSN_PROFINC /* 64-bit profile counter increment */
sewardj2019a972011-03-07 16:04:07 +0000154} s390_insn_tag;
155
156
157/* The kind of ALU instructions */
158typedef enum {
159 S390_ALU_ADD,
160 S390_ALU_SUB,
161 S390_ALU_MUL, /* n-bit operands; result is lower n-bit of product */
162 S390_ALU_AND,
163 S390_ALU_OR,
164 S390_ALU_XOR,
165 S390_ALU_LSH,
166 S390_ALU_RSH,
167 S390_ALU_RSHA /* arithmetic */
168} s390_alu_t;
169
170
171/* The kind of unary integer operations */
172typedef enum {
173 S390_ZERO_EXTEND_8,
174 S390_ZERO_EXTEND_16,
175 S390_ZERO_EXTEND_32,
176 S390_SIGN_EXTEND_8,
177 S390_SIGN_EXTEND_16,
178 S390_SIGN_EXTEND_32,
179 S390_NEGATE
180} s390_unop_t;
181
182/* The kind of ternary BFP operations */
183typedef enum {
184 S390_BFP_MADD,
185 S390_BFP_MSUB,
186} s390_bfp_triop_t;
187
188/* The kind of binary BFP operations */
189typedef enum {
190 S390_BFP_ADD,
191 S390_BFP_SUB,
192 S390_BFP_MUL,
193 S390_BFP_DIV
194} s390_bfp_binop_t;
195
sewardj2019a972011-03-07 16:04:07 +0000196/* The kind of unary BFP operations */
197typedef enum {
198 S390_BFP_ABS,
199 S390_BFP_NABS,
200 S390_BFP_NEG,
florian9fcff4c2012-09-10 03:09:04 +0000201 S390_BFP_SQRT
202} s390_bfp_unop_t;
203
floriane38f6412012-12-21 17:32:12 +0000204/* Type conversion operations: to and/or from binary floating point */
florian9fcff4c2012-09-10 03:09:04 +0000205typedef enum {
sewardj2019a972011-03-07 16:04:07 +0000206 S390_BFP_I32_TO_F32,
207 S390_BFP_I32_TO_F64,
208 S390_BFP_I32_TO_F128,
209 S390_BFP_I64_TO_F32,
210 S390_BFP_I64_TO_F64,
211 S390_BFP_I64_TO_F128,
florian1c8f7ff2012-09-01 00:12:11 +0000212 S390_BFP_U32_TO_F32,
213 S390_BFP_U32_TO_F64,
214 S390_BFP_U32_TO_F128,
215 S390_BFP_U64_TO_F32,
216 S390_BFP_U64_TO_F64,
217 S390_BFP_U64_TO_F128,
sewardj2019a972011-03-07 16:04:07 +0000218 S390_BFP_F32_TO_I32,
219 S390_BFP_F32_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000220 S390_BFP_F32_TO_U32,
221 S390_BFP_F32_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000222 S390_BFP_F32_TO_F64,
223 S390_BFP_F32_TO_F128,
224 S390_BFP_F64_TO_I32,
225 S390_BFP_F64_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000226 S390_BFP_F64_TO_U32,
227 S390_BFP_F64_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000228 S390_BFP_F64_TO_F32,
229 S390_BFP_F64_TO_F128,
230 S390_BFP_F128_TO_I32,
231 S390_BFP_F128_TO_I64,
florian1c8f7ff2012-09-01 00:12:11 +0000232 S390_BFP_F128_TO_U32,
233 S390_BFP_F128_TO_U64,
sewardj2019a972011-03-07 16:04:07 +0000234 S390_BFP_F128_TO_F32,
235 S390_BFP_F128_TO_F64
florian9fcff4c2012-09-10 03:09:04 +0000236} s390_conv_t;
sewardj2019a972011-03-07 16:04:07 +0000237
floriane38f6412012-12-21 17:32:12 +0000238/* Type conversion operations: to and/or from decimal floating point */
239typedef enum {
240 S390_DFP_D32_TO_D64,
241 S390_DFP_D64_TO_D32,
242 S390_DFP_D64_TO_D128,
243 S390_DFP_D128_TO_D64
244} s390_dfp_conv_t;
sewardj2019a972011-03-07 16:04:07 +0000245
florian12390202012-11-10 22:34:14 +0000246/* The kind of binary DFP operations */
247typedef enum {
248 S390_DFP_ADD,
249 S390_DFP_SUB,
250 S390_DFP_MUL,
251 S390_DFP_DIV
252} s390_dfp_binop_t;
253
254
sewardj2019a972011-03-07 16:04:07 +0000255/* Condition code. The encoding of the enumerators matches the value of
256 the mask field in the various branch opcodes. */
257typedef enum {
258 S390_CC_NEVER= 0,
259 S390_CC_OVFL = 1, /* overflow */
260 S390_CC_H = 2, /* A > B ; high */
261 S390_CC_NLE = 3, /* not low or equal */
262 S390_CC_L = 4, /* A < B ; low */
263 S390_CC_NHE = 5, /* not high or equal */
264 S390_CC_LH = 6, /* low or high */
265 S390_CC_NE = 7, /* A != B ; not zero */
266 S390_CC_E = 8, /* A == B ; zero */
267 S390_CC_NLH = 9, /* not low or high */
268 S390_CC_HE = 10, /* A >= B ; high or equal*/
269 S390_CC_NL = 11, /* not low */
270 S390_CC_LE = 12, /* A <= B ; low or equal */
271 S390_CC_NH = 13, /* not high */
272 S390_CC_NO = 14, /* not overflow */
273 S390_CC_ALWAYS = 15
274} s390_cc_t;
275
276
florianc8e4f562012-10-27 16:19:31 +0000277/* BFP Rounding mode as it is encoded in the m3 field of certain
sewardj2019a972011-03-07 16:04:07 +0000278 instructions (e.g. CFEBR) */
279typedef enum {
florian125e20d2012-10-07 15:42:37 +0000280 S390_BFP_ROUND_PER_FPC = 0,
281 S390_BFP_ROUND_NEAREST_AWAY = 1,
florian847684d2012-09-05 04:19:09 +0000282 /* 2 is not allowed */
florian125e20d2012-10-07 15:42:37 +0000283 S390_BFP_ROUND_PREPARE_SHORT = 3,
284 S390_BFP_ROUND_NEAREST_EVEN = 4,
285 S390_BFP_ROUND_ZERO = 5,
286 S390_BFP_ROUND_POSINF = 6,
287 S390_BFP_ROUND_NEGINF = 7
288} s390_bfp_round_t;
sewardj2019a972011-03-07 16:04:07 +0000289
290
florianc8e4f562012-10-27 16:19:31 +0000291/* BFP Rounding mode as it is encoded in bits [29:31] of the FPC register.
florian2c74d242012-09-12 19:38:42 +0000292 Only rounding modes 0..3 are universally supported. Others require
293 additional hardware facilities. */
294typedef enum {
florian125e20d2012-10-07 15:42:37 +0000295 S390_FPC_BFP_ROUND_NEAREST_EVEN = 0,
296 S390_FPC_BFP_ROUND_ZERO = 1,
297 S390_FPC_BFP_ROUND_POSINF = 2,
298 S390_FPC_BFP_ROUND_NEGINF = 3,
florian2c74d242012-09-12 19:38:42 +0000299 /* 4,5,6 are not allowed */
florian125e20d2012-10-07 15:42:37 +0000300 S390_FPC_BFP_ROUND_PREPARE_SHORT = 7
301} s390_fpc_bfp_round_t;
florian2c74d242012-09-12 19:38:42 +0000302
303
florianc8e4f562012-10-27 16:19:31 +0000304/* DFP Rounding mode as it is encoded in the m3 field of certain
305 instructions (e.g. CGDTR) */
306typedef enum {
307 S390_DFP_ROUND_PER_FPC_0 = 0,
308 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1 = 1,
309 S390_DFP_ROUND_PER_FPC_2 = 2,
310 S390_DFP_ROUND_PREPARE_SHORT_3 = 3,
311 S390_DFP_ROUND_NEAREST_EVEN_4 = 4,
312 S390_DFP_ROUND_ZERO_5 = 5,
313 S390_DFP_ROUND_POSINF_6 = 6,
314 S390_DFP_ROUND_NEGINF_7 = 7,
315 S390_DFP_ROUND_NEAREST_EVEN_8 = 8,
316 S390_DFP_ROUND_ZERO_9 = 9,
317 S390_DFP_ROUND_POSINF_10 = 10,
318 S390_DFP_ROUND_NEGINF_11 = 11,
319 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12 = 12,
320 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0 = 13,
321 S390_DFP_ROUND_AWAY_0 = 14,
322 S390_DFP_ROUND_PREPARE_SHORT_15 = 15
323} s390_dfp_round_t;
324
325
326/* DFP Rounding mode as it is encoded in bits [25:27] of the FPC register. */
327typedef enum {
328 S390_FPC_DFP_ROUND_NEAREST_EVEN = 0,
329 S390_FPC_DFP_ROUND_ZERO = 1,
330 S390_FPC_DFP_ROUND_POSINF = 2,
331 S390_FPC_DFP_ROUND_NEGINF = 3,
332 S390_FPC_DFP_ROUND_NEAREST_AWAY_0 = 4,
333 S390_FPC_DFP_ROUND_NEAREST_TOWARD_0 = 5,
334 S390_FPC_DFP_ROUND_AWAY_ZERO = 6,
335 S390_FPC_DFP_ROUND_PREPARE_SHORT = 7
336} s390_fpc_dfp_round_t;
337
338
sewardj2019a972011-03-07 16:04:07 +0000339/* Invert the condition code */
340static __inline__ s390_cc_t
341s390_cc_invert(s390_cc_t cond)
342{
343 return S390_CC_ALWAYS - cond;
344}
345
346
florianb4df7682011-07-05 02:09:01 +0000347typedef struct {
sewardj2019a972011-03-07 16:04:07 +0000348 s390_insn_tag tag;
floriancc491a62012-09-10 23:44:37 +0000349 /* Usually, this is the size of the result of an operation.
350 Exceptions are:
351 - for comparisons it is the size of the operand
352 */
353 UChar size;
sewardj2019a972011-03-07 16:04:07 +0000354 union {
355 struct {
356 HReg dst;
357 s390_amode *src;
358 } load;
359 struct {
360 s390_amode *dst;
361 HReg src;
362 } store;
363 struct {
364 HReg dst;
365 HReg src;
366 } move;
367 struct {
368 s390_cc_t cond;
369 HReg dst;
370 s390_opnd_RMI src;
371 } cond_move;
372 struct {
373 HReg dst;
374 ULong value; /* not sign extended */
375 } load_immediate;
376 /* add, and, or, xor */
377 struct {
378 s390_alu_t tag;
379 HReg dst; /* op1 */
380 s390_opnd_RMI op2;
381 } alu;
382 struct {
383 Bool signed_multiply;
384 HReg dst_hi; /* r10 */
385 HReg dst_lo; /* also op1 r11 */
386 s390_opnd_RMI op2;
387 } mul;
388 struct {
389 Bool signed_divide;
390 HReg op1_hi; /* also remainder r10 */
391 HReg op1_lo; /* also quotient r11 */
392 s390_opnd_RMI op2;
393 } div;
394 struct {
395 HReg rem; /* remainder r10 */
396 HReg op1; /* also quotient r11 */
397 s390_opnd_RMI op2;
398 } divs;
399 struct {
sewardj611b06e2011-03-24 08:57:29 +0000400 HReg num_bits; /* number of leftmost '0' bits r10 */
401 HReg clobber; /* unspecified r11 */
sewardj2019a972011-03-07 16:04:07 +0000402 s390_opnd_RMI src;
sewardj611b06e2011-03-24 08:57:29 +0000403 } clz;
sewardj2019a972011-03-07 16:04:07 +0000404 struct {
405 s390_unop_t tag;
406 HReg dst;
407 s390_opnd_RMI src;
408 } unop;
409 struct {
410 Bool signed_comparison;
411 HReg src1;
412 s390_opnd_RMI src2;
413 } compare;
414 struct {
sewardj2019a972011-03-07 16:04:07 +0000415 s390_opnd_RMI src;
416 } test;
417 /* Convert the condition code to a boolean value. */
418 struct {
419 s390_cc_t cond;
420 HReg dst;
421 } cc2bool;
422 struct {
423 HReg op1;
424 s390_amode *op2;
425 HReg op3;
426 HReg old_mem;
427 } cas;
florian448cbba2012-06-06 02:26:01 +0000428 struct {
429 HReg op1_high;
430 HReg op1_low;
431 s390_amode *op2;
432 HReg op3_high;
433 HReg op3_low;
434 HReg old_mem_high;
435 HReg old_mem_low;
436 HReg scratch;
437 } cdas;
sewardj2019a972011-03-07 16:04:07 +0000438 /* Pseudo-insn for representing a helper call.
439 TARGET is the absolute address of the helper function
440 NUM_ARGS says how many arguments are being passed.
441 All arguments have integer type and are being passed according to ABI,
442 i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
443 passed in r2 and so forth. */
444 struct {
florian1ff47562012-10-21 02:09:51 +0000445 s390_cc_t cond;
446 Addr64 target;
447 UInt num_args;
448 HReg dst; /* if not INVALID_HREG, put return value here */
449 const HChar *name; /* callee's name (for debugging) */
sewardj2019a972011-03-07 16:04:07 +0000450 } helper_call;
floriancc491a62012-09-10 23:44:37 +0000451
452 /* Floating point instructions (including conversion to/from floating
453 point
454
455 128-bit floating point requires register pairs. As the registers
456 in a register pair cannot be chosen independently it would suffice
457 to store only one register of the pair in order to represent it.
458 We chose not to do that as being explicit about all registers
459 helps with debugging and does not require special handling in
florian2c74d242012-09-12 19:38:42 +0000460 e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
floriancc491a62012-09-10 23:44:37 +0000461 the "other" register in a pair if it is implicit.
462
463 The convention for all fp s390_insn is that the _hi register will
464 be used to store the result / operand of a 32/64-bit operation.
465 The _hi register holds the 8 bytes of HIgher significance of a
466 128-bit value (hence the suffix). However, it is the lower numbered
467 register of a register pair. POP says that the lower numbered
468 register is used to identify the pair in an insn encoding. So,
469 when an insn is emitted, only the _hi registers need to be looked
470 at. Nothing special is needed for 128-bit BFP which is nice.
471 */
472
473 /* There are currently no ternary 128-bit BFP operations. */
sewardj2019a972011-03-07 16:04:07 +0000474 struct {
475 s390_bfp_triop_t tag;
floriancc491a62012-09-10 23:44:37 +0000476 HReg dst;
477 HReg op2;
478 HReg op3;
sewardj2019a972011-03-07 16:04:07 +0000479 } bfp_triop;
480 struct {
481 s390_bfp_binop_t tag;
floriancc491a62012-09-10 23:44:37 +0000482 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
483 HReg dst_lo; /* 128-bit result low part */
484 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
485 HReg op2_lo; /* 128-bit operand low part */
sewardj2019a972011-03-07 16:04:07 +0000486 } bfp_binop;
487 struct {
sewardj2019a972011-03-07 16:04:07 +0000488 s390_bfp_unop_t tag;
floriancc491a62012-09-10 23:44:37 +0000489 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
490 HReg dst_lo; /* 128-bit result low part */
491 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
492 HReg op_lo; /* 128-bit operand low part */
493 } bfp_unop;
sewardj2019a972011-03-07 16:04:07 +0000494 struct {
florian9fcff4c2012-09-10 03:09:04 +0000495 s390_conv_t tag;
florian125e20d2012-10-07 15:42:37 +0000496 s390_bfp_round_t rounding_mode;
florian9fcff4c2012-09-10 03:09:04 +0000497 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
498 HReg dst_lo; /* 128-bit result low part */
499 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
500 HReg op_lo; /* 128-bit operand low part */
floriancc491a62012-09-10 23:44:37 +0000501 } bfp_convert;
florian9fcff4c2012-09-10 03:09:04 +0000502 struct {
floriancc491a62012-09-10 23:44:37 +0000503 HReg dst; /* condition code in s390 encoding */
504 HReg op1_hi; /* 128-bit operand high part; 32/64-bit opnd */
505 HReg op1_lo; /* 128-bit operand low part */
506 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
507 HReg op2_lo; /* 128-bit operand low part */
508 } bfp_compare;
florian12390202012-11-10 22:34:14 +0000509 struct {
510 s390_dfp_binop_t tag;
511 HReg dst_hi; /* 128-bit result high part; 64-bit result */
512 HReg dst_lo; /* 128-bit result low part */
513 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
514 HReg op2_lo; /* 128-bit operand low part */
515 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
516 HReg op3_lo; /* 128-bit operand low part */
517 s390_dfp_round_t rounding_mode;
518 } dfp_binop;
floriane38f6412012-12-21 17:32:12 +0000519 struct {
520 s390_dfp_conv_t tag;
521 s390_dfp_round_t rounding_mode;
522 HReg dst_hi; /* 128-bit result high part; 64-bit result */
523 HReg dst_lo; /* 128-bit result low part */
524 HReg op_hi; /* 128-bit operand high part; 64-bit opnd */
525 HReg op_lo; /* 128-bit operand low part */
526 } dfp_convert;
527 struct {
528 HReg dst; /* condition code in s390 encoding */
529 HReg op1_hi; /* 128-bit operand high part; 64-bit opnd 1 */
530 HReg op1_lo; /* 128-bit operand low part */
531 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 2 */
532 HReg op2_lo; /* 128-bit operand low part */
533 } dfp_compare;
floriancc491a62012-09-10 23:44:37 +0000534
535 /* Miscellaneous */
florianad43b3a2012-02-20 15:01:14 +0000536 struct {
florian09bbba82012-12-11 04:09:43 +0000537 s390_amode *dst;
538 } mzero;
florianad43b3a2012-02-20 15:01:14 +0000539 struct {
540 UInt offset;
541 UChar delta;
542 ULong value; /* for debugging only */
543 } gadd;
florian2c74d242012-09-12 19:38:42 +0000544 struct {
545 HReg mode;
florian125e20d2012-10-07 15:42:37 +0000546 } set_fpc_bfprm;
florianc8e4f562012-10-27 16:19:31 +0000547 struct {
548 HReg mode;
549 } set_fpc_dfprm;
florian8844a632012-04-13 04:04:06 +0000550
551 /* The next 5 entries are generic to support translation chaining */
552
553 /* Update the guest IA value, then exit requesting to chain
554 to it. May be conditional. */
555 struct {
556 s390_cc_t cond;
557 Bool to_fast_entry; /* chain to the what entry point? */
558 Addr64 dst; /* next guest address */
559 s390_amode *guest_IA;
560 } xdirect;
561 /* Boring transfer to a guest address not known at JIT time.
562 Not chainable. May be conditional. */
563 struct {
564 s390_cc_t cond;
565 HReg dst;
566 s390_amode *guest_IA;
567 } xindir;
568 /* Assisted transfer to a guest address, most general case.
569 Not chainable. May be conditional. */
570 struct {
571 s390_cc_t cond;
572 IRJumpKind kind;
573 HReg dst;
574 s390_amode *guest_IA;
575 } xassisted;
576 struct {
577 /* fixs390: I don't think these are really needed
578 as the gsp and the offset are fixed no ? */
579 s390_amode *counter; /* dispatch counter */
580 s390_amode *fail_addr;
581 } evcheck;
582 struct {
583 /* No fields. The address of the counter to increment is
584 installed later, post-translation, by patching it in,
585 as it is not known at translation time. */
586 } profinc;
587
sewardj2019a972011-03-07 16:04:07 +0000588 } variant;
589} s390_insn;
590
591s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
592s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
593s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
594s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
595 s390_opnd_RMI src);
596s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
597s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
598 s390_opnd_RMI op2);
599s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
600 s390_opnd_RMI op2, Bool signed_multiply);
601s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
602 s390_opnd_RMI op2, Bool signed_divide);
603s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
sewardj611b06e2011-03-24 08:57:29 +0000604s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
605 s390_opnd_RMI op);
sewardj2019a972011-03-07 16:04:07 +0000606s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
607 HReg old);
florian448cbba2012-06-06 02:26:01 +0000608s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
609 s390_amode *op2, HReg op3_high, HReg op3_low,
610 HReg old_high, HReg old_low, HReg scratch);
sewardj2019a972011-03-07 16:04:07 +0000611s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
612 s390_opnd_RMI opnd);
613s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
614s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
615s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
616 Bool signed_comparison);
sewardj2019a972011-03-07 16:04:07 +0000617s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
florian1ff47562012-10-21 02:09:51 +0000618 const HChar *name, HReg dst);
florian2c74d242012-09-12 19:38:42 +0000619s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
620 HReg op2, HReg op3);
621s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
622 HReg op2);
sewardj2019a972011-03-07 16:04:07 +0000623s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
florian2c74d242012-09-12 19:38:42 +0000624 HReg op);
sewardj2019a972011-03-07 16:04:07 +0000625s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
florian9fcff4c2012-09-10 03:09:04 +0000626s390_insn *s390_insn_bfp_convert(UChar size, s390_conv_t tag, HReg dst,
florian125e20d2012-10-07 15:42:37 +0000627 HReg op, s390_bfp_round_t);
sewardj2019a972011-03-07 16:04:07 +0000628s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
florian2c74d242012-09-12 19:38:42 +0000629 HReg dst_lo, HReg op2_hi, HReg op2_lo);
sewardja970c402011-04-28 18:38:42 +0000630s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
florian2c74d242012-09-12 19:38:42 +0000631 HReg dst_lo, HReg op_hi, HReg op_lo);
sewardj2019a972011-03-07 16:04:07 +0000632s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
633 HReg op1_lo, HReg op2_hi, HReg op2_lo);
florian9fcff4c2012-09-10 03:09:04 +0000634s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_conv_t,
sewardj2019a972011-03-07 16:04:07 +0000635 HReg dst_hi, HReg dst_lo, HReg op);
florian9fcff4c2012-09-10 03:09:04 +0000636s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_conv_t,
sewardj2019a972011-03-07 16:04:07 +0000637 HReg dst, HReg op_hi, HReg op_lo,
florian125e20d2012-10-07 15:42:37 +0000638 s390_bfp_round_t);
florian12390202012-11-10 22:34:14 +0000639s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
640 HReg op2, HReg op3,
641 s390_dfp_round_t rounding_mode);
floriane38f6412012-12-21 17:32:12 +0000642s390_insn *s390_insn_dfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
643s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
644 HReg op, s390_dfp_round_t);
645s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
646 HReg dst_lo, HReg op2_hi, HReg op2_lo,
647 HReg op3_hi, HReg op3_lo,
648 s390_dfp_round_t rounding_mode);
649s390_insn *s390_insn_dfp128_compare(UChar size, HReg dst, HReg op1_hi,
650 HReg op1_lo, HReg op2_hi, HReg op2_lo);
651s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
652 HReg dst_hi, HReg dst_lo, HReg op);
653s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
654 HReg dst, HReg op_hi, HReg op_lo,
655 s390_dfp_round_t);
sewardja52e37e2011-04-28 18:48:06 +0000656s390_insn *s390_insn_mfence(void);
florian09bbba82012-12-11 04:09:43 +0000657s390_insn *s390_insn_mzero(UChar size, s390_amode *dst);
florianad43b3a2012-02-20 15:01:14 +0000658s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value);
florian125e20d2012-10-07 15:42:37 +0000659s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
florianc8e4f562012-10-27 16:19:31 +0000660s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
sewardj2019a972011-03-07 16:04:07 +0000661
florian8844a632012-04-13 04:04:06 +0000662/* Five for translation chaining */
663s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
664 Bool to_fast_entry);
665s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
666s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
667 IRJumpKind kind);
668s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
669s390_insn *s390_insn_profinc(void);
670
sewardj2019a972011-03-07 16:04:07 +0000671const HChar *s390_insn_as_string(const s390_insn *);
672
673/*--------------------------------------------------------*/
674/* --- Interface exposed to VEX --- */
675/*--------------------------------------------------------*/
676
florianb4df7682011-07-05 02:09:01 +0000677void ppS390AMode(s390_amode *);
678void ppS390Instr(s390_insn *, Bool mode64);
sewardj2019a972011-03-07 16:04:07 +0000679void ppHRegS390(HReg);
680
681/* Some functions that insulate the register allocator from details
682 of the underlying instruction set. */
florianb4df7682011-07-05 02:09:01 +0000683void getRegUsage_S390Instr( HRegUsage *, s390_insn *, Bool );
684void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool );
685Bool isMove_S390Instr ( s390_insn *, HReg *, HReg * );
florian8844a632012-04-13 04:04:06 +0000686Int emit_S390Instr ( Bool *, UChar *, Int, s390_insn *, Bool,
687 void *, void *, void *, void *);
sewardj2019a972011-03-07 16:04:07 +0000688void getAllocableRegs_S390( Int *, HReg **, Bool );
689void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
690void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
florianb4df7682011-07-05 02:09:01 +0000691s390_insn *directReload_S390 ( s390_insn *, HReg, Short );
florian8844a632012-04-13 04:04:06 +0000692HInstrArray *iselSB_S390 ( IRSB *, VexArch, VexArchInfo *, VexAbiInfo *,
693 Int, Int, Bool, Bool, Addr64);
694
695/* Return the number of bytes of code needed for an event check */
696Int evCheckSzB_S390(void);
697
698/* Perform a chaining and unchaining of an XDirect jump. */
699VexInvalRange chainXDirect_S390(void *place_to_chain,
700 void *disp_cp_chain_me_EXPECTED,
701 void *place_to_jump_to);
702
703VexInvalRange unchainXDirect_S390(void *place_to_unchain,
704 void *place_to_jump_to_EXPECTED,
705 void *disp_cp_chain_me);
706
707/* Patch the counter location into an existing ProfInc point. */
708VexInvalRange patchProfInc_S390(void *code_to_patch,
709 ULong *location_of_counter);
sewardj2019a972011-03-07 16:04:07 +0000710
711/* KLUDGE: See detailled comment in host_s390_defs.c. */
florianf26994a2012-04-21 03:34:54 +0000712extern UInt s390_host_hwcaps;
sewardj2019a972011-03-07 16:04:07 +0000713
714/* Convenience macros to test installed facilities */
sewardj652b56a2011-04-13 15:38:17 +0000715#define s390_host_has_ldisp \
florianf26994a2012-04-21 03:34:54 +0000716 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
sewardj2019a972011-03-07 16:04:07 +0000717#define s390_host_has_eimm \
florianf26994a2012-04-21 03:34:54 +0000718 (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
sewardj2019a972011-03-07 16:04:07 +0000719#define s390_host_has_gie \
florianf26994a2012-04-21 03:34:54 +0000720 (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
sewardj2019a972011-03-07 16:04:07 +0000721#define s390_host_has_dfp \
florianf26994a2012-04-21 03:34:54 +0000722 (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
sewardjd07b8562011-04-27 11:58:22 +0000723#define s390_host_has_fgx \
florianf26994a2012-04-21 03:34:54 +0000724 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
florian9af37692012-01-15 21:01:16 +0000725#define s390_host_has_etf2 \
florianf26994a2012-04-21 03:34:54 +0000726 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
florian90ece042012-04-21 15:41:51 +0000727#define s390_host_has_stfle \
728 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
florian79bee4b2012-05-03 01:30:48 +0000729#define s390_host_has_etf3 \
730 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
floriana4c36692012-08-26 04:22:33 +0000731#define s390_host_has_stckf \
732 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
florian60b665b2012-08-30 20:28:00 +0000733#define s390_host_has_fpext \
734 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
florianaec8e052012-12-09 17:26:32 +0000735#define s390_host_has_lsc \
736 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
sewardj2019a972011-03-07 16:04:07 +0000737
738#endif /* ndef __VEX_HOST_S390_DEFS_H */
739
740/*---------------------------------------------------------------*/
741/*--- end host_s390_defs.h ---*/
742/*---------------------------------------------------------------*/