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-2015
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 /* Contributed by Florian Krohm */
32
33 #ifndef __VEX_HOST_S390_DEFS_H
34 #define __VEX_HOST_S390_DEFS_H
35
36 #include "libvex_basictypes.h" /* Bool */
37 #include "libvex.h" /* VexArchInfo */
38 #include "host_generic_regs.h" /* HReg */
39 #include "s390_defs.h" /* s390_cc_t */
40
41 /* --------- Registers --------- */
42 const HChar *s390_hreg_as_string(HReg);
43 HReg s390_hreg_gpr(UInt regno);
44 HReg s390_hreg_fpr(UInt regno);
45
46 /* Dedicated registers */
47 HReg 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, ... */
53 static __inline__ UInt
s390_gprno_from_arg_index(UInt ix)54 s390_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
69 typedef enum {
70 S390_AMODE_B12,
71 S390_AMODE_B20,
72 S390_AMODE_BX12,
73 S390_AMODE_BX20
74 } s390_amode_t;
75
76 typedef 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
84 s390_amode *s390_amode_b12(Int d, HReg b);
85 s390_amode *s390_amode_b20(Int d, HReg b);
86 s390_amode *s390_amode_bx12(Int d, HReg b, HReg x);
87 s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
88 s390_amode *s390_amode_for_guest_state(Int d);
89 Bool s390_amode_is_sane(const s390_amode *);
90
91 const HChar *s390_amode_as_string(const s390_amode *);
92
93 /* ------------- 2nd (right) operand of binary operation ---------------- */
94
95 typedef 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 */
109 typedef 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 */
120 typedef 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 */
168 typedef 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 */
182 typedef 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 */
193 typedef enum {
194 S390_BFP_MADD,
195 S390_BFP_MSUB,
196 } s390_bfp_triop_t;
197
198 /* The kind of binary BFP operations */
199 typedef 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 */
207 typedef 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 */
215 typedef 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 */
252 typedef 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
275 typedef 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 */
297 typedef 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 */
306 typedef 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 */
314 typedef 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 */
321 typedef 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 */
328 typedef 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 */
341 typedef 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
352 typedef 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. */
368 typedef 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
376 typedef 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
626 s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
627 s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
628 s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
629 s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src);
630 s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
631 s390_opnd_RMI src);
632 s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
633 s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
634 s390_opnd_RMI op2);
635 s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
636 s390_opnd_RMI op2, Bool signed_multiply);
637 s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
638 s390_opnd_RMI op2, Bool signed_divide);
639 s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
640 s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
641 s390_opnd_RMI op);
642 s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
643 HReg old);
644 s390_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);
647 s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
648 s390_opnd_RMI opnd);
649 s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
650 s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
651 s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
652 Bool signed_comparison);
653 s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
654 const HChar *name, RetLoc rloc);
655 s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
656 HReg op2, HReg op3);
657 s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
658 HReg op2);
659 s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
660 HReg op);
661 s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
662 s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
663 HReg op, s390_bfp_round_t);
664 s390_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);
667 s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
668 HReg dst_lo, HReg op2_hi, HReg op2_lo);
669 s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
670 HReg dst_lo, HReg op_hi, HReg op_lo);
671 s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
672 HReg op1_lo, HReg op2_hi, HReg op2_lo);
673 s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
674 HReg dst_hi, HReg dst_lo, HReg op);
675 s390_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);
678 s390_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);
681 s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op);
682 s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst,
683 HReg op2, HReg op3);
684 s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst,
685 HReg op1, HReg op2);
686 s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
687 HReg op, s390_dfp_round_t);
688 s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
689 s390_dfp_round_t);
690 s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag,
691 HReg dst, HReg op, HReg r1, s390_dfp_round_t);
692 s390_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);
695 s390_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);
699 s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst,
700 HReg op_hi, HReg op_lo);
701 s390_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);
704 s390_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);
707 s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
708 HReg dst_hi, HReg dst_lo, HReg op);
709 s390_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);
712 s390_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);
715 s390_insn *s390_insn_mfence(void);
716 s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value);
717 s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
718 ULong value);
719 s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
720 s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
721
722 /* Five for translation chaining */
723 s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
724 Bool to_fast_entry);
725 s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
726 s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
727 IRJumpKind kind);
728 s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
729 s390_insn *s390_insn_profinc(void);
730
731 const HChar *s390_insn_as_string(const s390_insn *);
732
733 /*--------------------------------------------------------*/
734 /* --- Interface exposed to VEX --- */
735 /*--------------------------------------------------------*/
736
737 void ppS390AMode(const s390_amode *);
738 void ppS390Instr(const s390_insn *, Bool mode64);
739 void ppHRegS390(HReg);
740
741 /* Some functions that insulate the register allocator from details
742 of the underlying instruction set. */
743 void getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool );
744 void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool );
745 Bool isMove_S390Instr ( const s390_insn *, HReg *, HReg * );
746 Int emit_S390Instr ( Bool *, UChar *, Int, const s390_insn *, Bool,
747 VexEndness, const void *, const void *,
748 const void *, const void *);
749 const RRegUniverse *getRRegUniverse_S390( void );
750 void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
751 void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
752 HInstrArray *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 */
756 Int evCheckSzB_S390(void);
757
758 /* Perform a chaining and unchaining of an XDirect jump. */
759 VexInvalRange 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
764 VexInvalRange 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. */
770 VexInvalRange 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. */
775 extern 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