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