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