]> git.proxmox.com Git - mirror_qemu.git/blob - tcg/s390/tcg-target.inc.c
2faa761e7822c2058dd662778417992c6c29142d
[mirror_qemu.git] / tcg / s390 / tcg-target.inc.c
1 /*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 #include "tcg-be-ldst.h"
28
29 /* We only support generating code for 64-bit mode. */
30 #if TCG_TARGET_REG_BITS != 64
31 #error "unsupported code generation mode"
32 #endif
33
34 #include "elf.h"
35
36 /* ??? The translation blocks produced by TCG are generally small enough to
37 be entirely reachable with a 16-bit displacement. Leaving the option for
38 a 32-bit displacement here Just In Case. */
39 #define USE_LONG_BRANCHES 0
40
41 #define TCG_CT_CONST_MULI 0x100
42 #define TCG_CT_CONST_ORI 0x200
43 #define TCG_CT_CONST_XORI 0x400
44 #define TCG_CT_CONST_CMPI 0x800
45 #define TCG_CT_CONST_ADLI 0x1000
46
47 /* Several places within the instruction set 0 means "no register"
48 rather than TCG_REG_R0. */
49 #define TCG_REG_NONE 0
50
51 /* A scratch register that may be be used throughout the backend. */
52 #define TCG_TMP0 TCG_REG_R14
53
54 #ifndef CONFIG_SOFTMMU
55 #define TCG_GUEST_BASE_REG TCG_REG_R13
56 #endif
57
58 /* All of the following instructions are prefixed with their instruction
59 format, and are defined as 8- or 16-bit quantities, even when the two
60 halves of the 16-bit quantity may appear 32 bits apart in the insn.
61 This makes it easy to copy the values from the tables in Appendix B. */
62 typedef enum S390Opcode {
63 RIL_AFI = 0xc209,
64 RIL_AGFI = 0xc208,
65 RIL_ALFI = 0xc20b,
66 RIL_ALGFI = 0xc20a,
67 RIL_BRASL = 0xc005,
68 RIL_BRCL = 0xc004,
69 RIL_CFI = 0xc20d,
70 RIL_CGFI = 0xc20c,
71 RIL_CLFI = 0xc20f,
72 RIL_CLGFI = 0xc20e,
73 RIL_IIHF = 0xc008,
74 RIL_IILF = 0xc009,
75 RIL_LARL = 0xc000,
76 RIL_LGFI = 0xc001,
77 RIL_LGRL = 0xc408,
78 RIL_LLIHF = 0xc00e,
79 RIL_LLILF = 0xc00f,
80 RIL_LRL = 0xc40d,
81 RIL_MSFI = 0xc201,
82 RIL_MSGFI = 0xc200,
83 RIL_NIHF = 0xc00a,
84 RIL_NILF = 0xc00b,
85 RIL_OIHF = 0xc00c,
86 RIL_OILF = 0xc00d,
87 RIL_SLFI = 0xc205,
88 RIL_SLGFI = 0xc204,
89 RIL_XIHF = 0xc006,
90 RIL_XILF = 0xc007,
91
92 RI_AGHI = 0xa70b,
93 RI_AHI = 0xa70a,
94 RI_BRC = 0xa704,
95 RI_IIHH = 0xa500,
96 RI_IIHL = 0xa501,
97 RI_IILH = 0xa502,
98 RI_IILL = 0xa503,
99 RI_LGHI = 0xa709,
100 RI_LLIHH = 0xa50c,
101 RI_LLIHL = 0xa50d,
102 RI_LLILH = 0xa50e,
103 RI_LLILL = 0xa50f,
104 RI_MGHI = 0xa70d,
105 RI_MHI = 0xa70c,
106 RI_NIHH = 0xa504,
107 RI_NIHL = 0xa505,
108 RI_NILH = 0xa506,
109 RI_NILL = 0xa507,
110 RI_OIHH = 0xa508,
111 RI_OIHL = 0xa509,
112 RI_OILH = 0xa50a,
113 RI_OILL = 0xa50b,
114
115 RIE_CGIJ = 0xec7c,
116 RIE_CGRJ = 0xec64,
117 RIE_CIJ = 0xec7e,
118 RIE_CLGRJ = 0xec65,
119 RIE_CLIJ = 0xec7f,
120 RIE_CLGIJ = 0xec7d,
121 RIE_CLRJ = 0xec77,
122 RIE_CRJ = 0xec76,
123 RIE_RISBG = 0xec55,
124
125 RRE_AGR = 0xb908,
126 RRE_ALGR = 0xb90a,
127 RRE_ALCR = 0xb998,
128 RRE_ALCGR = 0xb988,
129 RRE_CGR = 0xb920,
130 RRE_CLGR = 0xb921,
131 RRE_DLGR = 0xb987,
132 RRE_DLR = 0xb997,
133 RRE_DSGFR = 0xb91d,
134 RRE_DSGR = 0xb90d,
135 RRE_LGBR = 0xb906,
136 RRE_LCGR = 0xb903,
137 RRE_LGFR = 0xb914,
138 RRE_LGHR = 0xb907,
139 RRE_LGR = 0xb904,
140 RRE_LLGCR = 0xb984,
141 RRE_LLGFR = 0xb916,
142 RRE_LLGHR = 0xb985,
143 RRE_LRVR = 0xb91f,
144 RRE_LRVGR = 0xb90f,
145 RRE_LTGR = 0xb902,
146 RRE_MLGR = 0xb986,
147 RRE_MSGR = 0xb90c,
148 RRE_MSR = 0xb252,
149 RRE_NGR = 0xb980,
150 RRE_OGR = 0xb981,
151 RRE_SGR = 0xb909,
152 RRE_SLGR = 0xb90b,
153 RRE_SLBR = 0xb999,
154 RRE_SLBGR = 0xb989,
155 RRE_XGR = 0xb982,
156
157 RRF_LOCR = 0xb9f2,
158 RRF_LOCGR = 0xb9e2,
159
160 RR_AR = 0x1a,
161 RR_ALR = 0x1e,
162 RR_BASR = 0x0d,
163 RR_BCR = 0x07,
164 RR_CLR = 0x15,
165 RR_CR = 0x19,
166 RR_DR = 0x1d,
167 RR_LCR = 0x13,
168 RR_LR = 0x18,
169 RR_LTR = 0x12,
170 RR_NR = 0x14,
171 RR_OR = 0x16,
172 RR_SR = 0x1b,
173 RR_SLR = 0x1f,
174 RR_XR = 0x17,
175
176 RSY_RLL = 0xeb1d,
177 RSY_RLLG = 0xeb1c,
178 RSY_SLLG = 0xeb0d,
179 RSY_SRAG = 0xeb0a,
180 RSY_SRLG = 0xeb0c,
181
182 RS_SLL = 0x89,
183 RS_SRA = 0x8a,
184 RS_SRL = 0x88,
185
186 RXY_AG = 0xe308,
187 RXY_AY = 0xe35a,
188 RXY_CG = 0xe320,
189 RXY_CY = 0xe359,
190 RXY_LAY = 0xe371,
191 RXY_LB = 0xe376,
192 RXY_LG = 0xe304,
193 RXY_LGB = 0xe377,
194 RXY_LGF = 0xe314,
195 RXY_LGH = 0xe315,
196 RXY_LHY = 0xe378,
197 RXY_LLGC = 0xe390,
198 RXY_LLGF = 0xe316,
199 RXY_LLGH = 0xe391,
200 RXY_LMG = 0xeb04,
201 RXY_LRV = 0xe31e,
202 RXY_LRVG = 0xe30f,
203 RXY_LRVH = 0xe31f,
204 RXY_LY = 0xe358,
205 RXY_STCY = 0xe372,
206 RXY_STG = 0xe324,
207 RXY_STHY = 0xe370,
208 RXY_STMG = 0xeb24,
209 RXY_STRV = 0xe33e,
210 RXY_STRVG = 0xe32f,
211 RXY_STRVH = 0xe33f,
212 RXY_STY = 0xe350,
213
214 RX_A = 0x5a,
215 RX_C = 0x59,
216 RX_L = 0x58,
217 RX_LA = 0x41,
218 RX_LH = 0x48,
219 RX_ST = 0x50,
220 RX_STC = 0x42,
221 RX_STH = 0x40,
222
223 NOP = 0x0707,
224 } S390Opcode;
225
226 #ifdef CONFIG_DEBUG_TCG
227 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
228 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
229 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
230 };
231 #endif
232
233 /* Since R6 is a potential argument register, choose it last of the
234 call-saved registers. Likewise prefer the call-clobbered registers
235 in reverse order to maximize the chance of avoiding the arguments. */
236 static const int tcg_target_reg_alloc_order[] = {
237 /* Call saved registers. */
238 TCG_REG_R13,
239 TCG_REG_R12,
240 TCG_REG_R11,
241 TCG_REG_R10,
242 TCG_REG_R9,
243 TCG_REG_R8,
244 TCG_REG_R7,
245 TCG_REG_R6,
246 /* Call clobbered registers. */
247 TCG_REG_R14,
248 TCG_REG_R0,
249 TCG_REG_R1,
250 /* Argument registers, in reverse order of allocation. */
251 TCG_REG_R5,
252 TCG_REG_R4,
253 TCG_REG_R3,
254 TCG_REG_R2,
255 };
256
257 static const int tcg_target_call_iarg_regs[] = {
258 TCG_REG_R2,
259 TCG_REG_R3,
260 TCG_REG_R4,
261 TCG_REG_R5,
262 TCG_REG_R6,
263 };
264
265 static const int tcg_target_call_oarg_regs[] = {
266 TCG_REG_R2,
267 };
268
269 #define S390_CC_EQ 8
270 #define S390_CC_LT 4
271 #define S390_CC_GT 2
272 #define S390_CC_OV 1
273 #define S390_CC_NE (S390_CC_LT | S390_CC_GT)
274 #define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
275 #define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
276 #define S390_CC_NEVER 0
277 #define S390_CC_ALWAYS 15
278
279 /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
280 static const uint8_t tcg_cond_to_s390_cond[] = {
281 [TCG_COND_EQ] = S390_CC_EQ,
282 [TCG_COND_NE] = S390_CC_NE,
283 [TCG_COND_LT] = S390_CC_LT,
284 [TCG_COND_LE] = S390_CC_LE,
285 [TCG_COND_GT] = S390_CC_GT,
286 [TCG_COND_GE] = S390_CC_GE,
287 [TCG_COND_LTU] = S390_CC_LT,
288 [TCG_COND_LEU] = S390_CC_LE,
289 [TCG_COND_GTU] = S390_CC_GT,
290 [TCG_COND_GEU] = S390_CC_GE,
291 };
292
293 /* Condition codes that result from a LOAD AND TEST. Here, we have no
294 unsigned instruction variation, however since the test is vs zero we
295 can re-map the outcomes appropriately. */
296 static const uint8_t tcg_cond_to_ltr_cond[] = {
297 [TCG_COND_EQ] = S390_CC_EQ,
298 [TCG_COND_NE] = S390_CC_NE,
299 [TCG_COND_LT] = S390_CC_LT,
300 [TCG_COND_LE] = S390_CC_LE,
301 [TCG_COND_GT] = S390_CC_GT,
302 [TCG_COND_GE] = S390_CC_GE,
303 [TCG_COND_LTU] = S390_CC_NEVER,
304 [TCG_COND_LEU] = S390_CC_EQ,
305 [TCG_COND_GTU] = S390_CC_NE,
306 [TCG_COND_GEU] = S390_CC_ALWAYS,
307 };
308
309 #ifdef CONFIG_SOFTMMU
310 static void * const qemu_ld_helpers[16] = {
311 [MO_UB] = helper_ret_ldub_mmu,
312 [MO_SB] = helper_ret_ldsb_mmu,
313 [MO_LEUW] = helper_le_lduw_mmu,
314 [MO_LESW] = helper_le_ldsw_mmu,
315 [MO_LEUL] = helper_le_ldul_mmu,
316 [MO_LESL] = helper_le_ldsl_mmu,
317 [MO_LEQ] = helper_le_ldq_mmu,
318 [MO_BEUW] = helper_be_lduw_mmu,
319 [MO_BESW] = helper_be_ldsw_mmu,
320 [MO_BEUL] = helper_be_ldul_mmu,
321 [MO_BESL] = helper_be_ldsl_mmu,
322 [MO_BEQ] = helper_be_ldq_mmu,
323 };
324
325 static void * const qemu_st_helpers[16] = {
326 [MO_UB] = helper_ret_stb_mmu,
327 [MO_LEUW] = helper_le_stw_mmu,
328 [MO_LEUL] = helper_le_stl_mmu,
329 [MO_LEQ] = helper_le_stq_mmu,
330 [MO_BEUW] = helper_be_stw_mmu,
331 [MO_BEUL] = helper_be_stl_mmu,
332 [MO_BEQ] = helper_be_stq_mmu,
333 };
334 #endif
335
336 static tcg_insn_unit *tb_ret_addr;
337 uint64_t s390_facilities;
338
339 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
340 intptr_t value, intptr_t addend)
341 {
342 intptr_t pcrel2 = (tcg_insn_unit *)value - (code_ptr - 1);
343 tcg_debug_assert(addend == -2);
344
345 switch (type) {
346 case R_390_PC16DBL:
347 tcg_debug_assert(pcrel2 == (int16_t)pcrel2);
348 tcg_patch16(code_ptr, pcrel2);
349 break;
350 case R_390_PC32DBL:
351 tcg_debug_assert(pcrel2 == (int32_t)pcrel2);
352 tcg_patch32(code_ptr, pcrel2);
353 break;
354 default:
355 tcg_abort();
356 break;
357 }
358 }
359
360 /* parse target specific constraints */
361 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
362 {
363 const char *ct_str = *pct_str;
364
365 switch (ct_str[0]) {
366 case 'r': /* all registers */
367 ct->ct |= TCG_CT_REG;
368 tcg_regset_set32(ct->u.regs, 0, 0xffff);
369 break;
370 case 'L': /* qemu_ld/st constraint */
371 ct->ct |= TCG_CT_REG;
372 tcg_regset_set32(ct->u.regs, 0, 0xffff);
373 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2);
374 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
375 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
376 break;
377 case 'a': /* force R2 for division */
378 ct->ct |= TCG_CT_REG;
379 tcg_regset_clear(ct->u.regs);
380 tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
381 break;
382 case 'b': /* force R3 for division */
383 ct->ct |= TCG_CT_REG;
384 tcg_regset_clear(ct->u.regs);
385 tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
386 break;
387 case 'A':
388 ct->ct |= TCG_CT_CONST_ADLI;
389 break;
390 case 'K':
391 ct->ct |= TCG_CT_CONST_MULI;
392 break;
393 case 'O':
394 ct->ct |= TCG_CT_CONST_ORI;
395 break;
396 case 'X':
397 ct->ct |= TCG_CT_CONST_XORI;
398 break;
399 case 'C':
400 ct->ct |= TCG_CT_CONST_CMPI;
401 break;
402 default:
403 return -1;
404 }
405 ct_str++;
406 *pct_str = ct_str;
407
408 return 0;
409 }
410
411 /* Immediates to be used with logical OR. This is an optimization only,
412 since a full 64-bit immediate OR can always be performed with 4 sequential
413 OI[LH][LH] instructions. What we're looking for is immediates that we
414 can load efficiently, and the immediate load plus the reg-reg OR is
415 smaller than the sequential OI's. */
416
417 static int tcg_match_ori(TCGType type, tcg_target_long val)
418 {
419 if (s390_facilities & FACILITY_EXT_IMM) {
420 if (type == TCG_TYPE_I32) {
421 /* All 32-bit ORs can be performed with 1 48-bit insn. */
422 return 1;
423 }
424 }
425
426 /* Look for negative values. These are best to load with LGHI. */
427 if (val < 0) {
428 if (val == (int16_t)val) {
429 return 0;
430 }
431 if (s390_facilities & FACILITY_EXT_IMM) {
432 if (val == (int32_t)val) {
433 return 0;
434 }
435 }
436 }
437
438 return 1;
439 }
440
441 /* Immediates to be used with logical XOR. This is almost, but not quite,
442 only an optimization. XOR with immediate is only supported with the
443 extended-immediate facility. That said, there are a few patterns for
444 which it is better to load the value into a register first. */
445
446 static int tcg_match_xori(TCGType type, tcg_target_long val)
447 {
448 if ((s390_facilities & FACILITY_EXT_IMM) == 0) {
449 return 0;
450 }
451
452 if (type == TCG_TYPE_I32) {
453 /* All 32-bit XORs can be performed with 1 48-bit insn. */
454 return 1;
455 }
456
457 /* Look for negative values. These are best to load with LGHI. */
458 if (val < 0 && val == (int32_t)val) {
459 return 0;
460 }
461
462 return 1;
463 }
464
465 /* Imediates to be used with comparisons. */
466
467 static int tcg_match_cmpi(TCGType type, tcg_target_long val)
468 {
469 if (s390_facilities & FACILITY_EXT_IMM) {
470 /* The COMPARE IMMEDIATE instruction is available. */
471 if (type == TCG_TYPE_I32) {
472 /* We have a 32-bit immediate and can compare against anything. */
473 return 1;
474 } else {
475 /* ??? We have no insight here into whether the comparison is
476 signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
477 signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
478 a 32-bit unsigned immediate. If we were to use the (semi)
479 obvious "val == (int32_t)val" we would be enabling unsigned
480 comparisons vs very large numbers. The only solution is to
481 take the intersection of the ranges. */
482 /* ??? Another possible solution is to simply lie and allow all
483 constants here and force the out-of-range values into a temp
484 register in tgen_cmp when we have knowledge of the actual
485 comparison code in use. */
486 return val >= 0 && val <= 0x7fffffff;
487 }
488 } else {
489 /* Only the LOAD AND TEST instruction is available. */
490 return val == 0;
491 }
492 }
493
494 /* Immediates to be used with add2/sub2. */
495
496 static int tcg_match_add2i(TCGType type, tcg_target_long val)
497 {
498 if (s390_facilities & FACILITY_EXT_IMM) {
499 if (type == TCG_TYPE_I32) {
500 return 1;
501 } else if (val >= -0xffffffffll && val <= 0xffffffffll) {
502 return 1;
503 }
504 }
505 return 0;
506 }
507
508 /* Test if a constant matches the constraint. */
509 static int tcg_target_const_match(tcg_target_long val, TCGType type,
510 const TCGArgConstraint *arg_ct)
511 {
512 int ct = arg_ct->ct;
513
514 if (ct & TCG_CT_CONST) {
515 return 1;
516 }
517
518 if (type == TCG_TYPE_I32) {
519 val = (int32_t)val;
520 }
521
522 /* The following are mutually exclusive. */
523 if (ct & TCG_CT_CONST_MULI) {
524 /* Immediates that may be used with multiply. If we have the
525 general-instruction-extensions, then we have MULTIPLY SINGLE
526 IMMEDIATE with a signed 32-bit, otherwise we have only
527 MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
528 if (s390_facilities & FACILITY_GEN_INST_EXT) {
529 return val == (int32_t)val;
530 } else {
531 return val == (int16_t)val;
532 }
533 } else if (ct & TCG_CT_CONST_ADLI) {
534 return tcg_match_add2i(type, val);
535 } else if (ct & TCG_CT_CONST_ORI) {
536 return tcg_match_ori(type, val);
537 } else if (ct & TCG_CT_CONST_XORI) {
538 return tcg_match_xori(type, val);
539 } else if (ct & TCG_CT_CONST_CMPI) {
540 return tcg_match_cmpi(type, val);
541 }
542
543 return 0;
544 }
545
546 /* Emit instructions according to the given instruction format. */
547
548 static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
549 {
550 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
551 }
552
553 static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
554 TCGReg r1, TCGReg r2)
555 {
556 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
557 }
558
559 static void tcg_out_insn_RRF(TCGContext *s, S390Opcode op,
560 TCGReg r1, TCGReg r2, int m3)
561 {
562 tcg_out32(s, (op << 16) | (m3 << 12) | (r1 << 4) | r2);
563 }
564
565 static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
566 {
567 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
568 }
569
570 static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
571 {
572 tcg_out16(s, op | (r1 << 4));
573 tcg_out32(s, i2);
574 }
575
576 static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
577 TCGReg b2, TCGReg r3, int disp)
578 {
579 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
580 | (disp & 0xfff));
581 }
582
583 static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
584 TCGReg b2, TCGReg r3, int disp)
585 {
586 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
587 tcg_out32(s, (op & 0xff) | (b2 << 28)
588 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
589 }
590
591 #define tcg_out_insn_RX tcg_out_insn_RS
592 #define tcg_out_insn_RXY tcg_out_insn_RSY
593
594 /* Emit an opcode with "type-checking" of the format. */
595 #define tcg_out_insn(S, FMT, OP, ...) \
596 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
597
598
599 /* emit 64-bit shifts */
600 static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
601 TCGReg src, TCGReg sh_reg, int sh_imm)
602 {
603 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
604 }
605
606 /* emit 32-bit shifts */
607 static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
608 TCGReg sh_reg, int sh_imm)
609 {
610 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
611 }
612
613 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
614 {
615 if (src != dst) {
616 if (type == TCG_TYPE_I32) {
617 tcg_out_insn(s, RR, LR, dst, src);
618 } else {
619 tcg_out_insn(s, RRE, LGR, dst, src);
620 }
621 }
622 }
623
624 /* load a register with an immediate value */
625 static void tcg_out_movi(TCGContext *s, TCGType type,
626 TCGReg ret, tcg_target_long sval)
627 {
628 static const S390Opcode lli_insns[4] = {
629 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
630 };
631
632 tcg_target_ulong uval = sval;
633 int i;
634
635 if (type == TCG_TYPE_I32) {
636 uval = (uint32_t)sval;
637 sval = (int32_t)sval;
638 }
639
640 /* Try all 32-bit insns that can load it in one go. */
641 if (sval >= -0x8000 && sval < 0x8000) {
642 tcg_out_insn(s, RI, LGHI, ret, sval);
643 return;
644 }
645
646 for (i = 0; i < 4; i++) {
647 tcg_target_long mask = 0xffffull << i*16;
648 if ((uval & mask) == uval) {
649 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
650 return;
651 }
652 }
653
654 /* Try all 48-bit insns that can load it in one go. */
655 if (s390_facilities & FACILITY_EXT_IMM) {
656 if (sval == (int32_t)sval) {
657 tcg_out_insn(s, RIL, LGFI, ret, sval);
658 return;
659 }
660 if (uval <= 0xffffffff) {
661 tcg_out_insn(s, RIL, LLILF, ret, uval);
662 return;
663 }
664 if ((uval & 0xffffffff) == 0) {
665 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
666 return;
667 }
668 }
669
670 /* Try for PC-relative address load. */
671 if ((sval & 1) == 0) {
672 ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1;
673 if (off == (int32_t)off) {
674 tcg_out_insn(s, RIL, LARL, ret, off);
675 return;
676 }
677 }
678
679 /* If extended immediates are not present, then we may have to issue
680 several instructions to load the low 32 bits. */
681 if (!(s390_facilities & FACILITY_EXT_IMM)) {
682 /* A 32-bit unsigned value can be loaded in 2 insns. And given
683 that the lli_insns loop above did not succeed, we know that
684 both insns are required. */
685 if (uval <= 0xffffffff) {
686 tcg_out_insn(s, RI, LLILL, ret, uval);
687 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
688 return;
689 }
690
691 /* If all high bits are set, the value can be loaded in 2 or 3 insns.
692 We first want to make sure that all the high bits get set. With
693 luck the low 16-bits can be considered negative to perform that for
694 free, otherwise we load an explicit -1. */
695 if (sval >> 31 >> 1 == -1) {
696 if (uval & 0x8000) {
697 tcg_out_insn(s, RI, LGHI, ret, uval);
698 } else {
699 tcg_out_insn(s, RI, LGHI, ret, -1);
700 tcg_out_insn(s, RI, IILL, ret, uval);
701 }
702 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
703 return;
704 }
705 }
706
707 /* If we get here, both the high and low parts have non-zero bits. */
708
709 /* Recurse to load the lower 32-bits. */
710 tcg_out_movi(s, TCG_TYPE_I64, ret, uval & 0xffffffff);
711
712 /* Insert data into the high 32-bits. */
713 uval = uval >> 31 >> 1;
714 if (s390_facilities & FACILITY_EXT_IMM) {
715 if (uval < 0x10000) {
716 tcg_out_insn(s, RI, IIHL, ret, uval);
717 } else if ((uval & 0xffff) == 0) {
718 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
719 } else {
720 tcg_out_insn(s, RIL, IIHF, ret, uval);
721 }
722 } else {
723 if (uval & 0xffff) {
724 tcg_out_insn(s, RI, IIHL, ret, uval);
725 }
726 if (uval & 0xffff0000) {
727 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
728 }
729 }
730 }
731
732
733 /* Emit a load/store type instruction. Inputs are:
734 DATA: The register to be loaded or stored.
735 BASE+OFS: The effective address.
736 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
737 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
738
739 static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
740 TCGReg data, TCGReg base, TCGReg index,
741 tcg_target_long ofs)
742 {
743 if (ofs < -0x80000 || ofs >= 0x80000) {
744 /* Combine the low 20 bits of the offset with the actual load insn;
745 the high 44 bits must come from an immediate load. */
746 tcg_target_long low = ((ofs & 0xfffff) ^ 0x80000) - 0x80000;
747 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - low);
748 ofs = low;
749
750 /* If we were already given an index register, add it in. */
751 if (index != TCG_REG_NONE) {
752 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
753 }
754 index = TCG_TMP0;
755 }
756
757 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
758 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
759 } else {
760 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
761 }
762 }
763
764
765 /* load data without address translation or endianness conversion */
766 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
767 TCGReg base, intptr_t ofs)
768 {
769 if (type == TCG_TYPE_I32) {
770 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
771 } else {
772 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
773 }
774 }
775
776 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
777 TCGReg base, intptr_t ofs)
778 {
779 if (type == TCG_TYPE_I32) {
780 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
781 } else {
782 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
783 }
784 }
785
786 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
787 TCGReg base, intptr_t ofs)
788 {
789 return false;
790 }
791
792 /* load data from an absolute host address */
793 static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
794 {
795 intptr_t addr = (intptr_t)abs;
796
797 if ((s390_facilities & FACILITY_GEN_INST_EXT) && !(addr & 1)) {
798 ptrdiff_t disp = tcg_pcrel_diff(s, abs) >> 1;
799 if (disp == (int32_t)disp) {
800 if (type == TCG_TYPE_I32) {
801 tcg_out_insn(s, RIL, LRL, dest, disp);
802 } else {
803 tcg_out_insn(s, RIL, LGRL, dest, disp);
804 }
805 return;
806 }
807 }
808
809 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
810 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
811 }
812
813 static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
814 int msb, int lsb, int ofs, int z)
815 {
816 /* Format RIE-f */
817 tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src);
818 tcg_out16(s, (msb << 8) | (z << 7) | lsb);
819 tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff));
820 }
821
822 static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
823 {
824 if (s390_facilities & FACILITY_EXT_IMM) {
825 tcg_out_insn(s, RRE, LGBR, dest, src);
826 return;
827 }
828
829 if (type == TCG_TYPE_I32) {
830 if (dest == src) {
831 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
832 } else {
833 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
834 }
835 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
836 } else {
837 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
838 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
839 }
840 }
841
842 static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
843 {
844 if (s390_facilities & FACILITY_EXT_IMM) {
845 tcg_out_insn(s, RRE, LLGCR, dest, src);
846 return;
847 }
848
849 if (dest == src) {
850 tcg_out_movi(s, type, TCG_TMP0, 0xff);
851 src = TCG_TMP0;
852 } else {
853 tcg_out_movi(s, type, dest, 0xff);
854 }
855 if (type == TCG_TYPE_I32) {
856 tcg_out_insn(s, RR, NR, dest, src);
857 } else {
858 tcg_out_insn(s, RRE, NGR, dest, src);
859 }
860 }
861
862 static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
863 {
864 if (s390_facilities & FACILITY_EXT_IMM) {
865 tcg_out_insn(s, RRE, LGHR, dest, src);
866 return;
867 }
868
869 if (type == TCG_TYPE_I32) {
870 if (dest == src) {
871 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
872 } else {
873 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
874 }
875 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
876 } else {
877 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
878 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
879 }
880 }
881
882 static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
883 {
884 if (s390_facilities & FACILITY_EXT_IMM) {
885 tcg_out_insn(s, RRE, LLGHR, dest, src);
886 return;
887 }
888
889 if (dest == src) {
890 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
891 src = TCG_TMP0;
892 } else {
893 tcg_out_movi(s, type, dest, 0xffff);
894 }
895 if (type == TCG_TYPE_I32) {
896 tcg_out_insn(s, RR, NR, dest, src);
897 } else {
898 tcg_out_insn(s, RRE, NGR, dest, src);
899 }
900 }
901
902 static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
903 {
904 tcg_out_insn(s, RRE, LGFR, dest, src);
905 }
906
907 static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
908 {
909 tcg_out_insn(s, RRE, LLGFR, dest, src);
910 }
911
912 /* Accept bit patterns like these:
913 0....01....1
914 1....10....0
915 1..10..01..1
916 0..01..10..0
917 Copied from gcc sources. */
918 static inline bool risbg_mask(uint64_t c)
919 {
920 uint64_t lsb;
921 /* We don't change the number of transitions by inverting,
922 so make sure we start with the LSB zero. */
923 if (c & 1) {
924 c = ~c;
925 }
926 /* Reject all zeros or all ones. */
927 if (c == 0) {
928 return false;
929 }
930 /* Find the first transition. */
931 lsb = c & -c;
932 /* Invert to look for a second transition. */
933 c = ~c;
934 /* Erase the first transition. */
935 c &= -lsb;
936 /* Find the second transition, if any. */
937 lsb = c & -c;
938 /* Match if all the bits are 1's, or if c is zero. */
939 return c == -lsb;
940 }
941
942 static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
943 {
944 int msb, lsb;
945 if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
946 /* Achieve wraparound by swapping msb and lsb. */
947 msb = 64 - ctz64(~val);
948 lsb = clz64(~val) - 1;
949 } else {
950 msb = clz64(val);
951 lsb = 63 - ctz64(val);
952 }
953 tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
954 }
955
956 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
957 {
958 static const S390Opcode ni_insns[4] = {
959 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
960 };
961 static const S390Opcode nif_insns[2] = {
962 RIL_NILF, RIL_NIHF
963 };
964 uint64_t valid = (type == TCG_TYPE_I32 ? 0xffffffffull : -1ull);
965 int i;
966
967 /* Look for the zero-extensions. */
968 if ((val & valid) == 0xffffffff) {
969 tgen_ext32u(s, dest, dest);
970 return;
971 }
972 if (s390_facilities & FACILITY_EXT_IMM) {
973 if ((val & valid) == 0xff) {
974 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
975 return;
976 }
977 if ((val & valid) == 0xffff) {
978 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
979 return;
980 }
981 }
982
983 /* Try all 32-bit insns that can perform it in one go. */
984 for (i = 0; i < 4; i++) {
985 tcg_target_ulong mask = ~(0xffffull << i*16);
986 if (((val | ~valid) & mask) == mask) {
987 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
988 return;
989 }
990 }
991
992 /* Try all 48-bit insns that can perform it in one go. */
993 if (s390_facilities & FACILITY_EXT_IMM) {
994 for (i = 0; i < 2; i++) {
995 tcg_target_ulong mask = ~(0xffffffffull << i*32);
996 if (((val | ~valid) & mask) == mask) {
997 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
998 return;
999 }
1000 }
1001 }
1002 if ((s390_facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
1003 tgen_andi_risbg(s, dest, dest, val);
1004 return;
1005 }
1006
1007 /* Fall back to loading the constant. */
1008 tcg_out_movi(s, type, TCG_TMP0, val);
1009 if (type == TCG_TYPE_I32) {
1010 tcg_out_insn(s, RR, NR, dest, TCG_TMP0);
1011 } else {
1012 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1013 }
1014 }
1015
1016 static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1017 {
1018 static const S390Opcode oi_insns[4] = {
1019 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1020 };
1021 static const S390Opcode nif_insns[2] = {
1022 RIL_OILF, RIL_OIHF
1023 };
1024
1025 int i;
1026
1027 /* Look for no-op. */
1028 if (val == 0) {
1029 return;
1030 }
1031
1032 if (s390_facilities & FACILITY_EXT_IMM) {
1033 /* Try all 32-bit insns that can perform it in one go. */
1034 for (i = 0; i < 4; i++) {
1035 tcg_target_ulong mask = (0xffffull << i*16);
1036 if ((val & mask) != 0 && (val & ~mask) == 0) {
1037 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1038 return;
1039 }
1040 }
1041
1042 /* Try all 48-bit insns that can perform it in one go. */
1043 for (i = 0; i < 2; i++) {
1044 tcg_target_ulong mask = (0xffffffffull << i*32);
1045 if ((val & mask) != 0 && (val & ~mask) == 0) {
1046 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1047 return;
1048 }
1049 }
1050
1051 /* Perform the OR via sequential modifications to the high and
1052 low parts. Do this via recursion to handle 16-bit vs 32-bit
1053 masks in each half. */
1054 tgen64_ori(s, dest, val & 0x00000000ffffffffull);
1055 tgen64_ori(s, dest, val & 0xffffffff00000000ull);
1056 } else {
1057 /* With no extended-immediate facility, we don't need to be so
1058 clever. Just iterate over the insns and mask in the constant. */
1059 for (i = 0; i < 4; i++) {
1060 tcg_target_ulong mask = (0xffffull << i*16);
1061 if ((val & mask) != 0) {
1062 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1063 }
1064 }
1065 }
1066 }
1067
1068 static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1069 {
1070 /* Perform the xor by parts. */
1071 if (val & 0xffffffff) {
1072 tcg_out_insn(s, RIL, XILF, dest, val);
1073 }
1074 if (val > 0xffffffff) {
1075 tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
1076 }
1077 }
1078
1079 static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1080 TCGArg c2, bool c2const, bool need_carry)
1081 {
1082 bool is_unsigned = is_unsigned_cond(c);
1083 if (c2const) {
1084 if (c2 == 0) {
1085 if (!(is_unsigned && need_carry)) {
1086 if (type == TCG_TYPE_I32) {
1087 tcg_out_insn(s, RR, LTR, r1, r1);
1088 } else {
1089 tcg_out_insn(s, RRE, LTGR, r1, r1);
1090 }
1091 return tcg_cond_to_ltr_cond[c];
1092 }
1093 /* If we only got here because of load-and-test,
1094 and we couldn't use that, then we need to load
1095 the constant into a register. */
1096 if (!(facilities & FACILITY_EXT_IMM)) {
1097 c2 = TCG_TMP0;
1098 tcg_out_movi(s, type, c2, 0);
1099 goto do_reg;
1100 }
1101 }
1102 if (is_unsigned) {
1103 if (type == TCG_TYPE_I32) {
1104 tcg_out_insn(s, RIL, CLFI, r1, c2);
1105 } else {
1106 tcg_out_insn(s, RIL, CLGFI, r1, c2);
1107 }
1108 } else {
1109 if (type == TCG_TYPE_I32) {
1110 tcg_out_insn(s, RIL, CFI, r1, c2);
1111 } else {
1112 tcg_out_insn(s, RIL, CGFI, r1, c2);
1113 }
1114 }
1115 } else {
1116 do_reg:
1117 if (is_unsigned) {
1118 if (type == TCG_TYPE_I32) {
1119 tcg_out_insn(s, RR, CLR, r1, c2);
1120 } else {
1121 tcg_out_insn(s, RRE, CLGR, r1, c2);
1122 }
1123 } else {
1124 if (type == TCG_TYPE_I32) {
1125 tcg_out_insn(s, RR, CR, r1, c2);
1126 } else {
1127 tcg_out_insn(s, RRE, CGR, r1, c2);
1128 }
1129 }
1130 }
1131 return tcg_cond_to_s390_cond[c];
1132 }
1133
1134 static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1135 TCGReg dest, TCGReg c1, TCGArg c2, int c2const)
1136 {
1137 int cc;
1138
1139 switch (cond) {
1140 case TCG_COND_GTU:
1141 case TCG_COND_GT:
1142 do_greater:
1143 /* The result of a compare has CC=2 for GT and CC=3 unused.
1144 ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */
1145 tgen_cmp(s, type, cond, c1, c2, c2const, true);
1146 tcg_out_movi(s, type, dest, 0);
1147 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1148 return;
1149
1150 case TCG_COND_GEU:
1151 do_geu:
1152 /* We need "real" carry semantics, so use SUBTRACT LOGICAL
1153 instead of COMPARE LOGICAL. This needs an extra move. */
1154 tcg_out_mov(s, type, TCG_TMP0, c1);
1155 if (c2const) {
1156 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1157 if (type == TCG_TYPE_I32) {
1158 tcg_out_insn(s, RIL, SLFI, TCG_TMP0, c2);
1159 } else {
1160 tcg_out_insn(s, RIL, SLGFI, TCG_TMP0, c2);
1161 }
1162 } else {
1163 if (type == TCG_TYPE_I32) {
1164 tcg_out_insn(s, RR, SLR, TCG_TMP0, c2);
1165 } else {
1166 tcg_out_insn(s, RRE, SLGR, TCG_TMP0, c2);
1167 }
1168 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1169 }
1170 tcg_out_insn(s, RRE, ALCGR, dest, dest);
1171 return;
1172
1173 case TCG_COND_LEU:
1174 case TCG_COND_LTU:
1175 case TCG_COND_LT:
1176 /* Swap operands so that we can use GEU/GTU/GT. */
1177 if (c2const) {
1178 tcg_out_movi(s, type, TCG_TMP0, c2);
1179 c2 = c1;
1180 c2const = 0;
1181 c1 = TCG_TMP0;
1182 } else {
1183 TCGReg t = c1;
1184 c1 = c2;
1185 c2 = t;
1186 }
1187 if (cond == TCG_COND_LEU) {
1188 goto do_geu;
1189 }
1190 cond = tcg_swap_cond(cond);
1191 goto do_greater;
1192
1193 case TCG_COND_NE:
1194 /* X != 0 is X > 0. */
1195 if (c2const && c2 == 0) {
1196 cond = TCG_COND_GTU;
1197 goto do_greater;
1198 }
1199 break;
1200
1201 case TCG_COND_EQ:
1202 /* X == 0 is X <= 0 is 0 >= X. */
1203 if (c2const && c2 == 0) {
1204 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 0);
1205 c2 = c1;
1206 c2const = 0;
1207 c1 = TCG_TMP0;
1208 goto do_geu;
1209 }
1210 break;
1211
1212 default:
1213 break;
1214 }
1215
1216 cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);
1217 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1218 /* Emit: d = 0, t = 1, d = (cc ? t : d). */
1219 tcg_out_movi(s, TCG_TYPE_I64, dest, 0);
1220 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);
1221 tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);
1222 } else {
1223 /* Emit: d = 1; if (cc) goto over; d = 0; over: */
1224 tcg_out_movi(s, type, dest, 1);
1225 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1226 tcg_out_movi(s, type, dest, 0);
1227 }
1228 }
1229
1230 static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
1231 TCGReg c1, TCGArg c2, int c2const, TCGReg r3)
1232 {
1233 int cc;
1234 if (s390_facilities & FACILITY_LOAD_ON_COND) {
1235 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1236 tcg_out_insn(s, RRF, LOCGR, dest, r3, cc);
1237 } else {
1238 c = tcg_invert_cond(c);
1239 cc = tgen_cmp(s, type, c, c1, c2, c2const, false);
1240
1241 /* Emit: if (cc) goto over; dest = r3; over: */
1242 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1243 tcg_out_insn(s, RRE, LGR, dest, r3);
1244 }
1245 }
1246
1247 static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
1248 int ofs, int len)
1249 {
1250 int lsb = (63 - ofs);
1251 int msb = lsb - (len - 1);
1252 tcg_out_risbg(s, dest, src, msb, lsb, ofs, 0);
1253 }
1254
1255 static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
1256 int ofs, int len)
1257 {
1258 tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
1259 }
1260
1261 static void tgen_gotoi(TCGContext *s, int cc, tcg_insn_unit *dest)
1262 {
1263 ptrdiff_t off = dest - s->code_ptr;
1264 if (off == (int16_t)off) {
1265 tcg_out_insn(s, RI, BRC, cc, off);
1266 } else if (off == (int32_t)off) {
1267 tcg_out_insn(s, RIL, BRCL, cc, off);
1268 } else {
1269 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1270 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1271 }
1272 }
1273
1274 static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
1275 {
1276 if (l->has_value) {
1277 tgen_gotoi(s, cc, l->u.value_ptr);
1278 } else if (USE_LONG_BRANCHES) {
1279 tcg_out16(s, RIL_BRCL | (cc << 4));
1280 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, -2);
1281 s->code_ptr += 2;
1282 } else {
1283 tcg_out16(s, RI_BRC | (cc << 4));
1284 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, -2);
1285 s->code_ptr += 1;
1286 }
1287 }
1288
1289 static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1290 TCGReg r1, TCGReg r2, TCGLabel *l)
1291 {
1292 intptr_t off;
1293
1294 if (l->has_value) {
1295 off = l->u.value_ptr - s->code_ptr;
1296 } else {
1297 /* We need to keep the offset unchanged for retranslation. */
1298 off = s->code_ptr[1];
1299 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, -2);
1300 }
1301
1302 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1303 tcg_out16(s, off);
1304 tcg_out16(s, cc << 12 | (opc & 0xff));
1305 }
1306
1307 static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1308 TCGReg r1, int i2, TCGLabel *l)
1309 {
1310 tcg_target_long off;
1311
1312 if (l->has_value) {
1313 off = l->u.value_ptr - s->code_ptr;
1314 } else {
1315 /* We need to keep the offset unchanged for retranslation. */
1316 off = s->code_ptr[1];
1317 tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, -2);
1318 }
1319
1320 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1321 tcg_out16(s, off);
1322 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1323 }
1324
1325 static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1326 TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
1327 {
1328 int cc;
1329
1330 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1331 bool is_unsigned = is_unsigned_cond(c);
1332 bool in_range;
1333 S390Opcode opc;
1334
1335 cc = tcg_cond_to_s390_cond[c];
1336
1337 if (!c2const) {
1338 opc = (type == TCG_TYPE_I32
1339 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1340 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1341 tgen_compare_branch(s, opc, cc, r1, c2, l);
1342 return;
1343 }
1344
1345 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1346 If the immediate we've been given does not fit that range, we'll
1347 fall back to separate compare and branch instructions using the
1348 larger comparison range afforded by COMPARE IMMEDIATE. */
1349 if (type == TCG_TYPE_I32) {
1350 if (is_unsigned) {
1351 opc = RIE_CLIJ;
1352 in_range = (uint32_t)c2 == (uint8_t)c2;
1353 } else {
1354 opc = RIE_CIJ;
1355 in_range = (int32_t)c2 == (int8_t)c2;
1356 }
1357 } else {
1358 if (is_unsigned) {
1359 opc = RIE_CLGIJ;
1360 in_range = (uint64_t)c2 == (uint8_t)c2;
1361 } else {
1362 opc = RIE_CGIJ;
1363 in_range = (int64_t)c2 == (int8_t)c2;
1364 }
1365 }
1366 if (in_range) {
1367 tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
1368 return;
1369 }
1370 }
1371
1372 cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
1373 tgen_branch(s, cc, l);
1374 }
1375
1376 static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
1377 {
1378 ptrdiff_t off = dest - s->code_ptr;
1379 if (off == (int32_t)off) {
1380 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1381 } else {
1382 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)dest);
1383 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1384 }
1385 }
1386
1387 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
1388 TCGReg base, TCGReg index, int disp)
1389 {
1390 switch (opc & (MO_SSIZE | MO_BSWAP)) {
1391 case MO_UB:
1392 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1393 break;
1394 case MO_SB:
1395 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1396 break;
1397
1398 case MO_UW | MO_BSWAP:
1399 /* swapped unsigned halfword load with upper bits zeroed */
1400 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1401 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1402 break;
1403 case MO_UW:
1404 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1405 break;
1406
1407 case MO_SW | MO_BSWAP:
1408 /* swapped sign-extended halfword load */
1409 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1410 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1411 break;
1412 case MO_SW:
1413 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1414 break;
1415
1416 case MO_UL | MO_BSWAP:
1417 /* swapped unsigned int load with upper bits zeroed */
1418 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1419 tgen_ext32u(s, data, data);
1420 break;
1421 case MO_UL:
1422 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1423 break;
1424
1425 case MO_SL | MO_BSWAP:
1426 /* swapped sign-extended int load */
1427 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1428 tgen_ext32s(s, data, data);
1429 break;
1430 case MO_SL:
1431 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1432 break;
1433
1434 case MO_Q | MO_BSWAP:
1435 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1436 break;
1437 case MO_Q:
1438 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1439 break;
1440
1441 default:
1442 tcg_abort();
1443 }
1444 }
1445
1446 static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg data,
1447 TCGReg base, TCGReg index, int disp)
1448 {
1449 switch (opc & (MO_SIZE | MO_BSWAP)) {
1450 case MO_UB:
1451 if (disp >= 0 && disp < 0x1000) {
1452 tcg_out_insn(s, RX, STC, data, base, index, disp);
1453 } else {
1454 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1455 }
1456 break;
1457
1458 case MO_UW | MO_BSWAP:
1459 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1460 break;
1461 case MO_UW:
1462 if (disp >= 0 && disp < 0x1000) {
1463 tcg_out_insn(s, RX, STH, data, base, index, disp);
1464 } else {
1465 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1466 }
1467 break;
1468
1469 case MO_UL | MO_BSWAP:
1470 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1471 break;
1472 case MO_UL:
1473 if (disp >= 0 && disp < 0x1000) {
1474 tcg_out_insn(s, RX, ST, data, base, index, disp);
1475 } else {
1476 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1477 }
1478 break;
1479
1480 case MO_Q | MO_BSWAP:
1481 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1482 break;
1483 case MO_Q:
1484 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1485 break;
1486
1487 default:
1488 tcg_abort();
1489 }
1490 }
1491
1492 #if defined(CONFIG_SOFTMMU)
1493 /* We're expecting to use a 20-bit signed offset on the tlb memory ops.
1494 Using the offset of the second entry in the last tlb table ensures
1495 that we can index all of the elements of the first entry. */
1496 QEMU_BUILD_BUG_ON(offsetof(CPUArchState, tlb_table[NB_MMU_MODES - 1][1])
1497 > 0x7ffff);
1498
1499 /* Load and compare a TLB entry, leaving the flags set. Loads the TLB
1500 addend into R2. Returns a register with the santitized guest address. */
1501 static TCGReg tcg_out_tlb_read(TCGContext* s, TCGReg addr_reg, TCGMemOp opc,
1502 int mem_index, bool is_ld)
1503 {
1504 unsigned s_bits = opc & MO_SIZE;
1505 unsigned a_bits = get_alignment_bits(opc);
1506 unsigned s_mask = (1 << s_bits) - 1;
1507 unsigned a_mask = (1 << a_bits) - 1;
1508 int ofs, a_off;
1509 uint64_t tlb_mask;
1510
1511 /* For aligned accesses, we check the first byte and include the alignment
1512 bits within the address. For unaligned access, we check that we don't
1513 cross pages using the address of the last byte of the access. */
1514 a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
1515 tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1516
1517 if (s390_facilities & FACILITY_GEN_INST_EXT) {
1518 tcg_out_risbg(s, TCG_REG_R2, addr_reg,
1519 64 - CPU_TLB_BITS - CPU_TLB_ENTRY_BITS,
1520 63 - CPU_TLB_ENTRY_BITS,
1521 64 + CPU_TLB_ENTRY_BITS - TARGET_PAGE_BITS, 1);
1522 if (a_off) {
1523 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1524 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1525 } else {
1526 tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
1527 }
1528 } else {
1529 tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
1530 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1531 tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
1532 tgen_andi(s, TCG_TYPE_I64, TCG_REG_R2,
1533 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1534 tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
1535 }
1536
1537 if (is_ld) {
1538 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
1539 } else {
1540 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
1541 }
1542 if (TARGET_LONG_BITS == 32) {
1543 tcg_out_mem(s, RX_C, RXY_CY, TCG_REG_R3, TCG_REG_R2, TCG_AREG0, ofs);
1544 } else {
1545 tcg_out_mem(s, 0, RXY_CG, TCG_REG_R3, TCG_REG_R2, TCG_AREG0, ofs);
1546 }
1547
1548 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1549 tcg_out_mem(s, 0, RXY_LG, TCG_REG_R2, TCG_REG_R2, TCG_AREG0, ofs);
1550
1551 if (TARGET_LONG_BITS == 32) {
1552 tgen_ext32u(s, TCG_REG_R3, addr_reg);
1553 return TCG_REG_R3;
1554 }
1555 return addr_reg;
1556 }
1557
1558 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1559 TCGReg data, TCGReg addr,
1560 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1561 {
1562 TCGLabelQemuLdst *label = new_ldst_label(s);
1563
1564 label->is_ld = is_ld;
1565 label->oi = oi;
1566 label->datalo_reg = data;
1567 label->addrlo_reg = addr;
1568 label->raddr = raddr;
1569 label->label_ptr[0] = label_ptr;
1570 }
1571
1572 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1573 {
1574 TCGReg addr_reg = lb->addrlo_reg;
1575 TCGReg data_reg = lb->datalo_reg;
1576 TCGMemOpIdx oi = lb->oi;
1577 TCGMemOp opc = get_memop(oi);
1578
1579 patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, -2);
1580
1581 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1582 if (TARGET_LONG_BITS == 64) {
1583 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1584 }
1585 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, oi);
1586 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R5, (uintptr_t)lb->raddr);
1587 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
1588 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
1589
1590 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1591 }
1592
1593 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1594 {
1595 TCGReg addr_reg = lb->addrlo_reg;
1596 TCGReg data_reg = lb->datalo_reg;
1597 TCGMemOpIdx oi = lb->oi;
1598 TCGMemOp opc = get_memop(oi);
1599
1600 patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, -2);
1601
1602 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
1603 if (TARGET_LONG_BITS == 64) {
1604 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
1605 }
1606 switch (opc & MO_SIZE) {
1607 case MO_UB:
1608 tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1609 break;
1610 case MO_UW:
1611 tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1612 break;
1613 case MO_UL:
1614 tgen_ext32u(s, TCG_REG_R4, data_reg);
1615 break;
1616 case MO_Q:
1617 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
1618 break;
1619 default:
1620 tcg_abort();
1621 }
1622 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
1623 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
1624 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1625
1626 tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
1627 }
1628 #else
1629 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1630 TCGReg *index_reg, tcg_target_long *disp)
1631 {
1632 if (TARGET_LONG_BITS == 32) {
1633 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1634 *addr_reg = TCG_TMP0;
1635 }
1636 if (guest_base < 0x80000) {
1637 *index_reg = TCG_REG_NONE;
1638 *disp = guest_base;
1639 } else {
1640 *index_reg = TCG_GUEST_BASE_REG;
1641 *disp = 0;
1642 }
1643 }
1644 #endif /* CONFIG_SOFTMMU */
1645
1646 static void tcg_out_qemu_ld(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1647 TCGMemOpIdx oi)
1648 {
1649 TCGMemOp opc = get_memop(oi);
1650 #ifdef CONFIG_SOFTMMU
1651 unsigned mem_index = get_mmuidx(oi);
1652 tcg_insn_unit *label_ptr;
1653 TCGReg base_reg;
1654
1655 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 1);
1656
1657 /* We need to keep the offset unchanged for retranslation. */
1658 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1659 label_ptr = s->code_ptr;
1660 s->code_ptr += 1;
1661
1662 tcg_out_qemu_ld_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1663
1664 add_qemu_ldst_label(s, 1, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1665 #else
1666 TCGReg index_reg;
1667 tcg_target_long disp;
1668
1669 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1670 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1671 #endif
1672 }
1673
1674 static void tcg_out_qemu_st(TCGContext* s, TCGReg data_reg, TCGReg addr_reg,
1675 TCGMemOpIdx oi)
1676 {
1677 TCGMemOp opc = get_memop(oi);
1678 #ifdef CONFIG_SOFTMMU
1679 unsigned mem_index = get_mmuidx(oi);
1680 tcg_insn_unit *label_ptr;
1681 TCGReg base_reg;
1682
1683 base_reg = tcg_out_tlb_read(s, addr_reg, opc, mem_index, 0);
1684
1685 /* We need to keep the offset unchanged for retranslation. */
1686 tcg_out16(s, RI_BRC | (S390_CC_NE << 4));
1687 label_ptr = s->code_ptr;
1688 s->code_ptr += 1;
1689
1690 tcg_out_qemu_st_direct(s, opc, data_reg, base_reg, TCG_REG_R2, 0);
1691
1692 add_qemu_ldst_label(s, 0, oi, data_reg, addr_reg, s->code_ptr, label_ptr);
1693 #else
1694 TCGReg index_reg;
1695 tcg_target_long disp;
1696
1697 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1698 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1699 #endif
1700 }
1701
1702 # define OP_32_64(x) \
1703 case glue(glue(INDEX_op_,x),_i32): \
1704 case glue(glue(INDEX_op_,x),_i64)
1705
1706 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1707 const TCGArg *args, const int *const_args)
1708 {
1709 S390Opcode op;
1710 TCGArg a0, a1, a2;
1711
1712 switch (opc) {
1713 case INDEX_op_exit_tb:
1714 /* return value */
1715 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
1716 tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
1717 break;
1718
1719 case INDEX_op_goto_tb:
1720 if (s->tb_jmp_insn_offset) {
1721 /* branch displacement must be aligned for atomic patching;
1722 * see if we need to add extra nop before branch
1723 */
1724 if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
1725 tcg_out16(s, NOP);
1726 }
1727 tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
1728 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
1729 s->code_ptr += 2;
1730 } else {
1731 /* load address stored at s->tb_jmp_target_addr + args[0] */
1732 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0,
1733 s->tb_jmp_target_addr + args[0]);
1734 /* and go there */
1735 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1736 }
1737 s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
1738 break;
1739
1740 OP_32_64(ld8u):
1741 /* ??? LLC (RXY format) is only present with the extended-immediate
1742 facility, whereas LLGC is always present. */
1743 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1744 break;
1745
1746 OP_32_64(ld8s):
1747 /* ??? LB is no smaller than LGB, so no point to using it. */
1748 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1749 break;
1750
1751 OP_32_64(ld16u):
1752 /* ??? LLH (RXY format) is only present with the extended-immediate
1753 facility, whereas LLGH is always present. */
1754 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1755 break;
1756
1757 case INDEX_op_ld16s_i32:
1758 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1759 break;
1760
1761 case INDEX_op_ld_i32:
1762 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1763 break;
1764
1765 OP_32_64(st8):
1766 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1767 TCG_REG_NONE, args[2]);
1768 break;
1769
1770 OP_32_64(st16):
1771 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1772 TCG_REG_NONE, args[2]);
1773 break;
1774
1775 case INDEX_op_st_i32:
1776 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1777 break;
1778
1779 case INDEX_op_add_i32:
1780 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1781 if (const_args[2]) {
1782 do_addi_32:
1783 if (a0 == a1) {
1784 if (a2 == (int16_t)a2) {
1785 tcg_out_insn(s, RI, AHI, a0, a2);
1786 break;
1787 }
1788 if (s390_facilities & FACILITY_EXT_IMM) {
1789 tcg_out_insn(s, RIL, AFI, a0, a2);
1790 break;
1791 }
1792 }
1793 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1794 } else if (a0 == a1) {
1795 tcg_out_insn(s, RR, AR, a0, a2);
1796 } else {
1797 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
1798 }
1799 break;
1800 case INDEX_op_sub_i32:
1801 a0 = args[0], a1 = args[1], a2 = (int32_t)args[2];
1802 if (const_args[2]) {
1803 a2 = -a2;
1804 goto do_addi_32;
1805 }
1806 tcg_out_insn(s, RR, SR, args[0], args[2]);
1807 break;
1808
1809 case INDEX_op_and_i32:
1810 if (const_args[2]) {
1811 tgen_andi(s, TCG_TYPE_I32, args[0], args[2]);
1812 } else {
1813 tcg_out_insn(s, RR, NR, args[0], args[2]);
1814 }
1815 break;
1816 case INDEX_op_or_i32:
1817 if (const_args[2]) {
1818 tgen64_ori(s, args[0], args[2] & 0xffffffff);
1819 } else {
1820 tcg_out_insn(s, RR, OR, args[0], args[2]);
1821 }
1822 break;
1823 case INDEX_op_xor_i32:
1824 if (const_args[2]) {
1825 tgen64_xori(s, args[0], args[2] & 0xffffffff);
1826 } else {
1827 tcg_out_insn(s, RR, XR, args[0], args[2]);
1828 }
1829 break;
1830
1831 case INDEX_op_neg_i32:
1832 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1833 break;
1834
1835 case INDEX_op_mul_i32:
1836 if (const_args[2]) {
1837 if ((int32_t)args[2] == (int16_t)args[2]) {
1838 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1839 } else {
1840 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1841 }
1842 } else {
1843 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1844 }
1845 break;
1846
1847 case INDEX_op_div2_i32:
1848 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1849 break;
1850 case INDEX_op_divu2_i32:
1851 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1852 break;
1853
1854 case INDEX_op_shl_i32:
1855 op = RS_SLL;
1856 do_shift32:
1857 if (const_args[2]) {
1858 tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1859 } else {
1860 tcg_out_sh32(s, op, args[0], args[2], 0);
1861 }
1862 break;
1863 case INDEX_op_shr_i32:
1864 op = RS_SRL;
1865 goto do_shift32;
1866 case INDEX_op_sar_i32:
1867 op = RS_SRA;
1868 goto do_shift32;
1869
1870 case INDEX_op_rotl_i32:
1871 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1872 if (const_args[2]) {
1873 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1874 } else {
1875 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1876 }
1877 break;
1878 case INDEX_op_rotr_i32:
1879 if (const_args[2]) {
1880 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1881 TCG_REG_NONE, (32 - args[2]) & 31);
1882 } else {
1883 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1884 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1885 }
1886 break;
1887
1888 case INDEX_op_ext8s_i32:
1889 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1890 break;
1891 case INDEX_op_ext16s_i32:
1892 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1893 break;
1894 case INDEX_op_ext8u_i32:
1895 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1896 break;
1897 case INDEX_op_ext16u_i32:
1898 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1899 break;
1900
1901 OP_32_64(bswap16):
1902 /* The TCG bswap definition requires bits 0-47 already be zero.
1903 Thus we don't need the G-type insns to implement bswap16_i64. */
1904 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1905 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1906 break;
1907 OP_32_64(bswap32):
1908 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1909 break;
1910
1911 case INDEX_op_add2_i32:
1912 if (const_args[4]) {
1913 tcg_out_insn(s, RIL, ALFI, args[0], args[4]);
1914 } else {
1915 tcg_out_insn(s, RR, ALR, args[0], args[4]);
1916 }
1917 tcg_out_insn(s, RRE, ALCR, args[1], args[5]);
1918 break;
1919 case INDEX_op_sub2_i32:
1920 if (const_args[4]) {
1921 tcg_out_insn(s, RIL, SLFI, args[0], args[4]);
1922 } else {
1923 tcg_out_insn(s, RR, SLR, args[0], args[4]);
1924 }
1925 tcg_out_insn(s, RRE, SLBR, args[1], args[5]);
1926 break;
1927
1928 case INDEX_op_br:
1929 tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
1930 break;
1931
1932 case INDEX_op_brcond_i32:
1933 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1934 args[1], const_args[1], arg_label(args[3]));
1935 break;
1936 case INDEX_op_setcond_i32:
1937 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1938 args[2], const_args[2]);
1939 break;
1940 case INDEX_op_movcond_i32:
1941 tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
1942 args[2], const_args[2], args[3]);
1943 break;
1944
1945 case INDEX_op_qemu_ld_i32:
1946 /* ??? Technically we can use a non-extending instruction. */
1947 case INDEX_op_qemu_ld_i64:
1948 tcg_out_qemu_ld(s, args[0], args[1], args[2]);
1949 break;
1950 case INDEX_op_qemu_st_i32:
1951 case INDEX_op_qemu_st_i64:
1952 tcg_out_qemu_st(s, args[0], args[1], args[2]);
1953 break;
1954
1955 case INDEX_op_ld16s_i64:
1956 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1957 break;
1958 case INDEX_op_ld32u_i64:
1959 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1960 break;
1961 case INDEX_op_ld32s_i64:
1962 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
1963 break;
1964 case INDEX_op_ld_i64:
1965 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1966 break;
1967
1968 case INDEX_op_st32_i64:
1969 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1970 break;
1971 case INDEX_op_st_i64:
1972 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1973 break;
1974
1975 case INDEX_op_add_i64:
1976 a0 = args[0], a1 = args[1], a2 = args[2];
1977 if (const_args[2]) {
1978 do_addi_64:
1979 if (a0 == a1) {
1980 if (a2 == (int16_t)a2) {
1981 tcg_out_insn(s, RI, AGHI, a0, a2);
1982 break;
1983 }
1984 if (s390_facilities & FACILITY_EXT_IMM) {
1985 if (a2 == (int32_t)a2) {
1986 tcg_out_insn(s, RIL, AGFI, a0, a2);
1987 break;
1988 } else if (a2 == (uint32_t)a2) {
1989 tcg_out_insn(s, RIL, ALGFI, a0, a2);
1990 break;
1991 } else if (-a2 == (uint32_t)-a2) {
1992 tcg_out_insn(s, RIL, SLGFI, a0, -a2);
1993 break;
1994 }
1995 }
1996 }
1997 tcg_out_mem(s, RX_LA, RXY_LAY, a0, a1, TCG_REG_NONE, a2);
1998 } else if (a0 == a1) {
1999 tcg_out_insn(s, RRE, AGR, a0, a2);
2000 } else {
2001 tcg_out_insn(s, RX, LA, a0, a1, a2, 0);
2002 }
2003 break;
2004 case INDEX_op_sub_i64:
2005 a0 = args[0], a1 = args[1], a2 = args[2];
2006 if (const_args[2]) {
2007 a2 = -a2;
2008 goto do_addi_64;
2009 } else {
2010 tcg_out_insn(s, RRE, SGR, args[0], args[2]);
2011 }
2012 break;
2013
2014 case INDEX_op_and_i64:
2015 if (const_args[2]) {
2016 tgen_andi(s, TCG_TYPE_I64, args[0], args[2]);
2017 } else {
2018 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
2019 }
2020 break;
2021 case INDEX_op_or_i64:
2022 if (const_args[2]) {
2023 tgen64_ori(s, args[0], args[2]);
2024 } else {
2025 tcg_out_insn(s, RRE, OGR, args[0], args[2]);
2026 }
2027 break;
2028 case INDEX_op_xor_i64:
2029 if (const_args[2]) {
2030 tgen64_xori(s, args[0], args[2]);
2031 } else {
2032 tcg_out_insn(s, RRE, XGR, args[0], args[2]);
2033 }
2034 break;
2035
2036 case INDEX_op_neg_i64:
2037 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
2038 break;
2039 case INDEX_op_bswap64_i64:
2040 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
2041 break;
2042
2043 case INDEX_op_mul_i64:
2044 if (const_args[2]) {
2045 if (args[2] == (int16_t)args[2]) {
2046 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
2047 } else {
2048 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
2049 }
2050 } else {
2051 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
2052 }
2053 break;
2054
2055 case INDEX_op_div2_i64:
2056 /* ??? We get an unnecessary sign-extension of the dividend
2057 into R3 with this definition, but as we do in fact always
2058 produce both quotient and remainder using INDEX_op_div_i64
2059 instead requires jumping through even more hoops. */
2060 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
2061 break;
2062 case INDEX_op_divu2_i64:
2063 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
2064 break;
2065 case INDEX_op_mulu2_i64:
2066 tcg_out_insn(s, RRE, MLGR, TCG_REG_R2, args[3]);
2067 break;
2068
2069 case INDEX_op_shl_i64:
2070 op = RSY_SLLG;
2071 do_shift64:
2072 if (const_args[2]) {
2073 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
2074 } else {
2075 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
2076 }
2077 break;
2078 case INDEX_op_shr_i64:
2079 op = RSY_SRLG;
2080 goto do_shift64;
2081 case INDEX_op_sar_i64:
2082 op = RSY_SRAG;
2083 goto do_shift64;
2084
2085 case INDEX_op_rotl_i64:
2086 if (const_args[2]) {
2087 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2088 TCG_REG_NONE, args[2]);
2089 } else {
2090 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
2091 }
2092 break;
2093 case INDEX_op_rotr_i64:
2094 if (const_args[2]) {
2095 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
2096 TCG_REG_NONE, (64 - args[2]) & 63);
2097 } else {
2098 /* We can use the smaller 32-bit negate because only the
2099 low 6 bits are examined for the rotate. */
2100 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2101 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2102 }
2103 break;
2104
2105 case INDEX_op_ext8s_i64:
2106 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2107 break;
2108 case INDEX_op_ext16s_i64:
2109 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2110 break;
2111 case INDEX_op_ext_i32_i64:
2112 case INDEX_op_ext32s_i64:
2113 tgen_ext32s(s, args[0], args[1]);
2114 break;
2115 case INDEX_op_ext8u_i64:
2116 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2117 break;
2118 case INDEX_op_ext16u_i64:
2119 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2120 break;
2121 case INDEX_op_extu_i32_i64:
2122 case INDEX_op_ext32u_i64:
2123 tgen_ext32u(s, args[0], args[1]);
2124 break;
2125
2126 case INDEX_op_add2_i64:
2127 if (const_args[4]) {
2128 if ((int64_t)args[4] >= 0) {
2129 tcg_out_insn(s, RIL, ALGFI, args[0], args[4]);
2130 } else {
2131 tcg_out_insn(s, RIL, SLGFI, args[0], -args[4]);
2132 }
2133 } else {
2134 tcg_out_insn(s, RRE, ALGR, args[0], args[4]);
2135 }
2136 tcg_out_insn(s, RRE, ALCGR, args[1], args[5]);
2137 break;
2138 case INDEX_op_sub2_i64:
2139 if (const_args[4]) {
2140 if ((int64_t)args[4] >= 0) {
2141 tcg_out_insn(s, RIL, SLGFI, args[0], args[4]);
2142 } else {
2143 tcg_out_insn(s, RIL, ALGFI, args[0], -args[4]);
2144 }
2145 } else {
2146 tcg_out_insn(s, RRE, SLGR, args[0], args[4]);
2147 }
2148 tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
2149 break;
2150
2151 case INDEX_op_brcond_i64:
2152 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2153 args[1], const_args[1], arg_label(args[3]));
2154 break;
2155 case INDEX_op_setcond_i64:
2156 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2157 args[2], const_args[2]);
2158 break;
2159 case INDEX_op_movcond_i64:
2160 tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
2161 args[2], const_args[2], args[3]);
2162 break;
2163
2164 OP_32_64(deposit):
2165 tgen_deposit(s, args[0], args[2], args[3], args[4]);
2166 break;
2167 OP_32_64(extract):
2168 tgen_extract(s, args[0], args[1], args[2], args[3]);
2169 break;
2170
2171 case INDEX_op_mb:
2172 /* The host memory model is quite strong, we simply need to
2173 serialize the instruction stream. */
2174 if (args[0] & TCG_MO_ST_LD) {
2175 tcg_out_insn(s, RR, BCR,
2176 s390_facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
2177 }
2178 break;
2179
2180 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2181 case INDEX_op_mov_i64:
2182 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2183 case INDEX_op_movi_i64:
2184 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2185 default:
2186 tcg_abort();
2187 }
2188 }
2189
2190 static const TCGTargetOpDef s390_op_defs[] = {
2191 { INDEX_op_exit_tb, { } },
2192 { INDEX_op_goto_tb, { } },
2193 { INDEX_op_br, { } },
2194
2195 { INDEX_op_ld8u_i32, { "r", "r" } },
2196 { INDEX_op_ld8s_i32, { "r", "r" } },
2197 { INDEX_op_ld16u_i32, { "r", "r" } },
2198 { INDEX_op_ld16s_i32, { "r", "r" } },
2199 { INDEX_op_ld_i32, { "r", "r" } },
2200 { INDEX_op_st8_i32, { "r", "r" } },
2201 { INDEX_op_st16_i32, { "r", "r" } },
2202 { INDEX_op_st_i32, { "r", "r" } },
2203
2204 { INDEX_op_add_i32, { "r", "r", "ri" } },
2205 { INDEX_op_sub_i32, { "r", "0", "ri" } },
2206 { INDEX_op_mul_i32, { "r", "0", "rK" } },
2207
2208 { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2209 { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2210
2211 { INDEX_op_and_i32, { "r", "0", "ri" } },
2212 { INDEX_op_or_i32, { "r", "0", "rO" } },
2213 { INDEX_op_xor_i32, { "r", "0", "rX" } },
2214
2215 { INDEX_op_neg_i32, { "r", "r" } },
2216
2217 { INDEX_op_shl_i32, { "r", "0", "ri" } },
2218 { INDEX_op_shr_i32, { "r", "0", "ri" } },
2219 { INDEX_op_sar_i32, { "r", "0", "ri" } },
2220
2221 { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2222 { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2223
2224 { INDEX_op_ext8s_i32, { "r", "r" } },
2225 { INDEX_op_ext8u_i32, { "r", "r" } },
2226 { INDEX_op_ext16s_i32, { "r", "r" } },
2227 { INDEX_op_ext16u_i32, { "r", "r" } },
2228
2229 { INDEX_op_bswap16_i32, { "r", "r" } },
2230 { INDEX_op_bswap32_i32, { "r", "r" } },
2231
2232 { INDEX_op_add2_i32, { "r", "r", "0", "1", "rA", "r" } },
2233 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "rA", "r" } },
2234
2235 { INDEX_op_brcond_i32, { "r", "rC" } },
2236 { INDEX_op_setcond_i32, { "r", "r", "rC" } },
2237 { INDEX_op_movcond_i32, { "r", "r", "rC", "r", "0" } },
2238 { INDEX_op_deposit_i32, { "r", "0", "r" } },
2239 { INDEX_op_extract_i32, { "r", "r" } },
2240
2241 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2242 { INDEX_op_qemu_ld_i64, { "r", "L" } },
2243 { INDEX_op_qemu_st_i32, { "L", "L" } },
2244 { INDEX_op_qemu_st_i64, { "L", "L" } },
2245
2246 { INDEX_op_ld8u_i64, { "r", "r" } },
2247 { INDEX_op_ld8s_i64, { "r", "r" } },
2248 { INDEX_op_ld16u_i64, { "r", "r" } },
2249 { INDEX_op_ld16s_i64, { "r", "r" } },
2250 { INDEX_op_ld32u_i64, { "r", "r" } },
2251 { INDEX_op_ld32s_i64, { "r", "r" } },
2252 { INDEX_op_ld_i64, { "r", "r" } },
2253
2254 { INDEX_op_st8_i64, { "r", "r" } },
2255 { INDEX_op_st16_i64, { "r", "r" } },
2256 { INDEX_op_st32_i64, { "r", "r" } },
2257 { INDEX_op_st_i64, { "r", "r" } },
2258
2259 { INDEX_op_add_i64, { "r", "r", "ri" } },
2260 { INDEX_op_sub_i64, { "r", "0", "ri" } },
2261 { INDEX_op_mul_i64, { "r", "0", "rK" } },
2262
2263 { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2264 { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2265 { INDEX_op_mulu2_i64, { "b", "a", "0", "r" } },
2266
2267 { INDEX_op_and_i64, { "r", "0", "ri" } },
2268 { INDEX_op_or_i64, { "r", "0", "rO" } },
2269 { INDEX_op_xor_i64, { "r", "0", "rX" } },
2270
2271 { INDEX_op_neg_i64, { "r", "r" } },
2272
2273 { INDEX_op_shl_i64, { "r", "r", "ri" } },
2274 { INDEX_op_shr_i64, { "r", "r", "ri" } },
2275 { INDEX_op_sar_i64, { "r", "r", "ri" } },
2276
2277 { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2278 { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2279
2280 { INDEX_op_ext8s_i64, { "r", "r" } },
2281 { INDEX_op_ext8u_i64, { "r", "r" } },
2282 { INDEX_op_ext16s_i64, { "r", "r" } },
2283 { INDEX_op_ext16u_i64, { "r", "r" } },
2284 { INDEX_op_ext32s_i64, { "r", "r" } },
2285 { INDEX_op_ext32u_i64, { "r", "r" } },
2286
2287 { INDEX_op_ext_i32_i64, { "r", "r" } },
2288 { INDEX_op_extu_i32_i64, { "r", "r" } },
2289
2290 { INDEX_op_bswap16_i64, { "r", "r" } },
2291 { INDEX_op_bswap32_i64, { "r", "r" } },
2292 { INDEX_op_bswap64_i64, { "r", "r" } },
2293
2294 { INDEX_op_add2_i64, { "r", "r", "0", "1", "rA", "r" } },
2295 { INDEX_op_sub2_i64, { "r", "r", "0", "1", "rA", "r" } },
2296
2297 { INDEX_op_brcond_i64, { "r", "rC" } },
2298 { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2299 { INDEX_op_movcond_i64, { "r", "r", "rC", "r", "0" } },
2300 { INDEX_op_deposit_i64, { "r", "0", "r" } },
2301 { INDEX_op_extract_i64, { "r", "r" } },
2302
2303 { INDEX_op_mb, { } },
2304 { -1 },
2305 };
2306
2307 static void query_s390_facilities(void)
2308 {
2309 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2310
2311 /* Is STORE FACILITY LIST EXTENDED available? Honestly, I believe this
2312 is present on all 64-bit systems, but let's check for it anyway. */
2313 if (hwcap & HWCAP_S390_STFLE) {
2314 register int r0 __asm__("0");
2315 register void *r1 __asm__("1");
2316
2317 /* stfle 0(%r1) */
2318 r1 = &s390_facilities;
2319 asm volatile(".word 0xb2b0,0x1000"
2320 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2321 }
2322 }
2323
2324 static void tcg_target_init(TCGContext *s)
2325 {
2326 query_s390_facilities();
2327
2328 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2329 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2330
2331 tcg_regset_clear(tcg_target_call_clobber_regs);
2332 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2333 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2334 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2335 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2336 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2337 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2338 /* The r6 register is technically call-saved, but it's also a parameter
2339 register, so it can get killed by setup for the qemu_st helper. */
2340 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2341 /* The return register can be considered call-clobbered. */
2342 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2343
2344 tcg_regset_clear(s->reserved_regs);
2345 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2346 /* XXX many insns can't be used with R0, so we better avoid it for now */
2347 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2348 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2349
2350 tcg_add_target_add_op_defs(s390_op_defs);
2351 }
2352
2353 #define FRAME_SIZE ((int)(TCG_TARGET_CALL_STACK_OFFSET \
2354 + TCG_STATIC_CALL_ARGS_SIZE \
2355 + CPU_TEMP_BUF_NLONGS * sizeof(long)))
2356
2357 static void tcg_target_qemu_prologue(TCGContext *s)
2358 {
2359 /* stmg %r6,%r15,48(%r15) (save registers) */
2360 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2361
2362 /* aghi %r15,-frame_size */
2363 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -FRAME_SIZE);
2364
2365 tcg_set_frame(s, TCG_REG_CALL_STACK,
2366 TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET,
2367 CPU_TEMP_BUF_NLONGS * sizeof(long));
2368
2369 #ifndef CONFIG_SOFTMMU
2370 if (guest_base >= 0x80000) {
2371 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
2372 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2373 }
2374 #endif
2375
2376 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2377 /* br %r3 (go to TB) */
2378 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
2379
2380 tb_ret_addr = s->code_ptr;
2381
2382 /* lmg %r6,%r15,fs+48(%r15) (restore registers) */
2383 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
2384 FRAME_SIZE + 48);
2385
2386 /* br %r14 (return) */
2387 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2388 }
2389
2390 typedef struct {
2391 DebugFrameHeader h;
2392 uint8_t fde_def_cfa[4];
2393 uint8_t fde_reg_ofs[18];
2394 } DebugFrame;
2395
2396 /* We're expecting a 2 byte uleb128 encoded value. */
2397 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2398
2399 #define ELF_HOST_MACHINE EM_S390
2400
2401 static const DebugFrame debug_frame = {
2402 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2403 .h.cie.id = -1,
2404 .h.cie.version = 1,
2405 .h.cie.code_align = 1,
2406 .h.cie.data_align = 8, /* sleb128 8 */
2407 .h.cie.return_column = TCG_REG_R14,
2408
2409 /* Total FDE size does not include the "len" member. */
2410 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2411
2412 .fde_def_cfa = {
2413 12, TCG_REG_CALL_STACK, /* DW_CFA_def_cfa %r15, ... */
2414 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2415 (FRAME_SIZE >> 7)
2416 },
2417 .fde_reg_ofs = {
2418 0x86, 6, /* DW_CFA_offset, %r6, 48 */
2419 0x87, 7, /* DW_CFA_offset, %r7, 56 */
2420 0x88, 8, /* DW_CFA_offset, %r8, 64 */
2421 0x89, 9, /* DW_CFA_offset, %r92, 72 */
2422 0x8a, 10, /* DW_CFA_offset, %r10, 80 */
2423 0x8b, 11, /* DW_CFA_offset, %r11, 88 */
2424 0x8c, 12, /* DW_CFA_offset, %r12, 96 */
2425 0x8d, 13, /* DW_CFA_offset, %r13, 104 */
2426 0x8e, 14, /* DW_CFA_offset, %r14, 112 */
2427 }
2428 };
2429
2430 void tcg_register_jit(void *buf, size_t buf_size)
2431 {
2432 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2433 }