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);
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_conv_t;
247
248/* Type conversion operations: to and/or from decimal floating point */
249typedef enum {
250   S390_DFP_D32_TO_D64,
251   S390_DFP_D64_TO_D32,
252   S390_DFP_D64_TO_D128,
253   S390_DFP_D128_TO_D64,
254   S390_DFP_I32_TO_D64,
255   S390_DFP_I32_TO_D128,
256   S390_DFP_I64_TO_D64,
257   S390_DFP_I64_TO_D128,
258   S390_DFP_U32_TO_D64,
259   S390_DFP_U32_TO_D128,
260   S390_DFP_U64_TO_D64,
261   S390_DFP_U64_TO_D128,
262   S390_DFP_D64_TO_I32,
263   S390_DFP_D64_TO_I64,
264   S390_DFP_D64_TO_U32,
265   S390_DFP_D64_TO_U64,
266   S390_DFP_D128_TO_I32,
267   S390_DFP_D128_TO_I64,
268   S390_DFP_D128_TO_U32,
269   S390_DFP_D128_TO_U64
270} s390_dfp_conv_t;
271
272typedef enum {
273   S390_FP_F32_TO_D32,
274   S390_FP_F32_TO_D64,
275   S390_FP_F32_TO_D128,
276   S390_FP_F64_TO_D32,
277   S390_FP_F64_TO_D64,
278   S390_FP_F64_TO_D128,
279   S390_FP_F128_TO_D32,
280   S390_FP_F128_TO_D64,
281   S390_FP_F128_TO_D128,
282   S390_FP_D32_TO_F32,
283   S390_FP_D32_TO_F64,
284   S390_FP_D32_TO_F128,
285   S390_FP_D64_TO_F32,
286   S390_FP_D64_TO_F64,
287   S390_FP_D64_TO_F128,
288   S390_FP_D128_TO_F32,
289   S390_FP_D128_TO_F64,
290   S390_FP_D128_TO_F128
291} s390_fp_conv_t;
292
293/* The kind of binary DFP operations */
294typedef enum {
295   S390_DFP_ADD,
296   S390_DFP_SUB,
297   S390_DFP_MUL,
298   S390_DFP_DIV,
299   S390_DFP_QUANTIZE
300} s390_dfp_binop_t;
301
302/* The kind of unary DFP operations */
303typedef enum {
304   S390_DFP_EXTRACT_EXP_D64,
305   S390_DFP_EXTRACT_EXP_D128,
306   S390_DFP_EXTRACT_SIG_D64,
307   S390_DFP_EXTRACT_SIG_D128,
308} s390_dfp_unop_t;
309
310/* The DFP operations with 2 operands one of them being integer */
311typedef enum {
312   S390_DFP_SHIFT_LEFT,
313   S390_DFP_SHIFT_RIGHT,
314   S390_DFP_INSERT_EXP
315} s390_dfp_intop_t;
316
317/* The kind of DFP compare operations */
318typedef enum {
319   S390_DFP_COMPARE,
320   S390_DFP_COMPARE_EXP,
321} s390_dfp_cmp_t;
322
323/* The details of a CDAS insn. Carved out to keep the size of
324   s390_insn low */
325typedef struct {
326   HReg        op1_high;
327   HReg        op1_low;
328   s390_amode *op2;
329   HReg        op3_high;
330   HReg        op3_low;
331   HReg        old_mem_high;
332   HReg        old_mem_low;
333   HReg        scratch;
334} s390_cdas;
335
336/* The details of a binary DFP insn. Carved out to keep the size of
337   s390_insn low */
338typedef struct {
339   s390_dfp_binop_t tag;
340   s390_dfp_round_t rounding_mode;
341   HReg         dst_hi; /* 128-bit result high part; 64-bit result */
342   HReg         dst_lo; /* 128-bit result low part */
343   HReg         op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
344   HReg         op2_lo; /* 128-bit operand low part */
345   HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
346   HReg         op3_lo; /* 128-bit operand low part */
347} s390_dfp_binop;
348
349typedef struct {
350   s390_fp_conv_t  tag;
351   s390_dfp_round_t rounding_mode;
352   HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
353   HReg         dst_lo; /* 128-bit result low part */
354   HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
355   HReg         op_lo;  /* 128-bit operand low part */
356   HReg         r1;     /* clobbered register GPR #1 */
357} s390_fp_convert;
358
359/* Pseudo-insn for representing a helper call.
360   TARGET is the absolute address of the helper function
361   NUM_ARGS says how many arguments are being passed.
362   All arguments have integer type and are being passed according to ABI,
363   i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
364   passed in r2 and so forth. */
365typedef struct {
366   s390_cc_t    cond     : 16;
367   UInt         num_args : 16;
368   RetLoc       rloc;     /* where the return value will be */
369   Addr64       target;
370   const HChar *name;      /* callee's name (for debugging) */
371} s390_helper_call;
372
373typedef struct {
374   s390_insn_tag tag;
375   /* Usually, this is the size of the result of an operation.
376      Exceptions are:
377      - for comparisons it is the size of the operand
378   */
379   UChar size;
380   union {
381      struct {
382         HReg        dst;
383         s390_amode *src;
384      } load;
385      struct {
386         s390_amode *dst;
387         HReg        src;
388      } store;
389      struct {
390         HReg        dst;
391         HReg        src;
392      } move;
393      struct {
394         s390_amode *dst;
395         s390_amode *src;
396      } memcpy;
397      struct {
398         s390_cc_t     cond;
399         HReg          dst;
400         s390_opnd_RMI src;
401      } cond_move;
402      struct {
403         HReg        dst;
404         ULong       value;  /* not sign extended */
405      } load_immediate;
406      /* add, and, or, xor */
407      struct {
408         s390_alu_t    tag;
409         HReg          dst; /* op1 */
410         s390_opnd_RMI op2;
411      } alu;
412      struct {
413         HReg          dst_hi;  /*           r10 */
414         HReg          dst_lo;  /* also op1  r11 */
415         s390_opnd_RMI op2;
416      } mul;
417      struct {
418         HReg          op1_hi;  /* also remainder   r10 */
419         HReg          op1_lo;  /* also quotient    r11 */
420         s390_opnd_RMI op2;
421      } div;
422      struct {
423         HReg          rem; /* remainder      r10 */
424         HReg          op1; /* also quotient  r11 */
425         s390_opnd_RMI op2;
426      } divs;
427      struct {
428         HReg          num_bits; /* number of leftmost '0' bits  r10 */
429         HReg          clobber;  /* unspecified                  r11 */
430         s390_opnd_RMI src;
431      } clz;
432      struct {
433         s390_unop_t   tag;
434         HReg          dst;
435         s390_opnd_RMI src;
436      } unop;
437      struct {
438         Bool          signed_comparison;
439         HReg          src1;
440         s390_opnd_RMI src2;
441      } compare;
442      struct {
443         s390_opnd_RMI src;
444      } test;
445      /* Convert the condition code to a boolean value. */
446      struct {
447         s390_cc_t cond;
448         HReg      dst;
449      } cc2bool;
450      struct {
451         HReg        op1;
452         s390_amode *op2;
453         HReg        op3;
454         HReg        old_mem;
455      } cas;
456      struct {
457         s390_cdas *details;
458      } cdas;
459      struct {
460         s390_helper_call *details;
461      } helper_call;
462
463      /* Floating point instructions (including conversion to/from floating
464         point
465
466         128-bit floating point requires register pairs. As the registers
467         in a register pair cannot be chosen independently it would suffice
468         to store only one register of the pair in order to represent it.
469         We chose not to do that as being explicit about all registers
470         helps with debugging and does not require special handling in
471         e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
472         the "other" register in a pair if it is implicit.
473
474         The convention for all fp s390_insn is that the _hi register will
475         be used to store the result / operand of a 32/64-bit operation.
476         The _hi register holds the  8 bytes of HIgher significance of a
477         128-bit value (hence the suffix). However, it is the lower numbered
478         register of a register pair. POP says that the lower numbered
479         register is used to identify the pair in an insn encoding. So,
480         when an insn is emitted, only the _hi registers need to be looked
481         at. Nothing special is needed for 128-bit BFP which is nice.
482      */
483
484      /* There are currently no ternary 128-bit BFP operations. */
485      struct {
486         s390_bfp_triop_t tag;
487         HReg         dst;
488         HReg         op2;
489         HReg         op3;
490      } bfp_triop;
491      struct {
492         s390_bfp_binop_t tag;
493         HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
494         HReg         dst_lo; /* 128-bit result low part */
495         HReg         op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
496         HReg         op2_lo; /* 128-bit operand low part */
497      } bfp_binop;
498      struct {
499         s390_bfp_unop_t  tag;
500         HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
501         HReg         dst_lo; /* 128-bit result low part */
502         HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
503         HReg         op_lo;  /* 128-bit operand low part */
504      } bfp_unop;
505      struct {
506         s390_bfp_conv_t  tag;
507         s390_bfp_round_t rounding_mode;
508         HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
509         HReg         dst_lo; /* 128-bit result low part */
510         HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
511         HReg         op_lo;  /* 128-bit operand low part */
512      } bfp_convert;
513      struct {
514         HReg         dst;     /* condition code in s390 encoding */
515         HReg         op1_hi;  /* 128-bit operand high part; 32/64-bit opnd */
516         HReg         op1_lo;  /* 128-bit operand low part */
517         HReg         op2_hi;  /* 128-bit operand high part; 32/64-bit opnd */
518         HReg         op2_lo;  /* 128-bit operand low part */
519      } bfp_compare;
520      struct {
521         s390_dfp_binop *details;
522      } dfp_binop;
523      struct {
524         s390_dfp_unop_t tag;
525         HReg         dst_hi; /* 128-bit result high part; 64-bit result */
526         HReg         dst_lo; /* 128-bit result low part */
527         HReg         op_hi;  /* 128-bit operand high part; 64-bit opnd */
528         HReg         op_lo;  /* 128-bit operand low part */
529      } dfp_unop;
530      struct {
531         s390_dfp_intop_t tag;
532         HReg         dst_hi; /* 128-bit result high part; 64-bit result */
533         HReg         dst_lo; /* 128-bit result low part */
534         HReg         op2;    /* integer operand */
535         HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd */
536         HReg         op3_lo; /* 128-bit operand low part */
537      } dfp_intop;
538      struct {
539         s390_dfp_conv_t  tag;
540         s390_dfp_round_t rounding_mode;
541         HReg         dst_hi; /* 128-bit result high part; 64-bit result */
542         HReg         dst_lo; /* 128-bit result low part */
543         HReg         op_hi;  /* 128-bit operand high part; 64-bit opnd */
544         HReg         op_lo;  /* 128-bit operand low part */
545      } dfp_convert;
546      struct {
547         s390_fp_convert *details;
548      } fp_convert;
549      struct {
550         s390_dfp_cmp_t tag;
551         HReg         dst;     /* condition code in s390 encoding */
552         HReg         op1_hi;  /* 128-bit operand high part; 64-bit opnd 1 */
553         HReg         op1_lo;  /* 128-bit operand low part */
554         HReg         op2_hi;  /* 128-bit operand high part; 64-bit opnd 2 */
555         HReg         op2_lo;  /* 128-bit operand low part */
556      } dfp_compare;
557      struct {
558         s390_dfp_round_t rounding_mode;
559         HReg         dst_hi; /* 128-bit result high part; 64-bit result */
560         HReg         dst_lo; /* 128-bit result low part */
561         HReg         op2;    /* integer operand */
562         HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd */
563         HReg         op3_lo; /* 128-bit operand low part */
564      } dfp_reround;
565
566      /* Miscellaneous */
567      struct {
568         s390_amode      *dst;
569         ULong            value;  /* sign extended */
570      } mimm;
571      struct {
572         s390_amode      *dst;
573         UChar            delta;
574         ULong            value;  /* for debugging only */
575      } madd;
576      struct {
577         HReg             mode;
578      } set_fpc_bfprm;
579      struct {
580         HReg             mode;
581      } set_fpc_dfprm;
582
583      /* The next 5 entries are generic to support translation chaining */
584
585      /* Update the guest IA value, then exit requesting to chain
586         to it.  May be conditional. */
587      struct {
588         s390_cc_t     cond;
589         Bool          to_fast_entry;  /* chain to the what entry point? */
590         Addr64        dst;            /* next guest address */
591         s390_amode   *guest_IA;
592      } xdirect;
593      /* Boring transfer to a guest address not known at JIT time.
594         Not chainable.  May be conditional. */
595      struct {
596         s390_cc_t     cond;
597         HReg          dst;
598         s390_amode   *guest_IA;
599      } xindir;
600      /* Assisted transfer to a guest address, most general case.
601         Not chainable.  May be conditional. */
602      struct {
603         s390_cc_t     cond;
604         IRJumpKind    kind;
605         HReg          dst;
606         s390_amode   *guest_IA;
607      } xassisted;
608      struct {
609         /* fixs390: I don't think these are really needed
610            as the gsp and the offset are fixed  no ? */
611         s390_amode   *counter;    /* dispatch counter */
612         s390_amode   *fail_addr;
613      } evcheck;
614      struct {
615         /* No fields.  The address of the counter to increment is
616            installed later, post-translation, by patching it in,
617            as it is not known at translation time. */
618      } profinc;
619
620   } variant;
621} s390_insn;
622
623s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
624s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
625s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
626s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src);
627s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
628                               s390_opnd_RMI src);
629s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
630s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
631                         s390_opnd_RMI op2);
632s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
633                         s390_opnd_RMI op2, Bool signed_multiply);
634s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
635                         s390_opnd_RMI op2, Bool signed_divide);
636s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
637s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
638                         s390_opnd_RMI op);
639s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
640                         HReg old);
641s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
642                          s390_amode *op2, HReg op3_high, HReg op3_low,
643                          HReg old_high, HReg old_low, HReg scratch);
644s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
645                          s390_opnd_RMI opnd);
646s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
647s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
648s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
649                             Bool signed_comparison);
650s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
651                                 const HChar *name, RetLoc rloc);
652s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
653                               HReg op2, HReg op3);
654s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
655                               HReg op2);
656s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
657                              HReg op);
658s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
659s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
660                                 HReg op, s390_bfp_round_t);
661s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
662                                  HReg dst_lo, HReg op2_hi, HReg op2_lo);
663s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
664                                 HReg dst_lo, HReg op_hi, HReg op_lo);
665s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
666                                    HReg op1_lo, HReg op2_hi, HReg op2_lo);
667s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
668                                       HReg dst_hi, HReg dst_lo, HReg op);
669s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t,
670                                         HReg dst_hi, HReg dst_lo, HReg op_hi,
671                                         HReg op_lo, s390_bfp_round_t);
672s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
673                               HReg op2, HReg op3,
674                               s390_dfp_round_t rounding_mode);
675s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op);
676s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst,
677                               HReg op2, HReg op3);
678s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst,
679                                 HReg op1, HReg op2);
680s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
681                                 HReg op, s390_dfp_round_t);
682s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
683                                 s390_dfp_round_t);
684s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag,
685                                HReg dst, HReg op, HReg r1, s390_dfp_round_t);
686s390_insn *s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag,
687                                   HReg dst_hi, HReg dst_lo, HReg op_hi,
688                                   HReg op_lo, HReg r1, s390_dfp_round_t);
689s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
690                                  HReg dst_lo, HReg op2_hi, HReg op2_lo,
691                                  HReg op3_hi, HReg op3_lo,
692                                  s390_dfp_round_t rounding_mode);
693s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst,
694                                 HReg op_hi, HReg op_lo);
695s390_insn *s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t, HReg dst_hi,
696                                  HReg dst_lo, HReg op2,
697                                  HReg op3_hi, HReg op3_lo);
698s390_insn *s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t, HReg dst,
699                                    HReg op1_hi, HReg op1_lo, HReg op2_hi,
700                                    HReg op2_lo);
701s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
702                                       HReg dst_hi, HReg dst_lo, HReg op);
703s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
704                                         HReg dst_hi, HReg dst_lo, HReg op_hi,
705                                         HReg op_lo, s390_dfp_round_t);
706s390_insn *s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo,
707                                    HReg op2, HReg op3_hi, HReg op3_lo,
708                                    s390_dfp_round_t);
709s390_insn *s390_insn_mfence(void);
710s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value);
711s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
712                          ULong value);
713s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
714s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
715
716/* Five for translation chaining */
717s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
718                             Bool to_fast_entry);
719s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
720s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
721                               IRJumpKind kind);
722s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
723s390_insn *s390_insn_profinc(void);
724
725const HChar *s390_insn_as_string(const s390_insn *);
726
727/*--------------------------------------------------------*/
728/* --- Interface exposed to VEX                       --- */
729/*--------------------------------------------------------*/
730
731void ppS390AMode(const s390_amode *);
732void ppS390Instr(const s390_insn *, Bool mode64);
733void ppHRegS390(HReg);
734
735/* Some functions that insulate the register allocator from details
736   of the underlying instruction set. */
737void  getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool );
738void  mapRegs_S390Instr    ( HRegRemap *, s390_insn *, Bool );
739Bool  isMove_S390Instr     ( const s390_insn *, HReg *, HReg * );
740Int   emit_S390Instr       ( Bool *, UChar *, Int, const s390_insn *, Bool,
741                             VexEndness, const void *, const void *,
742                             const void *, const void *);
743const RRegUniverse *getRRegUniverse_S390( void );
744void  genSpill_S390        ( HInstr **, HInstr **, HReg , Int , Bool );
745void  genReload_S390       ( HInstr **, HInstr **, HReg , Int , Bool );
746HInstrArray *iselSB_S390   ( const IRSB *, VexArch, const VexArchInfo *,
747                             const VexAbiInfo *, Int, Int, Bool, Bool, Addr);
748
749/* Return the number of bytes of code needed for an event check */
750Int evCheckSzB_S390(void);
751
752/* Perform a chaining and unchaining of an XDirect jump. */
753VexInvalRange chainXDirect_S390(VexEndness endness_host,
754                                void *place_to_chain,
755                                const void *disp_cp_chain_me_EXPECTED,
756                                const void *place_to_jump_to);
757
758VexInvalRange unchainXDirect_S390(VexEndness endness_host,
759                                  void *place_to_unchain,
760                                  const void *place_to_jump_to_EXPECTED,
761                                  const void *disp_cp_chain_me);
762
763/* Patch the counter location into an existing ProfInc point. */
764VexInvalRange patchProfInc_S390(VexEndness endness_host,
765                                void  *code_to_patch,
766                                const ULong *location_of_counter);
767
768/* KLUDGE: See detailled comment in host_s390_defs.c. */
769extern UInt s390_host_hwcaps;
770
771/* Convenience macros to test installed facilities */
772#define s390_host_has_ldisp \
773                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
774#define s390_host_has_eimm \
775                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
776#define s390_host_has_gie \
777                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
778#define s390_host_has_dfp \
779                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
780#define s390_host_has_fgx \
781                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
782#define s390_host_has_etf2 \
783                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
784#define s390_host_has_stfle \
785                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
786#define s390_host_has_etf3 \
787                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
788#define s390_host_has_stckf \
789                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
790#define s390_host_has_fpext \
791                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
792#define s390_host_has_lsc \
793                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
794#define s390_host_has_pfpo \
795                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO))
796
797#endif /* ndef __VEX_HOST_S390_DEFS_H */
798
799/*---------------------------------------------------------------*/
800/*--- end                                    host_s390_defs.h ---*/
801/*---------------------------------------------------------------*/
802