1 /* -*- 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 
11    Copyright IBM Corp. 2010-2017
12 
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 */
38 #include "host_generic_regs.h"            /* HReg */
39 #include "s390_defs.h"                    /* s390_cc_t */
40 
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);
46 
47 /* Dedicated registers */
48 HReg s390_hreg_guest_state_pointer(void);
49 HReg s390_hreg_stack_pointer(void);
50 
51 
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
s390_gprno_from_arg_index(UInt ix)56 s390_gprno_from_arg_index(UInt ix)
57 {
58    return ix + 2;
59 }
60 
61 /* --------- Memory address expressions (amodes). --------- */
62 
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
69 */
70 
71 typedef enum {
72    S390_AMODE_B12,
73    S390_AMODE_B20,
74    S390_AMODE_BX12,
75    S390_AMODE_BX20
76 } s390_amode_t;
77 
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;
84 
85 
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 *);
93 
94 const HChar *s390_amode_as_string(const s390_amode *);
95 
96 /* ------------- 2nd (right) operand of binary operation ---------------- */
97 
98 typedef enum {
99    S390_OPND_REG,
100    S390_OPND_IMMEDIATE,
101    S390_OPND_AMODE
102 } s390_opnd_t;
103 
104 
105 /* Naming convention for operand locations:
106    R    - GPR
107    I    - immediate value
108    M    - memory (any Amode may be used)
109 */
110 
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;
120 
121 
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;
173 
174 
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;
187 
188 
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;
210 
211 /* The kind of ternary BFP operations */
212 typedef enum {
213    S390_BFP_MADD,
214    S390_BFP_MSUB,
215 } s390_bfp_triop_t;
216 
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;
224 
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;
232 
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;
269 
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;
293 
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;
314 
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;
323 
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;
331 
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;
338 
339 /* The kind of DFP compare operations */
340 typedef enum {
341    S390_DFP_COMPARE,
342    S390_DFP_COMPARE_EXP,
343 } s390_dfp_cmp_t;
344 
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;
352 
353 /* The vector operations with three (vector, amode and integer) operands */
354 typedef enum {
355    S390_VEC_SET_ELEM
356 } s390_vec_amodeintop_t;
357 
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,
389 
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,
394 
395    S390_VEC_PWSUM_W,
396    S390_VEC_PWSUM_DW,
397    S390_VEC_PWSUM_QW,
398 
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;
408 
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;
415 
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;
428 
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;
441 
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;
451 
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;
465 
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
471    */
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;
555 
556       /* Floating point instructions (including conversion to/from floating
557          point
558 
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.
566 
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.
575       */
576 
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;
658 
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;
675 
676       /* The next 5 entries are generic to support translation chaining */
677 
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;
739 
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);
835 
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);
852 
853 const HChar *s390_insn_as_string(const s390_insn *);
854 
855 /*--------------------------------------------------------*/
856 /* --- Interface exposed to VEX                       --- */
857 /*--------------------------------------------------------*/
858 
859 void ppS390AMode(const s390_amode *);
860 void ppS390Instr(const s390_insn *, Bool mode64);
861 UInt ppHRegS390(HReg);
862 
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);
876 
877 /* Return the number of bytes of code needed for an event check */
878 Int evCheckSzB_S390(void);
879 
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);
885 
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);
890 
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);
895 
896 /* KLUDGE: See detailled comment in host_s390_defs.c. */
897 extern UInt s390_host_hwcaps;
898 
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 */
929 
930 /*---------------------------------------------------------------*/
931 /*--- end                                    host_s390_defs.h ---*/
932 /*---------------------------------------------------------------*/
933