sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 | |
sewardj | 89ae847 | 2013-10-18 14:12:58 +0000 | [diff] [blame^] | 11 | Copyright IBM Corp. 2010-2013 |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 38 | #include "host_generic_regs.h" /* HReg */ |
florian | b0b6710 | 2012-12-24 00:14:31 +0000 | [diff] [blame] | 39 | #include "s390_defs.h" /* s390_cc_t */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 40 | |
| 41 | /* --------- Registers --------- */ |
| 42 | const HChar *s390_hreg_as_string(HReg); |
| 43 | |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 44 | /* Dedicated registers */ |
| 45 | HReg 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, ... */ |
florian | ffbd84d | 2012-12-09 02:06:29 +0000 | [diff] [blame] | 51 | static __inline__ UInt |
| 52 | s390_gprno_from_arg_index(UInt ix) |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 | |
| 67 | typedef enum { |
| 68 | S390_AMODE_B12, |
| 69 | S390_AMODE_B20, |
| 70 | S390_AMODE_BX12, |
| 71 | S390_AMODE_BX20 |
| 72 | } s390_amode_t; |
| 73 | |
florian | b4df768 | 2011-07-05 02:09:01 +0000 | [diff] [blame] | 74 | typedef struct { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 | |
| 82 | s390_amode *s390_amode_b12(Int d, HReg b); |
| 83 | s390_amode *s390_amode_b20(Int d, HReg b); |
| 84 | s390_amode *s390_amode_bx12(Int d, HReg b, HReg x); |
| 85 | s390_amode *s390_amode_bx20(Int d, HReg b, HReg x); |
| 86 | s390_amode *s390_amode_for_guest_state(Int d); |
| 87 | Bool s390_amode_is_sane(const s390_amode *); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 88 | |
| 89 | const HChar *s390_amode_as_string(const s390_amode *); |
| 90 | |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 91 | /* ------------- 2nd (right) operand of binary operation ---------------- */ |
| 92 | |
| 93 | typedef 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 */ |
| 107 | typedef 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 */ |
| 118 | typedef 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 */ |
florian | cec3a8a | 2013-02-02 00:16:58 +0000 | [diff] [blame] | 122 | S390_INSN_MEMCPY, /* from memory to memory */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 123 | S390_INSN_COND_MOVE, /* conditonal "move" to register */ |
| 124 | S390_INSN_LOAD_IMMEDIATE, |
| 125 | S390_INSN_ALU, |
florian | c4aa7ed | 2012-12-22 15:01:04 +0000 | [diff] [blame] | 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 */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 130 | S390_INSN_DIVS, /* n-bit dividend; n-bit divisor; n-bit quot/rem */ |
sewardj | 611b06e | 2011-03-24 08:57:29 +0000 | [diff] [blame] | 131 | S390_INSN_CLZ, /* count left-most zeroes */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 136 | S390_INSN_HELPER_CALL, |
| 137 | S390_INSN_CAS, /* compare and swap */ |
florian | 448cbba | 2012-06-06 02:26:01 +0000 | [diff] [blame] | 138 | S390_INSN_CDAS, /* compare double and swap */ |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 139 | S390_INSN_BFP_BINOP, /* Binary floating point */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 140 | S390_INSN_BFP_UNOP, |
| 141 | S390_INSN_BFP_TRIOP, |
| 142 | S390_INSN_BFP_COMPARE, |
florian | 9fcff4c | 2012-09-10 03:09:04 +0000 | [diff] [blame] | 143 | S390_INSN_BFP_CONVERT, |
florian | 1239020 | 2012-11-10 22:34:14 +0000 | [diff] [blame] | 144 | S390_INSN_DFP_BINOP, /* Decimal floating point */ |
florian | ce9e3db | 2012-12-27 20:14:03 +0000 | [diff] [blame] | 145 | S390_INSN_DFP_UNOP, |
florian | 1b901d4 | 2013-01-01 22:19:24 +0000 | [diff] [blame] | 146 | S390_INSN_DFP_INTOP, |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 147 | S390_INSN_DFP_COMPARE, |
| 148 | S390_INSN_DFP_CONVERT, |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 149 | S390_INSN_DFP_REROUND, |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 150 | S390_INSN_FP_CONVERT, |
florian | ad43b3a | 2012-02-20 15:01:14 +0000 | [diff] [blame] | 151 | S390_INSN_MFENCE, |
florian | b93348d | 2012-12-27 00:59:43 +0000 | [diff] [blame] | 152 | S390_INSN_MIMM, /* Assign an immediate constant to a memory location */ |
florian | f85fe3e | 2012-12-22 02:28:25 +0000 | [diff] [blame] | 153 | S390_INSN_MADD, /* Add a value to a memory location */ |
florian | 125e20d | 2012-10-07 15:42:37 +0000 | [diff] [blame] | 154 | S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */ |
florian | c8e4f56 | 2012-10-27 16:19:31 +0000 | [diff] [blame] | 155 | S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */ |
florian | 8844a63 | 2012-04-13 04:04:06 +0000 | [diff] [blame] | 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 */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 162 | } s390_insn_tag; |
| 163 | |
| 164 | |
| 165 | /* The kind of ALU instructions */ |
| 166 | typedef 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 */ |
| 180 | typedef 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 */ |
| 191 | typedef enum { |
| 192 | S390_BFP_MADD, |
| 193 | S390_BFP_MSUB, |
| 194 | } s390_bfp_triop_t; |
| 195 | |
| 196 | /* The kind of binary BFP operations */ |
| 197 | typedef enum { |
| 198 | S390_BFP_ADD, |
| 199 | S390_BFP_SUB, |
| 200 | S390_BFP_MUL, |
| 201 | S390_BFP_DIV |
| 202 | } s390_bfp_binop_t; |
| 203 | |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 204 | /* The kind of unary BFP operations */ |
| 205 | typedef enum { |
| 206 | S390_BFP_ABS, |
| 207 | S390_BFP_NABS, |
| 208 | S390_BFP_NEG, |
florian | 9fcff4c | 2012-09-10 03:09:04 +0000 | [diff] [blame] | 209 | S390_BFP_SQRT |
| 210 | } s390_bfp_unop_t; |
| 211 | |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 212 | /* Type conversion operations: to and/or from binary floating point */ |
florian | 9fcff4c | 2012-09-10 03:09:04 +0000 | [diff] [blame] | 213 | typedef enum { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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, |
florian | 1c8f7ff | 2012-09-01 00:12:11 +0000 | [diff] [blame] | 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, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 226 | S390_BFP_F32_TO_I32, |
| 227 | S390_BFP_F32_TO_I64, |
florian | 1c8f7ff | 2012-09-01 00:12:11 +0000 | [diff] [blame] | 228 | S390_BFP_F32_TO_U32, |
| 229 | S390_BFP_F32_TO_U64, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 230 | S390_BFP_F32_TO_F64, |
| 231 | S390_BFP_F32_TO_F128, |
| 232 | S390_BFP_F64_TO_I32, |
| 233 | S390_BFP_F64_TO_I64, |
florian | 1c8f7ff | 2012-09-01 00:12:11 +0000 | [diff] [blame] | 234 | S390_BFP_F64_TO_U32, |
| 235 | S390_BFP_F64_TO_U64, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 236 | S390_BFP_F64_TO_F32, |
| 237 | S390_BFP_F64_TO_F128, |
| 238 | S390_BFP_F128_TO_I32, |
| 239 | S390_BFP_F128_TO_I64, |
florian | 1c8f7ff | 2012-09-01 00:12:11 +0000 | [diff] [blame] | 240 | S390_BFP_F128_TO_U32, |
| 241 | S390_BFP_F128_TO_U64, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 242 | S390_BFP_F128_TO_F32, |
| 243 | S390_BFP_F128_TO_F64 |
florian | 6dc9024 | 2012-12-21 21:43:00 +0000 | [diff] [blame] | 244 | } s390_bfp_conv_t; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 245 | |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 246 | /* Type conversion operations: to and/or from decimal floating point */ |
| 247 | typedef enum { |
| 248 | S390_DFP_D32_TO_D64, |
| 249 | S390_DFP_D64_TO_D32, |
| 250 | S390_DFP_D64_TO_D128, |
florian | 5f03462 | 2013-01-13 02:29:05 +0000 | [diff] [blame] | 251 | S390_DFP_D128_TO_D64, |
| 252 | S390_DFP_I32_TO_D64, |
| 253 | S390_DFP_I32_TO_D128, |
florian | a887acd | 2013-02-08 23:32:54 +0000 | [diff] [blame] | 254 | S390_DFP_I64_TO_D64, |
| 255 | S390_DFP_I64_TO_D128, |
florian | 5f03462 | 2013-01-13 02:29:05 +0000 | [diff] [blame] | 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, |
florian | a887acd | 2013-02-08 23:32:54 +0000 | [diff] [blame] | 261 | S390_DFP_D64_TO_I64, |
florian | 5f03462 | 2013-01-13 02:29:05 +0000 | [diff] [blame] | 262 | S390_DFP_D64_TO_U32, |
| 263 | S390_DFP_D64_TO_U64, |
| 264 | S390_DFP_D128_TO_I32, |
florian | a887acd | 2013-02-08 23:32:54 +0000 | [diff] [blame] | 265 | S390_DFP_D128_TO_I64, |
florian | 5f03462 | 2013-01-13 02:29:05 +0000 | [diff] [blame] | 266 | S390_DFP_D128_TO_U32, |
| 267 | S390_DFP_D128_TO_U64 |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 268 | } s390_dfp_conv_t; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 269 | |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 270 | typedef enum { |
florian | 7ab421d | 2013-06-17 21:03:56 +0000 | [diff] [blame] | 271 | S390_FP_F32_TO_D32, |
| 272 | S390_FP_F32_TO_D64, |
| 273 | S390_FP_F32_TO_D128, |
| 274 | S390_FP_F64_TO_D32, |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 275 | S390_FP_F64_TO_D64, |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 276 | S390_FP_F64_TO_D128, |
florian | 7ab421d | 2013-06-17 21:03:56 +0000 | [diff] [blame] | 277 | S390_FP_F128_TO_D32, |
| 278 | S390_FP_F128_TO_D64, |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 279 | S390_FP_F128_TO_D128, |
florian | 7ab421d | 2013-06-17 21:03:56 +0000 | [diff] [blame] | 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, |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 288 | S390_FP_D128_TO_F128 |
| 289 | } s390_fp_conv_t; |
| 290 | |
florian | 1239020 | 2012-11-10 22:34:14 +0000 | [diff] [blame] | 291 | /* The kind of binary DFP operations */ |
| 292 | typedef enum { |
| 293 | S390_DFP_ADD, |
| 294 | S390_DFP_SUB, |
| 295 | S390_DFP_MUL, |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 296 | S390_DFP_DIV, |
| 297 | S390_DFP_QUANTIZE |
florian | 1239020 | 2012-11-10 22:34:14 +0000 | [diff] [blame] | 298 | } s390_dfp_binop_t; |
| 299 | |
florian | ce9e3db | 2012-12-27 20:14:03 +0000 | [diff] [blame] | 300 | /* The kind of unary DFP operations */ |
| 301 | typedef enum { |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 302 | S390_DFP_EXTRACT_EXP_D64, |
| 303 | S390_DFP_EXTRACT_EXP_D128, |
florian | ce9e3db | 2012-12-27 20:14:03 +0000 | [diff] [blame] | 304 | S390_DFP_EXTRACT_SIG_D64, |
| 305 | S390_DFP_EXTRACT_SIG_D128, |
| 306 | } s390_dfp_unop_t; |
| 307 | |
florian | 1b901d4 | 2013-01-01 22:19:24 +0000 | [diff] [blame] | 308 | /* The DFP operations with 2 operands one of them being integer */ |
| 309 | typedef enum { |
| 310 | S390_DFP_SHIFT_LEFT, |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 311 | S390_DFP_SHIFT_RIGHT, |
| 312 | S390_DFP_INSERT_EXP |
florian | 1b901d4 | 2013-01-01 22:19:24 +0000 | [diff] [blame] | 313 | } s390_dfp_intop_t; |
| 314 | |
florian | 20c6bca | 2012-12-26 17:47:19 +0000 | [diff] [blame] | 315 | /* The kind of DFP compare operations */ |
| 316 | typedef enum { |
| 317 | S390_DFP_COMPARE, |
| 318 | S390_DFP_COMPARE_EXP, |
| 319 | } s390_dfp_cmp_t; |
| 320 | |
florian | c4aa7ed | 2012-12-22 15:01:04 +0000 | [diff] [blame] | 321 | /* The details of a CDAS insn. Carved out to keep the size of |
| 322 | s390_insn low */ |
| 323 | typedef 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 */ |
| 336 | typedef 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 | |
florian | b4df768 | 2011-07-05 02:09:01 +0000 | [diff] [blame] | 347 | typedef struct { |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 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 | |
sewardj | 74142b8 | 2013-08-08 10:28:59 +0000 | [diff] [blame] | 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. */ |
| 363 | typedef 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 | |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 371 | typedef struct { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 372 | s390_insn_tag tag; |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 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; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 { |
florian | cec3a8a | 2013-02-02 00:16:58 +0000 | [diff] [blame] | 392 | s390_amode *dst; |
| 393 | s390_amode *src; |
| 394 | } memcpy; |
| 395 | struct { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 411 | HReg dst_hi; /* r10 */ |
| 412 | HReg dst_lo; /* also op1 r11 */ |
| 413 | s390_opnd_RMI op2; |
| 414 | } mul; |
| 415 | struct { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 { |
sewardj | 611b06e | 2011-03-24 08:57:29 +0000 | [diff] [blame] | 426 | HReg num_bits; /* number of leftmost '0' bits r10 */ |
| 427 | HReg clobber; /* unspecified r11 */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 428 | s390_opnd_RMI src; |
sewardj | 611b06e | 2011-03-24 08:57:29 +0000 | [diff] [blame] | 429 | } clz; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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 { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 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; |
florian | 448cbba | 2012-06-06 02:26:01 +0000 | [diff] [blame] | 454 | struct { |
florian | c4aa7ed | 2012-12-22 15:01:04 +0000 | [diff] [blame] | 455 | s390_cdas *details; |
florian | 448cbba | 2012-06-06 02:26:01 +0000 | [diff] [blame] | 456 | } cdas; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 457 | struct { |
sewardj | 74142b8 | 2013-08-08 10:28:59 +0000 | [diff] [blame] | 458 | s390_helper_call *details; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 459 | } helper_call; |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 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 |
florian | 2c74d24 | 2012-09-12 19:38:42 +0000 | [diff] [blame] | 469 | e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 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. */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 483 | struct { |
| 484 | s390_bfp_triop_t tag; |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 485 | HReg dst; |
| 486 | HReg op2; |
| 487 | HReg op3; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 488 | } bfp_triop; |
| 489 | struct { |
| 490 | s390_bfp_binop_t tag; |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 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 */ |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 495 | } bfp_binop; |
| 496 | struct { |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 497 | s390_bfp_unop_t tag; |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 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; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 503 | struct { |
florian | 6dc9024 | 2012-12-21 21:43:00 +0000 | [diff] [blame] | 504 | s390_bfp_conv_t tag; |
florian | 125e20d | 2012-10-07 15:42:37 +0000 | [diff] [blame] | 505 | s390_bfp_round_t rounding_mode; |
florian | 9fcff4c | 2012-09-10 03:09:04 +0000 | [diff] [blame] | 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 */ |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 510 | } bfp_convert; |
florian | 9fcff4c | 2012-09-10 03:09:04 +0000 | [diff] [blame] | 511 | struct { |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 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; |
florian | 1239020 | 2012-11-10 22:34:14 +0000 | [diff] [blame] | 518 | struct { |
florian | c4aa7ed | 2012-12-22 15:01:04 +0000 | [diff] [blame] | 519 | s390_dfp_binop *details; |
florian | 1239020 | 2012-11-10 22:34:14 +0000 | [diff] [blame] | 520 | } dfp_binop; |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 521 | struct { |
florian | ce9e3db | 2012-12-27 20:14:03 +0000 | [diff] [blame] | 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 { |
florian | 1b901d4 | 2013-01-01 22:19:24 +0000 | [diff] [blame] | 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 { |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 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 { |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 545 | s390_fp_convert *details; |
| 546 | } fp_convert; |
| 547 | struct { |
florian | 20c6bca | 2012-12-26 17:47:19 +0000 | [diff] [blame] | 548 | s390_dfp_cmp_t tag; |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 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; |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 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; |
florian | cc491a6 | 2012-09-10 23:44:37 +0000 | [diff] [blame] | 563 | |
| 564 | /* Miscellaneous */ |
florian | ad43b3a | 2012-02-20 15:01:14 +0000 | [diff] [blame] | 565 | struct { |
florian | 09bbba8 | 2012-12-11 04:09:43 +0000 | [diff] [blame] | 566 | s390_amode *dst; |
florian | b93348d | 2012-12-27 00:59:43 +0000 | [diff] [blame] | 567 | ULong value; /* sign extended */ |
| 568 | } mimm; |
florian | ad43b3a | 2012-02-20 15:01:14 +0000 | [diff] [blame] | 569 | struct { |
florian | f85fe3e | 2012-12-22 02:28:25 +0000 | [diff] [blame] | 570 | s390_amode *dst; |
florian | ad43b3a | 2012-02-20 15:01:14 +0000 | [diff] [blame] | 571 | UChar delta; |
| 572 | ULong value; /* for debugging only */ |
florian | f85fe3e | 2012-12-22 02:28:25 +0000 | [diff] [blame] | 573 | } madd; |
florian | 2c74d24 | 2012-09-12 19:38:42 +0000 | [diff] [blame] | 574 | struct { |
| 575 | HReg mode; |
florian | 125e20d | 2012-10-07 15:42:37 +0000 | [diff] [blame] | 576 | } set_fpc_bfprm; |
florian | c8e4f56 | 2012-10-27 16:19:31 +0000 | [diff] [blame] | 577 | struct { |
| 578 | HReg mode; |
| 579 | } set_fpc_dfprm; |
florian | 8844a63 | 2012-04-13 04:04:06 +0000 | [diff] [blame] | 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 | |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 618 | } variant; |
| 619 | } s390_insn; |
| 620 | |
| 621 | s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src); |
| 622 | s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src); |
| 623 | s390_insn *s390_insn_move(UChar size, HReg dst, HReg src); |
florian | cec3a8a | 2013-02-02 00:16:58 +0000 | [diff] [blame] | 624 | s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 625 | s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst, |
| 626 | s390_opnd_RMI src); |
| 627 | s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val); |
| 628 | s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst, |
| 629 | s390_opnd_RMI op2); |
| 630 | s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo, |
| 631 | s390_opnd_RMI op2, Bool signed_multiply); |
| 632 | s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo, |
| 633 | s390_opnd_RMI op2, Bool signed_divide); |
| 634 | s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2); |
sewardj | 611b06e | 2011-03-24 08:57:29 +0000 | [diff] [blame] | 635 | s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber, |
| 636 | s390_opnd_RMI op); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 637 | s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3, |
| 638 | HReg old); |
florian | 448cbba | 2012-06-06 02:26:01 +0000 | [diff] [blame] | 639 | s390_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); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 642 | s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst, |
| 643 | s390_opnd_RMI opnd); |
| 644 | s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src); |
| 645 | s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src); |
| 646 | s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd, |
| 647 | Bool signed_comparison); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 648 | s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args, |
sewardj | 74142b8 | 2013-08-08 10:28:59 +0000 | [diff] [blame] | 649 | const HChar *name, RetLoc rloc); |
florian | 2c74d24 | 2012-09-12 19:38:42 +0000 | [diff] [blame] | 650 | s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst, |
| 651 | HReg op2, HReg op3); |
| 652 | s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst, |
| 653 | HReg op2); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 654 | s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst, |
florian | 2c74d24 | 2012-09-12 19:38:42 +0000 | [diff] [blame] | 655 | HReg op); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 656 | s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2); |
florian | 6dc9024 | 2012-12-21 21:43:00 +0000 | [diff] [blame] | 657 | s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst, |
florian | 125e20d | 2012-10-07 15:42:37 +0000 | [diff] [blame] | 658 | HReg op, s390_bfp_round_t); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 659 | s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi, |
florian | 2c74d24 | 2012-09-12 19:38:42 +0000 | [diff] [blame] | 660 | HReg dst_lo, HReg op2_hi, HReg op2_lo); |
sewardj | a970c40 | 2011-04-28 18:38:42 +0000 | [diff] [blame] | 661 | s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi, |
florian | 2c74d24 | 2012-09-12 19:38:42 +0000 | [diff] [blame] | 662 | HReg dst_lo, HReg op_hi, HReg op_lo); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 663 | s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi, |
| 664 | HReg op1_lo, HReg op2_hi, HReg op2_lo); |
florian | 6dc9024 | 2012-12-21 21:43:00 +0000 | [diff] [blame] | 665 | s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 666 | HReg dst_hi, HReg dst_lo, HReg op); |
florian | 6dc9024 | 2012-12-21 21:43:00 +0000 | [diff] [blame] | 667 | s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t, |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 668 | HReg dst, HReg op_hi, HReg op_lo, |
florian | 125e20d | 2012-10-07 15:42:37 +0000 | [diff] [blame] | 669 | s390_bfp_round_t); |
florian | 1239020 | 2012-11-10 22:34:14 +0000 | [diff] [blame] | 670 | s390_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); |
florian | ce9e3db | 2012-12-27 20:14:03 +0000 | [diff] [blame] | 673 | s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op); |
florian | 1b901d4 | 2013-01-01 22:19:24 +0000 | [diff] [blame] | 674 | s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst, |
| 675 | HReg op2, HReg op3); |
florian | 20c6bca | 2012-12-26 17:47:19 +0000 | [diff] [blame] | 676 | s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst, |
| 677 | HReg op1, HReg op2); |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 678 | s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst, |
| 679 | HReg op, s390_dfp_round_t); |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 680 | s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3, |
| 681 | s390_dfp_round_t); |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 682 | s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag, |
| 683 | HReg dst, HReg op, HReg r1, s390_dfp_round_t); |
| 684 | s390_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); |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 687 | s390_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); |
florian | ce9e3db | 2012-12-27 20:14:03 +0000 | [diff] [blame] | 691 | s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst, |
| 692 | HReg op_hi, HReg op_lo); |
florian | 1b901d4 | 2013-01-01 22:19:24 +0000 | [diff] [blame] | 693 | s390_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); |
florian | 20c6bca | 2012-12-26 17:47:19 +0000 | [diff] [blame] | 696 | s390_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); |
florian | e38f641 | 2012-12-21 17:32:12 +0000 | [diff] [blame] | 699 | s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t, |
| 700 | HReg dst_hi, HReg dst_lo, HReg op); |
| 701 | s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t, |
| 702 | HReg dst, HReg op_hi, HReg op_lo, |
| 703 | s390_dfp_round_t); |
florian | 5c53973 | 2013-02-14 14:27:12 +0000 | [diff] [blame] | 704 | s390_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); |
sewardj | a52e37e | 2011-04-28 18:48:06 +0000 | [diff] [blame] | 707 | s390_insn *s390_insn_mfence(void); |
florian | b93348d | 2012-12-27 00:59:43 +0000 | [diff] [blame] | 708 | s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value); |
florian | f85fe3e | 2012-12-22 02:28:25 +0000 | [diff] [blame] | 709 | s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta, |
| 710 | ULong value); |
florian | 125e20d | 2012-10-07 15:42:37 +0000 | [diff] [blame] | 711 | s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode); |
florian | c8e4f56 | 2012-10-27 16:19:31 +0000 | [diff] [blame] | 712 | s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 713 | |
florian | 8844a63 | 2012-04-13 04:04:06 +0000 | [diff] [blame] | 714 | /* Five for translation chaining */ |
| 715 | s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA, |
| 716 | Bool to_fast_entry); |
| 717 | s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA); |
| 718 | s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA, |
| 719 | IRJumpKind kind); |
| 720 | s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr); |
| 721 | s390_insn *s390_insn_profinc(void); |
| 722 | |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 723 | const HChar *s390_insn_as_string(const s390_insn *); |
| 724 | |
| 725 | /*--------------------------------------------------------*/ |
| 726 | /* --- Interface exposed to VEX --- */ |
| 727 | /*--------------------------------------------------------*/ |
| 728 | |
florian | b4df768 | 2011-07-05 02:09:01 +0000 | [diff] [blame] | 729 | void ppS390AMode(s390_amode *); |
| 730 | void ppS390Instr(s390_insn *, Bool mode64); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 731 | void ppHRegS390(HReg); |
| 732 | |
| 733 | /* Some functions that insulate the register allocator from details |
| 734 | of the underlying instruction set. */ |
florian | b4df768 | 2011-07-05 02:09:01 +0000 | [diff] [blame] | 735 | void getRegUsage_S390Instr( HRegUsage *, s390_insn *, Bool ); |
| 736 | void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool ); |
| 737 | Bool isMove_S390Instr ( s390_insn *, HReg *, HReg * ); |
florian | 8844a63 | 2012-04-13 04:04:06 +0000 | [diff] [blame] | 738 | Int emit_S390Instr ( Bool *, UChar *, Int, s390_insn *, Bool, |
| 739 | void *, void *, void *, void *); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 740 | void getAllocableRegs_S390( Int *, HReg **, Bool ); |
| 741 | void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool ); |
| 742 | void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool ); |
florian | b4df768 | 2011-07-05 02:09:01 +0000 | [diff] [blame] | 743 | s390_insn *directReload_S390 ( s390_insn *, HReg, Short ); |
florian | 8844a63 | 2012-04-13 04:04:06 +0000 | [diff] [blame] | 744 | HInstrArray *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 */ |
| 748 | Int evCheckSzB_S390(void); |
| 749 | |
| 750 | /* Perform a chaining and unchaining of an XDirect jump. */ |
| 751 | VexInvalRange chainXDirect_S390(void *place_to_chain, |
| 752 | void *disp_cp_chain_me_EXPECTED, |
| 753 | void *place_to_jump_to); |
| 754 | |
| 755 | VexInvalRange 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. */ |
| 760 | VexInvalRange patchProfInc_S390(void *code_to_patch, |
| 761 | ULong *location_of_counter); |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 762 | |
| 763 | /* KLUDGE: See detailled comment in host_s390_defs.c. */ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 764 | extern UInt s390_host_hwcaps; |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 765 | |
| 766 | /* Convenience macros to test installed facilities */ |
sewardj | 652b56a | 2011-04-13 15:38:17 +0000 | [diff] [blame] | 767 | #define s390_host_has_ldisp \ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 768 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP)) |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 769 | #define s390_host_has_eimm \ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 770 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM)) |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 771 | #define s390_host_has_gie \ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 772 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE)) |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 773 | #define s390_host_has_dfp \ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 774 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP)) |
sewardj | d07b856 | 2011-04-27 11:58:22 +0000 | [diff] [blame] | 775 | #define s390_host_has_fgx \ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 776 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX)) |
florian | 9af3769 | 2012-01-15 21:01:16 +0000 | [diff] [blame] | 777 | #define s390_host_has_etf2 \ |
florian | f26994a | 2012-04-21 03:34:54 +0000 | [diff] [blame] | 778 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2)) |
florian | 90ece04 | 2012-04-21 15:41:51 +0000 | [diff] [blame] | 779 | #define s390_host_has_stfle \ |
| 780 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE)) |
florian | 79bee4b | 2012-05-03 01:30:48 +0000 | [diff] [blame] | 781 | #define s390_host_has_etf3 \ |
| 782 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3)) |
florian | a4c3669 | 2012-08-26 04:22:33 +0000 | [diff] [blame] | 783 | #define s390_host_has_stckf \ |
| 784 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF)) |
florian | 60b665b | 2012-08-30 20:28:00 +0000 | [diff] [blame] | 785 | #define s390_host_has_fpext \ |
| 786 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT)) |
florian | aec8e05 | 2012-12-09 17:26:32 +0000 | [diff] [blame] | 787 | #define s390_host_has_lsc \ |
| 788 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC)) |
florian | 78d5ef7 | 2013-05-11 15:02:58 +0000 | [diff] [blame] | 789 | #define s390_host_has_pfpo \ |
| 790 | (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO)) |
sewardj | 2019a97 | 2011-03-07 16:04:07 +0000 | [diff] [blame] | 791 | |
| 792 | #endif /* ndef __VEX_HOST_S390_DEFS_H */ |
| 793 | |
| 794 | /*---------------------------------------------------------------*/ |
| 795 | /*--- end host_s390_defs.h ---*/ |
| 796 | /*---------------------------------------------------------------*/ |