1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*---------------------------------------------------------------*/
4 /*--- begin host_s390_defs.h ---*/
5 /*---------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright IBM Corp. 2010-2011
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
31 /* Contributed by Florian Krohm */
33 #ifndef __VEX_HOST_S390_DEFS_H
34 #define __VEX_HOST_S390_DEFS_H
36 #include "libvex_basictypes.h" /* Bool */
37 #include "libvex.h" /* VexArchInfo */
38 #include "main_util.h" /* needed for host_generic_regs.h */
39 #include "host_generic_regs.h" /* HReg */
41 /* --------- Registers --------- */
42 const HChar *s390_hreg_as_string(HReg);
44 void s390_hreg_get_allocable(Int *nregs, HReg **arr);
46 /* Dedicated registers */
47 HReg s390_hreg_guest_state_pointer(void);
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__ unsigned
54 s390_gprno_from_arg_index(unsigned ix)
59 /* --------- Memory address expressions (amodes). --------- */
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
76 typedef struct s390_amode {
79 HReg x; /* hregNumber(x) == 0 for S390_AMODE_B12/B20 kinds */
80 Int d; /* 12 bit unsigned or 20 bit signed */
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 void s390_amode_get_reg_usage(HRegUsage *, const s390_amode *);
91 void s390_amode_map_regs(HRegRemap *, s390_amode *);
93 const HChar *s390_amode_as_string(const s390_amode *);
97 /* ------------- 2nd (right) operand of binary operation ---------------- */
106 /* Naming convention for operand locations:
109 M - memory (any Amode may be used)
112 /* An operand that is either in a GPR or is addressable via a BX20 amode */
123 /* The kind of instructions */
125 S390_INSN_LOAD, /* load register from memory */
126 S390_INSN_STORE, /* store register to memory */
127 S390_INSN_MOVE, /* from register to register */
128 S390_INSN_COND_MOVE, /* conditonal "move" to register */
129 S390_INSN_LOAD_IMMEDIATE,
131 S390_INSN_MUL, /* n-bit operands; 2n-bit result */
132 S390_INSN_DIV, /* 2n-bit dividend; n-bit divisor; n-bit quot/rem */
133 S390_INSN_DIVS, /* n-bit dividend; n-bit divisor; n-bit quot/rem */
134 S390_INSN_CLZ, /* count left-most zeroes */
136 S390_INSN_TEST, /* test operand and set cc */
137 S390_INSN_CC2BOOL,/* convert condition code to 0/1 */
139 S390_INSN_BRANCH, /* un/conditional goto */
140 S390_INSN_HELPER_CALL,
141 S390_INSN_CAS, /* compare and swap */
142 S390_INSN_BFP_BINOP, /* Binary floating point 32-bit / 64-bit */
145 S390_INSN_BFP_COMPARE,
146 S390_INSN_BFP128_BINOP, /* Binary floating point 128-bit */
147 S390_INSN_BFP128_UNOP,
148 S390_INSN_BFP128_COMPARE,
149 S390_INSN_BFP128_CONVERT_TO,
150 S390_INSN_BFP128_CONVERT_FROM,
155 /* The kind of ALU instructions */
159 S390_ALU_MUL, /* n-bit operands; result is lower n-bit of product */
165 S390_ALU_RSHA /* arithmetic */
169 /* The kind of unary integer operations */
180 /* The kind of ternary BFP operations */
186 /* The kind of binary BFP operations */
195 /* The kind of unary BFP operations */
203 S390_BFP_I32_TO_F128,
206 S390_BFP_I64_TO_F128,
210 S390_BFP_F32_TO_F128,
214 S390_BFP_F64_TO_F128,
215 S390_BFP_F128_TO_I32,
216 S390_BFP_F128_TO_I64,
217 S390_BFP_F128_TO_F32,
222 /* Condition code. The encoding of the enumerators matches the value of
223 the mask field in the various branch opcodes. */
226 S390_CC_OVFL = 1, /* overflow */
227 S390_CC_H = 2, /* A > B ; high */
228 S390_CC_NLE = 3, /* not low or equal */
229 S390_CC_L = 4, /* A < B ; low */
230 S390_CC_NHE = 5, /* not high or equal */
231 S390_CC_LH = 6, /* low or high */
232 S390_CC_NE = 7, /* A != B ; not zero */
233 S390_CC_E = 8, /* A == B ; zero */
234 S390_CC_NLH = 9, /* not low or high */
235 S390_CC_HE = 10, /* A >= B ; high or equal*/
236 S390_CC_NL = 11, /* not low */
237 S390_CC_LE = 12, /* A <= B ; low or equal */
238 S390_CC_NH = 13, /* not high */
239 S390_CC_NO = 14, /* not overflow */
244 /* Rounding mode as it is encoded in the m3/m4 fields of certain
245 instructions (e.g. CFEBR) */
247 /* S390_ROUND_NEAREST_AWAY = 1, not supported */
248 S390_ROUND_NEAREST_EVEN = 4,
250 S390_ROUND_POSINF = 6,
251 S390_ROUND_NEGINF = 7
255 /* Invert the condition code */
256 static __inline__ s390_cc_t
257 s390_cc_invert(s390_cc_t cond)
259 return S390_CC_ALWAYS - cond;
263 typedef struct s390_insn {
265 UChar size; /* size of the result in bytes */
286 ULong value; /* not sign extended */
288 /* add, and, or, xor */
295 Bool signed_multiply;
296 HReg dst_hi; /* r10 */
297 HReg dst_lo; /* also op1 r11 */
302 HReg op1_hi; /* also remainder r10 */
303 HReg op1_lo; /* also quotient r11 */
307 HReg rem; /* remainder r10 */
308 HReg op1; /* also quotient r11 */
312 HReg num_bits; /* number of leftmost '0' bits r10 */
313 HReg clobber; /* unspecified r11 */
322 Bool signed_comparison;
327 HReg dst; /* condition code in s390 encoding */
334 /* Convert the condition code to a boolean value. */
350 /* Pseudo-insn for representing a helper call.
351 TARGET is the absolute address of the helper function
352 NUM_ARGS says how many arguments are being passed.
353 All arguments have integer type and are being passed according to ABI,
354 i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
355 passed in r2 and so forth. */
360 HChar *name; /* callee's name (for debugging) */
363 s390_bfp_triop_t tag;
364 s390_round_t rounding_mode;
365 HReg dst; /* first operand */
366 HReg op2; /* second operand */
367 HReg op3; /* third operand */
370 s390_bfp_binop_t tag;
371 s390_round_t rounding_mode;
372 HReg dst; /* left operand */
373 HReg op2; /* right operand */
377 s390_round_t rounding_mode;
378 HReg dst; /* result */
379 HReg op; /* operand */
382 s390_bfp_binop_t tag;
383 s390_round_t rounding_mode;
384 HReg dst_hi; /* left operand; high part */
385 HReg dst_lo; /* left operand; low part */
386 HReg op2_hi; /* right operand; high part */
387 HReg op2_lo; /* right operand; low part */
389 /* This variant is also used by the BFP128_CONVERT_TO and
390 BFP128_CONVERT_FROM insns. */
393 s390_round_t rounding_mode;
394 HReg dst_hi; /* result; high part */
395 HReg dst_lo; /* result; low part */
396 HReg op_hi; /* operand; high part */
397 HReg op_lo; /* operand; low part */
400 HReg dst; /* condition code in s390 encoding */
401 HReg op1_hi; /* left operand; high part */
402 HReg op1_lo; /* left operand; low part */
403 HReg op2_hi; /* right operand; high part */
404 HReg op2_lo; /* right operand; low part */
409 s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
410 s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
411 s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
412 s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
414 s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
415 s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
417 s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
418 s390_opnd_RMI op2, Bool signed_multiply);
419 s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
420 s390_opnd_RMI op2, Bool signed_divide);
421 s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
422 s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
424 s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
426 s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
428 s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
429 s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
430 s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
431 Bool signed_comparison);
432 s390_insn *s390_insn_branch(IRJumpKind jk, s390_cc_t cond, s390_opnd_RMI dst);
433 s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
435 s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst, HReg op2,
436 HReg op3, s390_round_t);
437 s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst, HReg op2,
439 s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
440 HReg op, s390_round_t);
441 s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
442 s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
443 HReg dst_lo, HReg op2_hi, HReg op2_lo,
445 s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
446 HReg dst_lo, HReg op_hi, HReg op_lo,
448 s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
449 HReg op1_lo, HReg op2_hi, HReg op2_lo);
450 s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_unop_t,
451 HReg dst_hi, HReg dst_lo, HReg op);
452 s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_unop_t,
453 HReg dst, HReg op_hi, HReg op_lo,
455 s390_insn *s390_insn_mfence(void);
456 void s390_insn_map_regs(HRegRemap *, s390_insn *);
457 Bool s390_insn_is_reg_reg_move(const s390_insn *, HReg *, HReg *);
458 void s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *);
459 UInt s390_insn_emit(UChar *buf, Int nbuf, const struct s390_insn *insn,
462 const HChar *s390_insn_as_string(const s390_insn *);
464 /*--------------------------------------------------------*/
465 /* --- Interface exposed to VEX --- */
466 /*--------------------------------------------------------*/
468 void ppS390AMode(struct s390_amode *);
469 void ppS390Instr(struct s390_insn *, Bool mode64);
470 void ppHRegS390(HReg);
472 /* Some functions that insulate the register allocator from details
473 of the underlying instruction set. */
474 void getRegUsage_S390Instr( HRegUsage *, struct s390_insn *, Bool );
475 void mapRegs_S390Instr ( HRegRemap *, struct s390_insn *, Bool );
476 Bool isMove_S390Instr ( struct s390_insn *, HReg *, HReg * );
477 Int emit_S390Instr ( UChar *, Int, struct s390_insn *, Bool, void * );
478 void getAllocableRegs_S390( Int *, HReg **, Bool );
479 void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
480 void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
481 struct s390_insn *directReload_S390 ( struct s390_insn *, HReg, Short );
482 HInstrArray *iselSB_S390 ( IRSB *, VexArch, VexArchInfo *, VexAbiInfo * );
484 /* KLUDGE: See detailled comment in host_s390_defs.c. */
485 extern const VexArchInfo *s390_archinfo_host;
487 /* Convenience macros to test installed facilities */
488 #define s390_host_has_ldisp \
489 (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_LDISP))
490 #define s390_host_has_eimm \
491 (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_EIMM))
492 #define s390_host_has_gie \
493 (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_GIE))
494 #define s390_host_has_dfp \
495 (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_DFP))
496 #define s390_host_has_fgx \
497 (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_FGX))
499 #endif /* ndef __VEX_HOST_S390_DEFS_H */
501 /*---------------------------------------------------------------*/
502 /*--- end host_s390_defs.h ---*/
503 /*---------------------------------------------------------------*/