Bug 385411 s390x: Add z13 vector floating point support
[valgrind.git] / VEX / priv / host_s390_defs.h
blob40f0472a2f3893005f9f60a0c0b9234f1d15a0f4
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*---------------------------------------------------------------*/
4 /*--- begin host_s390_defs.h ---*/
5 /*---------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright IBM Corp. 2010-2017
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.
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.
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.
28 The GNU General Public License is contained in the file COPYING.
31 /* Contributed by Florian Krohm */
33 #ifndef __VEX_HOST_S390_DEFS_H
34 #define __VEX_HOST_S390_DEFS_H
36 #include "libvex_basictypes.h" /* Bool */
37 #include "libvex.h" /* VexArchInfo */
38 #include "host_generic_regs.h" /* HReg */
39 #include "s390_defs.h" /* s390_cc_t */
41 /* --------- Registers --------- */
42 const HChar *s390_hreg_as_string(HReg);
43 HReg s390_hreg_gpr(UInt regno);
44 HReg s390_hreg_fpr(UInt regno);
45 HReg s390_hreg_vr(UInt regno);
47 /* Dedicated registers */
48 HReg s390_hreg_guest_state_pointer(void);
49 HReg s390_hreg_stack_pointer(void);
52 /* Given the index of a function argument, return the number of the
53 general purpose register in which it is being passed. Arguments are
54 counted 0, 1, 2, ... and they are being passed in r2, r3, r4, ... */
55 static __inline__ UInt
56 s390_gprno_from_arg_index(UInt ix)
58 return ix + 2;
61 /* --------- Memory address expressions (amodes). --------- */
63 /* These are the address modes:
64 (1) b12: base register + 12-bit unsigned offset (e.g. RS)
65 (2) b20: base register + 20-bit signed offset (e.g. RSY)
66 (3) bx12: base register + index register + 12-bit unsigned offset (e.g. RX)
67 (4) bx20: base register + index register + 20-bit signed offset (e.g. RXY)
68 fixs390: There is also pc-relative stuff.. e.g. LARL
71 typedef enum {
72 S390_AMODE_B12,
73 S390_AMODE_B20,
74 S390_AMODE_BX12,
75 S390_AMODE_BX20
76 } s390_amode_t;
78 typedef struct {
79 s390_amode_t tag;
80 HReg b;
81 HReg x; /* hregNumber(x) == 0 for S390_AMODE_B12/B20 kinds */
82 Int d; /* 12 bit unsigned or 20 bit signed */
83 } s390_amode;
86 s390_amode *s390_amode_b12(Int d, HReg b);
87 s390_amode *s390_amode_b20(Int d, HReg b);
88 s390_amode *s390_amode_bx12(Int d, HReg b, HReg x);
89 s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
90 s390_amode *s390_amode_for_guest_state(Int d);
91 s390_amode *s390_amode_for_stack_pointer(Int d);
92 Bool s390_amode_is_sane(const s390_amode *);
94 const HChar *s390_amode_as_string(const s390_amode *);
96 /* ------------- 2nd (right) operand of binary operation ---------------- */
98 typedef enum {
99 S390_OPND_REG,
100 S390_OPND_IMMEDIATE,
101 S390_OPND_AMODE
102 } s390_opnd_t;
105 /* Naming convention for operand locations:
106 R - GPR
107 I - immediate value
108 M - memory (any Amode may be used)
111 /* An operand that is either in a GPR or is addressable via a BX20 amode */
112 typedef struct {
113 s390_opnd_t tag;
114 union {
115 HReg reg;
116 s390_amode *am;
117 ULong imm;
118 } variant;
119 } s390_opnd_RMI;
122 /* The kind of instructions */
123 typedef enum {
124 S390_INSN_LOAD, /* load register from memory */
125 S390_INSN_STORE, /* store register to memory */
126 S390_INSN_MOVE, /* from register to register */
127 S390_INSN_MEMCPY, /* from memory to memory */
128 S390_INSN_COND_MOVE, /* conditonal "move" to register */
129 S390_INSN_LOAD_IMMEDIATE,
130 S390_INSN_ALU,
131 S390_INSN_SMUL, /* signed multiply; n-bit operands; 2n-bit result */
132 S390_INSN_UMUL, /* unsigned multiply; n-bit operands; 2n-bit result */
133 S390_INSN_SDIV, /* signed division; 2n-bit / n-bit -> n-bit quot/rem */
134 S390_INSN_UDIV, /* unsigned division; 2n-bit / n-bit -> n-bit quot/rem */
135 S390_INSN_DIVS, /* n-bit dividend; n-bit divisor; n-bit quot/rem */
136 S390_INSN_CLZ, /* count left-most zeroes */
137 S390_INSN_UNOP,
138 S390_INSN_TEST, /* test operand and set cc */
139 S390_INSN_CC2BOOL,/* convert condition code to 0/1 */
140 S390_INSN_COMPARE,
141 S390_INSN_HELPER_CALL,
142 S390_INSN_CAS, /* compare and swap */
143 S390_INSN_CDAS, /* compare double and swap */
144 S390_INSN_BFP_BINOP, /* Binary floating point */
145 S390_INSN_BFP_UNOP,
146 S390_INSN_BFP_TRIOP,
147 S390_INSN_BFP_COMPARE,
148 S390_INSN_BFP_CONVERT,
149 S390_INSN_DFP_BINOP, /* Decimal floating point */
150 S390_INSN_DFP_UNOP,
151 S390_INSN_DFP_INTOP,
152 S390_INSN_DFP_COMPARE,
153 S390_INSN_DFP_CONVERT,
154 S390_INSN_DFP_REROUND,
155 S390_INSN_FP_CONVERT,
156 S390_INSN_MFENCE,
157 S390_INSN_MIMM, /* Assign an immediate constant to a memory location */
158 S390_INSN_MADD, /* Add a value to a memory location */
159 S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
160 S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
161 /* The following 5 insns are mandated by translation chaining */
162 S390_INSN_XDIRECT, /* direct transfer to guest address */
163 S390_INSN_XINDIR, /* indirect transfer to guest address */
164 S390_INSN_XASSISTED, /* assisted transfer to guest address */
165 S390_INSN_EVCHECK, /* Event check */
166 S390_INSN_PROFINC, /* 64-bit profile counter increment */
167 S390_INSN_VEC_AMODEOP,
168 S390_INSN_VEC_AMODEINTOP,
169 S390_INSN_VEC_UNOP,
170 S390_INSN_VEC_BINOP,
171 S390_INSN_VEC_TRIOP
172 } s390_insn_tag;
175 /* The kind of ALU instructions */
176 typedef enum {
177 S390_ALU_ADD,
178 S390_ALU_SUB,
179 S390_ALU_MUL, /* n-bit operands; result is lower n-bit of product */
180 S390_ALU_AND,
181 S390_ALU_OR,
182 S390_ALU_XOR,
183 S390_ALU_LSH,
184 S390_ALU_RSH,
185 S390_ALU_RSHA /* arithmetic */
186 } s390_alu_t;
189 /* The kind of unary integer operations */
190 typedef enum {
191 S390_ZERO_EXTEND_8,
192 S390_ZERO_EXTEND_16,
193 S390_ZERO_EXTEND_32,
194 S390_SIGN_EXTEND_8,
195 S390_SIGN_EXTEND_16,
196 S390_SIGN_EXTEND_32,
197 S390_NEGATE,
198 S390_VEC_FILL,
199 S390_VEC_DUPLICATE,
200 S390_VEC_UNPACKLOWS,
201 S390_VEC_UNPACKLOWU,
202 S390_VEC_ABS,
203 S390_VEC_COUNT_LEADING_ZEROES,
204 S390_VEC_COUNT_TRAILING_ZEROES,
205 S390_VEC_COUNT_ONES,
206 S390_VEC_FLOAT_NEG,
207 S390_VEC_FLOAT_ABS,
208 S390_VEC_FLOAT_SQRT
209 } s390_unop_t;
211 /* The kind of ternary BFP operations */
212 typedef enum {
213 S390_BFP_MADD,
214 S390_BFP_MSUB,
215 } s390_bfp_triop_t;
217 /* The kind of binary BFP operations */
218 typedef enum {
219 S390_BFP_ADD,
220 S390_BFP_SUB,
221 S390_BFP_MUL,
222 S390_BFP_DIV
223 } s390_bfp_binop_t;
225 /* The kind of unary BFP operations */
226 typedef enum {
227 S390_BFP_ABS,
228 S390_BFP_NABS,
229 S390_BFP_NEG,
230 S390_BFP_SQRT
231 } s390_bfp_unop_t;
233 /* Type conversion operations: to and/or from binary floating point */
234 typedef enum {
235 S390_BFP_I32_TO_F32,
236 S390_BFP_I32_TO_F64,
237 S390_BFP_I32_TO_F128,
238 S390_BFP_I64_TO_F32,
239 S390_BFP_I64_TO_F64,
240 S390_BFP_I64_TO_F128,
241 S390_BFP_U32_TO_F32,
242 S390_BFP_U32_TO_F64,
243 S390_BFP_U32_TO_F128,
244 S390_BFP_U64_TO_F32,
245 S390_BFP_U64_TO_F64,
246 S390_BFP_U64_TO_F128,
247 S390_BFP_F32_TO_I32,
248 S390_BFP_F32_TO_I64,
249 S390_BFP_F32_TO_U32,
250 S390_BFP_F32_TO_U64,
251 S390_BFP_F32_TO_F64,
252 S390_BFP_F32_TO_F128,
253 S390_BFP_F64_TO_I32,
254 S390_BFP_F64_TO_I64,
255 S390_BFP_F64_TO_U32,
256 S390_BFP_F64_TO_U64,
257 S390_BFP_F64_TO_F32,
258 S390_BFP_F64_TO_F128,
259 S390_BFP_F128_TO_I32,
260 S390_BFP_F128_TO_I64,
261 S390_BFP_F128_TO_U32,
262 S390_BFP_F128_TO_U64,
263 S390_BFP_F128_TO_F32,
264 S390_BFP_F128_TO_F64,
265 S390_BFP_F32_TO_F32I,
266 S390_BFP_F64_TO_F64I,
267 S390_BFP_F128_TO_F128I
268 } s390_bfp_conv_t;
270 /* Type conversion operations: to and/or from decimal floating point */
271 typedef enum {
272 S390_DFP_D32_TO_D64,
273 S390_DFP_D64_TO_D32,
274 S390_DFP_D64_TO_D128,
275 S390_DFP_D128_TO_D64,
276 S390_DFP_I32_TO_D64,
277 S390_DFP_I32_TO_D128,
278 S390_DFP_I64_TO_D64,
279 S390_DFP_I64_TO_D128,
280 S390_DFP_U32_TO_D64,
281 S390_DFP_U32_TO_D128,
282 S390_DFP_U64_TO_D64,
283 S390_DFP_U64_TO_D128,
284 S390_DFP_D64_TO_I32,
285 S390_DFP_D64_TO_I64,
286 S390_DFP_D64_TO_U32,
287 S390_DFP_D64_TO_U64,
288 S390_DFP_D128_TO_I32,
289 S390_DFP_D128_TO_I64,
290 S390_DFP_D128_TO_U32,
291 S390_DFP_D128_TO_U64
292 } s390_dfp_conv_t;
294 typedef enum {
295 S390_FP_F32_TO_D32,
296 S390_FP_F32_TO_D64,
297 S390_FP_F32_TO_D128,
298 S390_FP_F64_TO_D32,
299 S390_FP_F64_TO_D64,
300 S390_FP_F64_TO_D128,
301 S390_FP_F128_TO_D32,
302 S390_FP_F128_TO_D64,
303 S390_FP_F128_TO_D128,
304 S390_FP_D32_TO_F32,
305 S390_FP_D32_TO_F64,
306 S390_FP_D32_TO_F128,
307 S390_FP_D64_TO_F32,
308 S390_FP_D64_TO_F64,
309 S390_FP_D64_TO_F128,
310 S390_FP_D128_TO_F32,
311 S390_FP_D128_TO_F64,
312 S390_FP_D128_TO_F128
313 } s390_fp_conv_t;
315 /* The kind of binary DFP operations */
316 typedef enum {
317 S390_DFP_ADD,
318 S390_DFP_SUB,
319 S390_DFP_MUL,
320 S390_DFP_DIV,
321 S390_DFP_QUANTIZE
322 } s390_dfp_binop_t;
324 /* The kind of unary DFP operations */
325 typedef enum {
326 S390_DFP_EXTRACT_EXP_D64,
327 S390_DFP_EXTRACT_EXP_D128,
328 S390_DFP_EXTRACT_SIG_D64,
329 S390_DFP_EXTRACT_SIG_D128,
330 } s390_dfp_unop_t;
332 /* The DFP operations with 2 operands one of them being integer */
333 typedef enum {
334 S390_DFP_SHIFT_LEFT,
335 S390_DFP_SHIFT_RIGHT,
336 S390_DFP_INSERT_EXP
337 } s390_dfp_intop_t;
339 /* The kind of DFP compare operations */
340 typedef enum {
341 S390_DFP_COMPARE,
342 S390_DFP_COMPARE_EXP,
343 } s390_dfp_cmp_t;
345 /* The vector operations with 2 operands one of them being amode */
346 typedef enum {
347 S390_VEC_GET_ELEM,
348 S390_VEC_ELEM_SHL_INT,
349 S390_VEC_ELEM_SHRA_INT,
350 S390_VEC_ELEM_SHRL_INT
351 } s390_vec_amodeop_t;
353 /* The vector operations with three (vector, amode and integer) operands */
354 typedef enum {
355 S390_VEC_SET_ELEM
356 } s390_vec_amodeintop_t;
358 /* The vector operations with two operands */
359 typedef enum {
360 S390_VEC_PACK,
361 S390_VEC_PACK_SATURS,
362 S390_VEC_PACK_SATURU,
363 S390_VEC_COMPARE_EQUAL,
364 S390_VEC_OR,
365 S390_VEC_XOR,
366 S390_VEC_AND,
367 S390_VEC_MERGEL,
368 S390_VEC_MERGEH,
369 S390_VEC_NOR,
370 S390_VEC_INT_ADD,
371 S390_VEC_INT_SUB,
372 S390_VEC_MAXU,
373 S390_VEC_MAXS,
374 S390_VEC_MINU,
375 S390_VEC_MINS,
376 S390_VEC_AVGU,
377 S390_VEC_AVGS,
378 S390_VEC_COMPARE_GREATERS,
379 S390_VEC_COMPARE_GREATERU,
380 S390_VEC_INT_MUL_HIGHS,
381 S390_VEC_INT_MUL_HIGHU,
382 S390_VEC_INT_MUL_LOW,
383 S390_VEC_INT_MUL_EVENS,
384 S390_VEC_INT_MUL_EVENU,
385 S390_VEC_ELEM_SHL_V,
386 S390_VEC_ELEM_SHRA_V,
387 S390_VEC_ELEM_SHRL_V,
388 S390_VEC_ELEM_ROLL_V,
390 /* host_s390_isel depends on this order. */
391 S390_VEC_SHL_BITS, S390_VEC_SHL_BYTES,
392 S390_VEC_SHRL_BITS, S390_VEC_SHRL_BYTES,
393 S390_VEC_SHRA_BITS, S390_VEC_SHRA_BYTES,
395 S390_VEC_PWSUM_W,
396 S390_VEC_PWSUM_DW,
397 S390_VEC_PWSUM_QW,
399 S390_VEC_INIT_FROM_GPRS,
400 S390_VEC_FLOAT_ADD,
401 S390_VEC_FLOAT_SUB,
402 S390_VEC_FLOAT_MUL,
403 S390_VEC_FLOAT_DIV,
404 S390_VEC_FLOAT_COMPARE_EQUAL,
405 S390_VEC_FLOAT_COMPARE_LESS_OR_EQUAL,
406 S390_VEC_FLOAT_COMPARE_LESS
407 } s390_vec_binop_t;
409 /* The vector operations with three operands */
410 typedef enum {
411 S390_VEC_PERM,
412 S390_VEC_FLOAT_MADD,
413 S390_VEC_FLOAT_MSUB
414 } s390_vec_triop_t;
416 /* The details of a CDAS insn. Carved out to keep the size of
417 s390_insn low */
418 typedef struct {
419 HReg op1_high;
420 HReg op1_low;
421 s390_amode *op2;
422 HReg op3_high;
423 HReg op3_low;
424 HReg old_mem_high;
425 HReg old_mem_low;
426 HReg scratch;
427 } s390_cdas;
429 /* The details of a binary DFP insn. Carved out to keep the size of
430 s390_insn low */
431 typedef struct {
432 s390_dfp_binop_t tag;
433 s390_dfp_round_t rounding_mode;
434 HReg dst_hi; /* 128-bit result high part; 64-bit result */
435 HReg dst_lo; /* 128-bit result low part */
436 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
437 HReg op2_lo; /* 128-bit operand low part */
438 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
439 HReg op3_lo; /* 128-bit operand low part */
440 } s390_dfp_binop;
442 typedef struct {
443 s390_fp_conv_t tag;
444 s390_dfp_round_t rounding_mode;
445 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
446 HReg dst_lo; /* 128-bit result low part */
447 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
448 HReg op_lo; /* 128-bit operand low part */
449 HReg r1; /* clobbered register GPR #1 */
450 } s390_fp_convert;
452 /* Pseudo-insn for representing a helper call.
453 TARGET is the absolute address of the helper function
454 NUM_ARGS says how many arguments are being passed.
455 All arguments have integer type and are being passed according to ABI,
456 i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
457 passed in r2 and so forth. */
458 typedef struct {
459 s390_cc_t cond : 16;
460 UInt num_args : 16;
461 RetLoc rloc; /* where the return value will be */
462 Addr64 target;
463 const HChar *name; /* callee's name (for debugging) */
464 } s390_helper_call;
466 typedef struct {
467 s390_insn_tag tag;
468 /* Usually, this is the size of the result of an operation.
469 Exceptions are:
470 - for comparisons it is the size of the operand
472 UChar size;
473 union {
474 struct {
475 HReg dst;
476 s390_amode *src;
477 } load;
478 struct {
479 s390_amode *dst;
480 HReg src;
481 } store;
482 struct {
483 HReg dst;
484 HReg src;
485 } move;
486 struct {
487 s390_amode *dst;
488 s390_amode *src;
489 } memcpy;
490 struct {
491 s390_cc_t cond;
492 HReg dst;
493 s390_opnd_RMI src;
494 } cond_move;
495 struct {
496 HReg dst;
497 ULong value; /* not sign extended */
498 } load_immediate;
499 /* add, and, or, xor */
500 struct {
501 s390_alu_t tag;
502 HReg dst; /* op1 */
503 s390_opnd_RMI op2;
504 } alu;
505 struct {
506 HReg dst_hi; /* r10 */
507 HReg dst_lo; /* also op1 r11 */
508 s390_opnd_RMI op2;
509 } mul;
510 struct {
511 HReg op1_hi; /* also remainder r10 */
512 HReg op1_lo; /* also quotient r11 */
513 s390_opnd_RMI op2;
514 } div;
515 struct {
516 HReg rem; /* remainder r10 */
517 HReg op1; /* also quotient r11 */
518 s390_opnd_RMI op2;
519 } divs;
520 struct {
521 HReg num_bits; /* number of leftmost '0' bits r10 */
522 HReg clobber; /* unspecified r11 */
523 s390_opnd_RMI src;
524 } clz;
525 struct {
526 s390_unop_t tag;
527 HReg dst;
528 s390_opnd_RMI src;
529 } unop;
530 struct {
531 Bool signed_comparison;
532 HReg src1;
533 s390_opnd_RMI src2;
534 } compare;
535 struct {
536 s390_opnd_RMI src;
537 } test;
538 /* Convert the condition code to a boolean value. */
539 struct {
540 s390_cc_t cond;
541 HReg dst;
542 } cc2bool;
543 struct {
544 HReg op1;
545 s390_amode *op2;
546 HReg op3;
547 HReg old_mem;
548 } cas;
549 struct {
550 s390_cdas *details;
551 } cdas;
552 struct {
553 s390_helper_call *details;
554 } helper_call;
556 /* Floating point instructions (including conversion to/from floating
557 point
559 128-bit floating point requires register pairs. As the registers
560 in a register pair cannot be chosen independently it would suffice
561 to store only one register of the pair in order to represent it.
562 We chose not to do that as being explicit about all registers
563 helps with debugging and does not require special handling in
564 e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
565 the "other" register in a pair if it is implicit.
567 The convention for all fp s390_insn is that the _hi register will
568 be used to store the result / operand of a 32/64-bit operation.
569 The _hi register holds the 8 bytes of HIgher significance of a
570 128-bit value (hence the suffix). However, it is the lower numbered
571 register of a register pair. POP says that the lower numbered
572 register is used to identify the pair in an insn encoding. So,
573 when an insn is emitted, only the _hi registers need to be looked
574 at. Nothing special is needed for 128-bit BFP which is nice.
577 /* There are currently no ternary 128-bit BFP operations. */
578 struct {
579 s390_bfp_triop_t tag;
580 HReg dst;
581 HReg op2;
582 HReg op3;
583 } bfp_triop;
584 struct {
585 s390_bfp_binop_t tag;
586 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
587 HReg dst_lo; /* 128-bit result low part */
588 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
589 HReg op2_lo; /* 128-bit operand low part */
590 } bfp_binop;
591 struct {
592 s390_bfp_unop_t tag;
593 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
594 HReg dst_lo; /* 128-bit result low part */
595 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
596 HReg op_lo; /* 128-bit operand low part */
597 } bfp_unop;
598 struct {
599 s390_bfp_conv_t tag;
600 s390_bfp_round_t rounding_mode;
601 HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
602 HReg dst_lo; /* 128-bit result low part */
603 HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */
604 HReg op_lo; /* 128-bit operand low part */
605 } bfp_convert;
606 struct {
607 HReg dst; /* condition code in s390 encoding */
608 HReg op1_hi; /* 128-bit operand high part; 32/64-bit opnd */
609 HReg op1_lo; /* 128-bit operand low part */
610 HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
611 HReg op2_lo; /* 128-bit operand low part */
612 } bfp_compare;
613 struct {
614 s390_dfp_binop *details;
615 } dfp_binop;
616 struct {
617 s390_dfp_unop_t tag;
618 HReg dst_hi; /* 128-bit result high part; 64-bit result */
619 HReg dst_lo; /* 128-bit result low part */
620 HReg op_hi; /* 128-bit operand high part; 64-bit opnd */
621 HReg op_lo; /* 128-bit operand low part */
622 } dfp_unop;
623 struct {
624 s390_dfp_intop_t tag;
625 HReg dst_hi; /* 128-bit result high part; 64-bit result */
626 HReg dst_lo; /* 128-bit result low part */
627 HReg op2; /* integer operand */
628 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd */
629 HReg op3_lo; /* 128-bit operand low part */
630 } dfp_intop;
631 struct {
632 s390_dfp_conv_t tag;
633 s390_dfp_round_t rounding_mode;
634 HReg dst_hi; /* 128-bit result high part; 64-bit result */
635 HReg dst_lo; /* 128-bit result low part */
636 HReg op_hi; /* 128-bit operand high part; 64-bit opnd */
637 HReg op_lo; /* 128-bit operand low part */
638 } dfp_convert;
639 struct {
640 s390_fp_convert *details;
641 } fp_convert;
642 struct {
643 s390_dfp_cmp_t tag;
644 HReg dst; /* condition code in s390 encoding */
645 HReg op1_hi; /* 128-bit operand high part; 64-bit opnd 1 */
646 HReg op1_lo; /* 128-bit operand low part */
647 HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 2 */
648 HReg op2_lo; /* 128-bit operand low part */
649 } dfp_compare;
650 struct {
651 s390_dfp_round_t rounding_mode;
652 HReg dst_hi; /* 128-bit result high part; 64-bit result */
653 HReg dst_lo; /* 128-bit result low part */
654 HReg op2; /* integer operand */
655 HReg op3_hi; /* 128-bit operand high part; 64-bit opnd */
656 HReg op3_lo; /* 128-bit operand low part */
657 } dfp_reround;
659 /* Miscellaneous */
660 struct {
661 s390_amode *dst;
662 ULong value; /* sign extended */
663 } mimm;
664 struct {
665 s390_amode *dst;
666 UChar delta;
667 ULong value; /* for debugging only */
668 } madd;
669 struct {
670 HReg mode;
671 } set_fpc_bfprm;
672 struct {
673 HReg mode;
674 } set_fpc_dfprm;
676 /* The next 5 entries are generic to support translation chaining */
678 /* Update the guest IA value, then exit requesting to chain
679 to it. May be conditional. */
680 struct {
681 s390_cc_t cond;
682 Bool to_fast_entry; /* chain to the what entry point? */
683 Addr64 dst; /* next guest address */
684 s390_amode *guest_IA;
685 } xdirect;
686 /* Boring transfer to a guest address not known at JIT time.
687 Not chainable. May be conditional. */
688 struct {
689 s390_cc_t cond;
690 HReg dst;
691 s390_amode *guest_IA;
692 } xindir;
693 /* Assisted transfer to a guest address, most general case.
694 Not chainable. May be conditional. */
695 struct {
696 s390_cc_t cond;
697 IRJumpKind kind;
698 HReg dst;
699 s390_amode *guest_IA;
700 } xassisted;
701 struct {
702 /* fixs390: I don't think these are really needed
703 as the gsp and the offset are fixed no ? */
704 s390_amode *counter; /* dispatch counter */
705 s390_amode *fail_addr;
706 } evcheck;
707 struct {
708 /* No fields. The address of the counter to increment is
709 installed later, post-translation, by patching it in,
710 as it is not known at translation time. */
711 } profinc;
712 struct {
713 s390_vec_amodeop_t tag;
714 HReg dst; /* 64-bit result */
715 HReg op1; /* 128-bit operand */
716 s390_amode *op2; /* amode operand */
717 } vec_amodeop;
718 struct {
719 s390_vec_amodeintop_t tag;
720 HReg dst; /* 128-bit result */
721 s390_amode *op2; /* amode operand */
722 HReg op3; /* integer operand */
723 } vec_amodeintop;
724 struct {
725 s390_vec_binop_t tag;
726 HReg dst; /* 128-bit result */
727 HReg op1; /* 128-bit first operand */
728 HReg op2; /* 128-bit second operand */
729 } vec_binop;
730 struct {
731 s390_vec_triop_t tag;
732 HReg dst; /* 128-bit result */
733 HReg op1; /* 128-bit first operand */
734 HReg op2; /* 128-bit second operand */
735 HReg op3; /* 128-bit third operand */
736 } vec_triop;
737 } variant;
738 } s390_insn;
740 s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
741 s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
742 s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
743 s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src);
744 s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
745 s390_opnd_RMI src);
746 s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
747 s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
748 s390_opnd_RMI op2);
749 s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
750 s390_opnd_RMI op2, Bool signed_multiply);
751 s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
752 s390_opnd_RMI op2, Bool signed_divide);
753 s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
754 s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
755 s390_opnd_RMI op);
756 s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
757 HReg old);
758 s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
759 s390_amode *op2, HReg op3_high, HReg op3_low,
760 HReg old_high, HReg old_low, HReg scratch);
761 s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
762 s390_opnd_RMI opnd);
763 s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
764 s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
765 s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
766 Bool signed_comparison);
767 s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
768 const HChar *name, RetLoc rloc);
769 s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
770 HReg op2, HReg op3);
771 s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
772 HReg op2);
773 s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
774 HReg op);
775 s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
776 s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
777 HReg op, s390_bfp_round_t);
778 s390_insn *s390_insn_bfp128_convert(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
779 HReg dst_lo, HReg op_hi, HReg op_lo,
780 s390_bfp_round_t rounding_mode);
781 s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
782 HReg dst_lo, HReg op2_hi, HReg op2_lo);
783 s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
784 HReg dst_lo, HReg op_hi, HReg op_lo);
785 s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
786 HReg op1_lo, HReg op2_hi, HReg op2_lo);
787 s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
788 HReg dst_hi, HReg dst_lo, HReg op);
789 s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t,
790 HReg dst_hi, HReg dst_lo, HReg op_hi,
791 HReg op_lo, s390_bfp_round_t);
792 s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
793 HReg op2, HReg op3,
794 s390_dfp_round_t rounding_mode);
795 s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op);
796 s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst,
797 HReg op2, HReg op3);
798 s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst,
799 HReg op1, HReg op2);
800 s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
801 HReg op, s390_dfp_round_t);
802 s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
803 s390_dfp_round_t);
804 s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag,
805 HReg dst, HReg op, HReg r1, s390_dfp_round_t);
806 s390_insn *s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag,
807 HReg dst_hi, HReg dst_lo, HReg op_hi,
808 HReg op_lo, HReg r1, s390_dfp_round_t);
809 s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
810 HReg dst_lo, HReg op2_hi, HReg op2_lo,
811 HReg op3_hi, HReg op3_lo,
812 s390_dfp_round_t rounding_mode);
813 s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst,
814 HReg op_hi, HReg op_lo);
815 s390_insn *s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t, HReg dst_hi,
816 HReg dst_lo, HReg op2,
817 HReg op3_hi, HReg op3_lo);
818 s390_insn *s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t, HReg dst,
819 HReg op1_hi, HReg op1_lo, HReg op2_hi,
820 HReg op2_lo);
821 s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
822 HReg dst_hi, HReg dst_lo, HReg op);
823 s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
824 HReg dst_hi, HReg dst_lo, HReg op_hi,
825 HReg op_lo, s390_dfp_round_t);
826 s390_insn *s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo,
827 HReg op2, HReg op3_hi, HReg op3_lo,
828 s390_dfp_round_t);
829 s390_insn *s390_insn_mfence(void);
830 s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value);
831 s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
832 ULong value);
833 s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
834 s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
836 /* Five for translation chaining */
837 s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
838 Bool to_fast_entry);
839 s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
840 s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
841 IRJumpKind kind);
842 s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
843 s390_insn *s390_insn_profinc(void);
844 s390_insn *s390_insn_vec_amodeop(UChar size, s390_vec_amodeop_t, HReg dst,
845 HReg op1, s390_amode* op2);
846 s390_insn *s390_insn_vec_amodeintop(UChar size, s390_vec_amodeintop_t, HReg dst,
847 s390_amode* op2, HReg op3);
848 s390_insn *s390_insn_vec_binop(UChar size, s390_vec_binop_t, HReg dst, HReg op1,
849 HReg op2);
850 s390_insn *s390_insn_vec_triop(UChar size, s390_vec_triop_t, HReg dst, HReg op1,
851 HReg op2, HReg op3);
853 const HChar *s390_insn_as_string(const s390_insn *);
855 /*--------------------------------------------------------*/
856 /* --- Interface exposed to VEX --- */
857 /*--------------------------------------------------------*/
859 void ppS390AMode(const s390_amode *);
860 void ppS390Instr(const s390_insn *, Bool mode64);
861 UInt ppHRegS390(HReg);
863 /* Some functions that insulate the register allocator from details
864 of the underlying instruction set. */
865 void getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool );
866 void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool );
867 Int emit_S390Instr ( Bool *, UChar *, Int, const s390_insn *, Bool,
868 VexEndness, const void *, const void *,
869 const void *, const void *);
870 const RRegUniverse *getRRegUniverse_S390( void );
871 void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
872 void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
873 extern s390_insn* genMove_S390(HReg from, HReg to, Bool mode64);
874 HInstrArray *iselSB_S390 ( const IRSB *, VexArch, const VexArchInfo *,
875 const VexAbiInfo *, Int, Int, Bool, Bool, Addr);
877 /* Return the number of bytes of code needed for an event check */
878 Int evCheckSzB_S390(void);
880 /* Perform a chaining and unchaining of an XDirect jump. */
881 VexInvalRange chainXDirect_S390(VexEndness endness_host,
882 void *place_to_chain,
883 const void *disp_cp_chain_me_EXPECTED,
884 const void *place_to_jump_to);
886 VexInvalRange unchainXDirect_S390(VexEndness endness_host,
887 void *place_to_unchain,
888 const void *place_to_jump_to_EXPECTED,
889 const void *disp_cp_chain_me);
891 /* Patch the counter location into an existing ProfInc point. */
892 VexInvalRange patchProfInc_S390(VexEndness endness_host,
893 void *code_to_patch,
894 const ULong *location_of_counter);
896 /* KLUDGE: See detailled comment in host_s390_defs.c. */
897 extern UInt s390_host_hwcaps;
899 /* Convenience macros to test installed facilities */
900 #define s390_host_has_ldisp \
901 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
902 #define s390_host_has_eimm \
903 (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
904 #define s390_host_has_gie \
905 (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
906 #define s390_host_has_dfp \
907 (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
908 #define s390_host_has_fgx \
909 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
910 #define s390_host_has_etf2 \
911 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
912 #define s390_host_has_stfle \
913 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
914 #define s390_host_has_etf3 \
915 (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
916 #define s390_host_has_stckf \
917 (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
918 #define s390_host_has_fpext \
919 (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
920 #define s390_host_has_lsc \
921 (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
922 #define s390_host_has_pfpo \
923 (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO))
924 #define s390_host_has_vx \
925 (s390_host_hwcaps & (VEX_HWCAPS_S390X_VX))
926 #define s390_host_has_msa5 \
927 (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA5))
928 #endif /* ndef __VEX_HOST_S390_DEFS_H */
930 /*---------------------------------------------------------------*/
931 /*--- end host_s390_defs.h ---*/
932 /*---------------------------------------------------------------*/