]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/s390/tcg-target.c
exec: move include files to include/exec/
[mirror_qemu.git] / tcg / s390 / tcg-target.c
CommitLineData
2827822e
AG
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
48bb3750
RH
5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
6 * Copyright (c) 2010 Richard Henderson <rth@twiddle.net>
2827822e
AG
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
48bb3750
RH
27/* ??? The translation blocks produced by TCG are generally small enough to
28 be entirely reachable with a 16-bit displacement. Leaving the option for
29 a 32-bit displacement here Just In Case. */
30#define USE_LONG_BRANCHES 0
31
32#define TCG_CT_CONST_32 0x0100
33#define TCG_CT_CONST_NEG 0x0200
34#define TCG_CT_CONST_ADDI 0x0400
35#define TCG_CT_CONST_MULI 0x0800
36#define TCG_CT_CONST_ANDI 0x1000
37#define TCG_CT_CONST_ORI 0x2000
38#define TCG_CT_CONST_XORI 0x4000
39#define TCG_CT_CONST_CMPI 0x8000
40
41/* Several places within the instruction set 0 means "no register"
42 rather than TCG_REG_R0. */
43#define TCG_REG_NONE 0
44
45/* A scratch register that may be be used throughout the backend. */
46#define TCG_TMP0 TCG_REG_R14
47
48#ifdef CONFIG_USE_GUEST_BASE
49#define TCG_GUEST_BASE_REG TCG_REG_R13
50#else
51#define TCG_GUEST_BASE_REG TCG_REG_R0
52#endif
53
54#ifndef GUEST_BASE
55#define GUEST_BASE 0
56#endif
57
58
59/* All of the following instructions are prefixed with their instruction
60 format, and are defined as 8- or 16-bit quantities, even when the two
61 halves of the 16-bit quantity may appear 32 bits apart in the insn.
62 This makes it easy to copy the values from the tables in Appendix B. */
63typedef enum S390Opcode {
64 RIL_AFI = 0xc209,
65 RIL_AGFI = 0xc208,
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_XIHF = 0xc006,
88 RIL_XILF = 0xc007,
89
90 RI_AGHI = 0xa70b,
91 RI_AHI = 0xa70a,
92 RI_BRC = 0xa704,
93 RI_IIHH = 0xa500,
94 RI_IIHL = 0xa501,
95 RI_IILH = 0xa502,
96 RI_IILL = 0xa503,
97 RI_LGHI = 0xa709,
98 RI_LLIHH = 0xa50c,
99 RI_LLIHL = 0xa50d,
100 RI_LLILH = 0xa50e,
101 RI_LLILL = 0xa50f,
102 RI_MGHI = 0xa70d,
103 RI_MHI = 0xa70c,
104 RI_NIHH = 0xa504,
105 RI_NIHL = 0xa505,
106 RI_NILH = 0xa506,
107 RI_NILL = 0xa507,
108 RI_OIHH = 0xa508,
109 RI_OIHL = 0xa509,
110 RI_OILH = 0xa50a,
111 RI_OILL = 0xa50b,
112
113 RIE_CGIJ = 0xec7c,
114 RIE_CGRJ = 0xec64,
115 RIE_CIJ = 0xec7e,
116 RIE_CLGRJ = 0xec65,
117 RIE_CLIJ = 0xec7f,
118 RIE_CLGIJ = 0xec7d,
119 RIE_CLRJ = 0xec77,
120 RIE_CRJ = 0xec76,
121
122 RRE_AGR = 0xb908,
123 RRE_CGR = 0xb920,
124 RRE_CLGR = 0xb921,
125 RRE_DLGR = 0xb987,
126 RRE_DLR = 0xb997,
127 RRE_DSGFR = 0xb91d,
128 RRE_DSGR = 0xb90d,
129 RRE_LGBR = 0xb906,
130 RRE_LCGR = 0xb903,
131 RRE_LGFR = 0xb914,
132 RRE_LGHR = 0xb907,
133 RRE_LGR = 0xb904,
134 RRE_LLGCR = 0xb984,
135 RRE_LLGFR = 0xb916,
136 RRE_LLGHR = 0xb985,
137 RRE_LRVR = 0xb91f,
138 RRE_LRVGR = 0xb90f,
139 RRE_LTGR = 0xb902,
140 RRE_MSGR = 0xb90c,
141 RRE_MSR = 0xb252,
142 RRE_NGR = 0xb980,
143 RRE_OGR = 0xb981,
144 RRE_SGR = 0xb909,
145 RRE_XGR = 0xb982,
146
147 RR_AR = 0x1a,
148 RR_BASR = 0x0d,
149 RR_BCR = 0x07,
150 RR_CLR = 0x15,
151 RR_CR = 0x19,
152 RR_DR = 0x1d,
153 RR_LCR = 0x13,
154 RR_LR = 0x18,
155 RR_LTR = 0x12,
156 RR_NR = 0x14,
157 RR_OR = 0x16,
158 RR_SR = 0x1b,
159 RR_XR = 0x17,
160
161 RSY_RLL = 0xeb1d,
162 RSY_RLLG = 0xeb1c,
163 RSY_SLLG = 0xeb0d,
164 RSY_SRAG = 0xeb0a,
165 RSY_SRLG = 0xeb0c,
166
167 RS_SLL = 0x89,
168 RS_SRA = 0x8a,
169 RS_SRL = 0x88,
170
171 RXY_AG = 0xe308,
172 RXY_AY = 0xe35a,
173 RXY_CG = 0xe320,
174 RXY_CY = 0xe359,
175 RXY_LB = 0xe376,
176 RXY_LG = 0xe304,
177 RXY_LGB = 0xe377,
178 RXY_LGF = 0xe314,
179 RXY_LGH = 0xe315,
180 RXY_LHY = 0xe378,
181 RXY_LLGC = 0xe390,
182 RXY_LLGF = 0xe316,
183 RXY_LLGH = 0xe391,
184 RXY_LMG = 0xeb04,
185 RXY_LRV = 0xe31e,
186 RXY_LRVG = 0xe30f,
187 RXY_LRVH = 0xe31f,
188 RXY_LY = 0xe358,
189 RXY_STCY = 0xe372,
190 RXY_STG = 0xe324,
191 RXY_STHY = 0xe370,
192 RXY_STMG = 0xeb24,
193 RXY_STRV = 0xe33e,
194 RXY_STRVG = 0xe32f,
195 RXY_STRVH = 0xe33f,
196 RXY_STY = 0xe350,
197
198 RX_A = 0x5a,
199 RX_C = 0x59,
200 RX_L = 0x58,
201 RX_LH = 0x48,
202 RX_ST = 0x50,
203 RX_STC = 0x42,
204 RX_STH = 0x40,
205} S390Opcode;
206
207#define LD_SIGNED 0x04
208#define LD_UINT8 0x00
209#define LD_INT8 (LD_UINT8 | LD_SIGNED)
210#define LD_UINT16 0x01
211#define LD_INT16 (LD_UINT16 | LD_SIGNED)
212#define LD_UINT32 0x02
213#define LD_INT32 (LD_UINT32 | LD_SIGNED)
214#define LD_UINT64 0x03
215#define LD_INT64 (LD_UINT64 | LD_SIGNED)
216
217#ifndef NDEBUG
218static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
219 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
220 "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
221};
222#endif
223
224/* Since R6 is a potential argument register, choose it last of the
225 call-saved registers. Likewise prefer the call-clobbered registers
226 in reverse order to maximize the chance of avoiding the arguments. */
2827822e 227static const int tcg_target_reg_alloc_order[] = {
48bb3750
RH
228 TCG_REG_R13,
229 TCG_REG_R12,
230 TCG_REG_R11,
231 TCG_REG_R10,
232 TCG_REG_R9,
233 TCG_REG_R8,
234 TCG_REG_R7,
235 TCG_REG_R6,
236 TCG_REG_R14,
237 TCG_REG_R0,
238 TCG_REG_R1,
239 TCG_REG_R5,
240 TCG_REG_R4,
241 TCG_REG_R3,
242 TCG_REG_R2,
2827822e
AG
243};
244
245static const int tcg_target_call_iarg_regs[] = {
48bb3750
RH
246 TCG_REG_R2,
247 TCG_REG_R3,
248 TCG_REG_R4,
249 TCG_REG_R5,
250 TCG_REG_R6,
2827822e
AG
251};
252
253static const int tcg_target_call_oarg_regs[] = {
48bb3750 254 TCG_REG_R2,
5ddd17b4
SW
255#if TCG_TARGET_REG_BITS == 32
256 TCG_REG_R3
257#endif
48bb3750
RH
258};
259
260#define S390_CC_EQ 8
261#define S390_CC_LT 4
262#define S390_CC_GT 2
263#define S390_CC_OV 1
264#define S390_CC_NE (S390_CC_LT | S390_CC_GT)
265#define S390_CC_LE (S390_CC_LT | S390_CC_EQ)
266#define S390_CC_GE (S390_CC_GT | S390_CC_EQ)
267#define S390_CC_NEVER 0
268#define S390_CC_ALWAYS 15
269
270/* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
0aed257f 271static const uint8_t tcg_cond_to_s390_cond[] = {
48bb3750
RH
272 [TCG_COND_EQ] = S390_CC_EQ,
273 [TCG_COND_NE] = S390_CC_NE,
274 [TCG_COND_LT] = S390_CC_LT,
275 [TCG_COND_LE] = S390_CC_LE,
276 [TCG_COND_GT] = S390_CC_GT,
277 [TCG_COND_GE] = S390_CC_GE,
278 [TCG_COND_LTU] = S390_CC_LT,
279 [TCG_COND_LEU] = S390_CC_LE,
280 [TCG_COND_GTU] = S390_CC_GT,
281 [TCG_COND_GEU] = S390_CC_GE,
282};
283
284/* Condition codes that result from a LOAD AND TEST. Here, we have no
285 unsigned instruction variation, however since the test is vs zero we
286 can re-map the outcomes appropriately. */
0aed257f 287static const uint8_t tcg_cond_to_ltr_cond[] = {
48bb3750
RH
288 [TCG_COND_EQ] = S390_CC_EQ,
289 [TCG_COND_NE] = S390_CC_NE,
290 [TCG_COND_LT] = S390_CC_LT,
291 [TCG_COND_LE] = S390_CC_LE,
292 [TCG_COND_GT] = S390_CC_GT,
293 [TCG_COND_GE] = S390_CC_GE,
294 [TCG_COND_LTU] = S390_CC_NEVER,
295 [TCG_COND_LEU] = S390_CC_EQ,
296 [TCG_COND_GTU] = S390_CC_NE,
297 [TCG_COND_GEU] = S390_CC_ALWAYS,
298};
299
300#ifdef CONFIG_SOFTMMU
301
022c62cb 302#include "exec/softmmu_defs.h"
48bb3750 303
e141ab52
BS
304/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
305 int mmu_idx) */
306static const void * const qemu_ld_helpers[4] = {
307 helper_ldb_mmu,
308 helper_ldw_mmu,
309 helper_ldl_mmu,
310 helper_ldq_mmu,
311};
312
313/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
314 uintxx_t val, int mmu_idx) */
315static const void * const qemu_st_helpers[4] = {
316 helper_stb_mmu,
317 helper_stw_mmu,
318 helper_stl_mmu,
319 helper_stq_mmu,
320};
e141ab52 321#endif
48bb3750
RH
322
323static uint8_t *tb_ret_addr;
324
325/* A list of relevant facilities used by this translator. Some of these
326 are required for proper operation, and these are checked at startup. */
327
328#define FACILITY_ZARCH_ACTIVE (1ULL << (63 - 2))
329#define FACILITY_LONG_DISP (1ULL << (63 - 18))
330#define FACILITY_EXT_IMM (1ULL << (63 - 21))
331#define FACILITY_GEN_INST_EXT (1ULL << (63 - 34))
332
333static uint64_t facilities;
2827822e
AG
334
335static void patch_reloc(uint8_t *code_ptr, int type,
48bb3750 336 tcg_target_long value, tcg_target_long addend)
2827822e 337{
48bb3750
RH
338 tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr;
339 tcg_target_long pcrel2;
340
341 /* ??? Not the usual definition of "addend". */
342 pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
343
344 switch (type) {
345 case R_390_PC16DBL:
346 assert(pcrel2 == (int16_t)pcrel2);
347 *(int16_t *)code_ptr = pcrel2;
348 break;
349 case R_390_PC32DBL:
350 assert(pcrel2 == (int32_t)pcrel2);
351 *(int32_t *)code_ptr = pcrel2;
352 break;
353 default:
354 tcg_abort();
355 break;
356 }
2827822e
AG
357}
358
2827822e
AG
359/* parse target specific constraints */
360static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
361{
48bb3750
RH
362 const char *ct_str = *pct_str;
363
364 switch (ct_str[0]) {
365 case 'r': /* all registers */
366 ct->ct |= TCG_CT_REG;
367 tcg_regset_set32(ct->u.regs, 0, 0xffff);
368 break;
369 case 'R': /* not R0 */
370 ct->ct |= TCG_CT_REG;
371 tcg_regset_set32(ct->u.regs, 0, 0xffff);
372 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
373 break;
374 case 'L': /* qemu_ld/st constraint */
375 ct->ct |= TCG_CT_REG;
376 tcg_regset_set32(ct->u.regs, 0, 0xffff);
377 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2);
378 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
379 break;
380 case 'a': /* force R2 for division */
381 ct->ct |= TCG_CT_REG;
382 tcg_regset_clear(ct->u.regs);
383 tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
384 break;
385 case 'b': /* force R3 for division */
386 ct->ct |= TCG_CT_REG;
387 tcg_regset_clear(ct->u.regs);
388 tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
389 break;
390 case 'N': /* force immediate negate */
391 ct->ct |= TCG_CT_CONST_NEG;
392 break;
393 case 'W': /* force 32-bit ("word") immediate */
394 ct->ct |= TCG_CT_CONST_32;
395 break;
396 case 'I':
397 ct->ct |= TCG_CT_CONST_ADDI;
398 break;
399 case 'K':
400 ct->ct |= TCG_CT_CONST_MULI;
401 break;
402 case 'A':
403 ct->ct |= TCG_CT_CONST_ANDI;
404 break;
405 case 'O':
406 ct->ct |= TCG_CT_CONST_ORI;
407 break;
408 case 'X':
409 ct->ct |= TCG_CT_CONST_XORI;
410 break;
411 case 'C':
412 ct->ct |= TCG_CT_CONST_CMPI;
413 break;
414 default:
415 return -1;
416 }
417 ct_str++;
418 *pct_str = ct_str;
419
2827822e
AG
420 return 0;
421}
422
48bb3750
RH
423/* Immediates to be used with logical AND. This is an optimization only,
424 since a full 64-bit immediate AND can always be performed with 4 sequential
425 NI[LH][LH] instructions. What we're looking for is immediates that we
426 can load efficiently, and the immediate load plus the reg-reg AND is
427 smaller than the sequential NI's. */
428
429static int tcg_match_andi(int ct, tcg_target_ulong val)
430{
431 int i;
432
433 if (facilities & FACILITY_EXT_IMM) {
434 if (ct & TCG_CT_CONST_32) {
435 /* All 32-bit ANDs can be performed with 1 48-bit insn. */
436 return 1;
437 }
438
439 /* Zero-extensions. */
440 if (val == 0xff || val == 0xffff || val == 0xffffffff) {
441 return 1;
442 }
443 } else {
444 if (ct & TCG_CT_CONST_32) {
445 val = (uint32_t)val;
446 } else if (val == 0xffffffff) {
447 return 1;
448 }
449 }
450
451 /* Try all 32-bit insns that can perform it in one go. */
452 for (i = 0; i < 4; i++) {
453 tcg_target_ulong mask = ~(0xffffull << i*16);
454 if ((val & mask) == mask) {
455 return 1;
456 }
457 }
458
459 /* Look for 16-bit values performing the mask. These are better
460 to load with LLI[LH][LH]. */
461 for (i = 0; i < 4; i++) {
462 tcg_target_ulong mask = 0xffffull << i*16;
463 if ((val & mask) == val) {
464 return 0;
465 }
466 }
467
468 /* Look for 32-bit values performing the 64-bit mask. These
469 are better to load with LLI[LH]F, or if extended immediates
470 not available, with a pair of LLI insns. */
471 if ((ct & TCG_CT_CONST_32) == 0) {
472 if (val <= 0xffffffff || (val & 0xffffffff) == 0) {
473 return 0;
474 }
475 }
476
477 return 1;
478}
479
480/* Immediates to be used with logical OR. This is an optimization only,
481 since a full 64-bit immediate OR can always be performed with 4 sequential
482 OI[LH][LH] instructions. What we're looking for is immediates that we
483 can load efficiently, and the immediate load plus the reg-reg OR is
484 smaller than the sequential OI's. */
485
486static int tcg_match_ori(int ct, tcg_target_long val)
487{
488 if (facilities & FACILITY_EXT_IMM) {
489 if (ct & TCG_CT_CONST_32) {
490 /* All 32-bit ORs can be performed with 1 48-bit insn. */
491 return 1;
492 }
493 }
494
495 /* Look for negative values. These are best to load with LGHI. */
496 if (val < 0) {
497 if (val == (int16_t)val) {
498 return 0;
499 }
500 if (facilities & FACILITY_EXT_IMM) {
501 if (val == (int32_t)val) {
502 return 0;
503 }
504 }
505 }
506
507 return 1;
508}
509
510/* Immediates to be used with logical XOR. This is almost, but not quite,
511 only an optimization. XOR with immediate is only supported with the
512 extended-immediate facility. That said, there are a few patterns for
513 which it is better to load the value into a register first. */
514
515static int tcg_match_xori(int ct, tcg_target_long val)
516{
517 if ((facilities & FACILITY_EXT_IMM) == 0) {
518 return 0;
519 }
520
521 if (ct & TCG_CT_CONST_32) {
522 /* All 32-bit XORs can be performed with 1 48-bit insn. */
523 return 1;
524 }
525
526 /* Look for negative values. These are best to load with LGHI. */
527 if (val < 0 && val == (int32_t)val) {
528 return 0;
529 }
530
531 return 1;
532}
533
534/* Imediates to be used with comparisons. */
535
536static int tcg_match_cmpi(int ct, tcg_target_long val)
537{
538 if (facilities & FACILITY_EXT_IMM) {
539 /* The COMPARE IMMEDIATE instruction is available. */
540 if (ct & TCG_CT_CONST_32) {
541 /* We have a 32-bit immediate and can compare against anything. */
542 return 1;
543 } else {
544 /* ??? We have no insight here into whether the comparison is
545 signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
546 signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
547 a 32-bit unsigned immediate. If we were to use the (semi)
548 obvious "val == (int32_t)val" we would be enabling unsigned
549 comparisons vs very large numbers. The only solution is to
550 take the intersection of the ranges. */
551 /* ??? Another possible solution is to simply lie and allow all
552 constants here and force the out-of-range values into a temp
553 register in tgen_cmp when we have knowledge of the actual
554 comparison code in use. */
555 return val >= 0 && val <= 0x7fffffff;
556 }
557 } else {
558 /* Only the LOAD AND TEST instruction is available. */
559 return val == 0;
560 }
561}
562
2827822e 563/* Test if a constant matches the constraint. */
48bb3750
RH
564static int tcg_target_const_match(tcg_target_long val,
565 const TCGArgConstraint *arg_ct)
2827822e 566{
48bb3750
RH
567 int ct = arg_ct->ct;
568
569 if (ct & TCG_CT_CONST) {
570 return 1;
571 }
572
573 /* Handle the modifiers. */
574 if (ct & TCG_CT_CONST_NEG) {
575 val = -val;
576 }
577 if (ct & TCG_CT_CONST_32) {
578 val = (int32_t)val;
579 }
580
581 /* The following are mutually exclusive. */
582 if (ct & TCG_CT_CONST_ADDI) {
583 /* Immediates that may be used with add. If we have the
584 extended-immediates facility then we have ADD IMMEDIATE
585 with signed and unsigned 32-bit, otherwise we have only
586 ADD HALFWORD IMMEDIATE with a signed 16-bit. */
587 if (facilities & FACILITY_EXT_IMM) {
588 return val == (int32_t)val || val == (uint32_t)val;
589 } else {
590 return val == (int16_t)val;
591 }
592 } else if (ct & TCG_CT_CONST_MULI) {
593 /* Immediates that may be used with multiply. If we have the
594 general-instruction-extensions, then we have MULTIPLY SINGLE
595 IMMEDIATE with a signed 32-bit, otherwise we have only
596 MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
597 if (facilities & FACILITY_GEN_INST_EXT) {
598 return val == (int32_t)val;
599 } else {
600 return val == (int16_t)val;
601 }
602 } else if (ct & TCG_CT_CONST_ANDI) {
603 return tcg_match_andi(ct, val);
604 } else if (ct & TCG_CT_CONST_ORI) {
605 return tcg_match_ori(ct, val);
606 } else if (ct & TCG_CT_CONST_XORI) {
607 return tcg_match_xori(ct, val);
608 } else if (ct & TCG_CT_CONST_CMPI) {
609 return tcg_match_cmpi(ct, val);
610 }
611
2827822e
AG
612 return 0;
613}
614
48bb3750
RH
615/* Emit instructions according to the given instruction format. */
616
617static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
618{
619 tcg_out16(s, (op << 8) | (r1 << 4) | r2);
620}
621
622static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
623 TCGReg r1, TCGReg r2)
624{
625 tcg_out32(s, (op << 16) | (r1 << 4) | r2);
626}
627
628static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
629{
630 tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
631}
632
633static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
634{
635 tcg_out16(s, op | (r1 << 4));
636 tcg_out32(s, i2);
637}
638
639static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
640 TCGReg b2, TCGReg r3, int disp)
641{
642 tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
643 | (disp & 0xfff));
644}
645
646static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
647 TCGReg b2, TCGReg r3, int disp)
648{
649 tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
650 tcg_out32(s, (op & 0xff) | (b2 << 28)
651 | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
652}
653
654#define tcg_out_insn_RX tcg_out_insn_RS
655#define tcg_out_insn_RXY tcg_out_insn_RSY
656
657/* Emit an opcode with "type-checking" of the format. */
658#define tcg_out_insn(S, FMT, OP, ...) \
659 glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
660
661
662/* emit 64-bit shifts */
663static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
664 TCGReg src, TCGReg sh_reg, int sh_imm)
665{
666 tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
667}
668
669/* emit 32-bit shifts */
670static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
671 TCGReg sh_reg, int sh_imm)
672{
673 tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
674}
675
676static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
677{
678 if (src != dst) {
679 if (type == TCG_TYPE_I32) {
680 tcg_out_insn(s, RR, LR, dst, src);
681 } else {
682 tcg_out_insn(s, RRE, LGR, dst, src);
683 }
684 }
685}
686
2827822e 687/* load a register with an immediate value */
48bb3750
RH
688static void tcg_out_movi(TCGContext *s, TCGType type,
689 TCGReg ret, tcg_target_long sval)
2827822e 690{
48bb3750
RH
691 static const S390Opcode lli_insns[4] = {
692 RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
693 };
694
695 tcg_target_ulong uval = sval;
696 int i;
697
698 if (type == TCG_TYPE_I32) {
699 uval = (uint32_t)sval;
700 sval = (int32_t)sval;
701 }
702
703 /* Try all 32-bit insns that can load it in one go. */
704 if (sval >= -0x8000 && sval < 0x8000) {
705 tcg_out_insn(s, RI, LGHI, ret, sval);
706 return;
707 }
708
709 for (i = 0; i < 4; i++) {
710 tcg_target_long mask = 0xffffull << i*16;
711 if ((uval & mask) == uval) {
712 tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
713 return;
714 }
715 }
716
717 /* Try all 48-bit insns that can load it in one go. */
718 if (facilities & FACILITY_EXT_IMM) {
719 if (sval == (int32_t)sval) {
720 tcg_out_insn(s, RIL, LGFI, ret, sval);
721 return;
722 }
723 if (uval <= 0xffffffff) {
724 tcg_out_insn(s, RIL, LLILF, ret, uval);
725 return;
726 }
727 if ((uval & 0xffffffff) == 0) {
728 tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
729 return;
730 }
731 }
732
733 /* Try for PC-relative address load. */
734 if ((sval & 1) == 0) {
735 intptr_t off = (sval - (intptr_t)s->code_ptr) >> 1;
736 if (off == (int32_t)off) {
737 tcg_out_insn(s, RIL, LARL, ret, off);
738 return;
739 }
740 }
741
742 /* If extended immediates are not present, then we may have to issue
743 several instructions to load the low 32 bits. */
744 if (!(facilities & FACILITY_EXT_IMM)) {
745 /* A 32-bit unsigned value can be loaded in 2 insns. And given
746 that the lli_insns loop above did not succeed, we know that
747 both insns are required. */
748 if (uval <= 0xffffffff) {
749 tcg_out_insn(s, RI, LLILL, ret, uval);
750 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
751 return;
752 }
753
754 /* If all high bits are set, the value can be loaded in 2 or 3 insns.
755 We first want to make sure that all the high bits get set. With
756 luck the low 16-bits can be considered negative to perform that for
757 free, otherwise we load an explicit -1. */
758 if (sval >> 31 >> 1 == -1) {
759 if (uval & 0x8000) {
760 tcg_out_insn(s, RI, LGHI, ret, uval);
761 } else {
762 tcg_out_insn(s, RI, LGHI, ret, -1);
763 tcg_out_insn(s, RI, IILL, ret, uval);
764 }
765 tcg_out_insn(s, RI, IILH, ret, uval >> 16);
766 return;
767 }
768 }
769
770 /* If we get here, both the high and low parts have non-zero bits. */
771
772 /* Recurse to load the lower 32-bits. */
773 tcg_out_movi(s, TCG_TYPE_I32, ret, sval);
774
775 /* Insert data into the high 32-bits. */
776 uval = uval >> 31 >> 1;
777 if (facilities & FACILITY_EXT_IMM) {
778 if (uval < 0x10000) {
779 tcg_out_insn(s, RI, IIHL, ret, uval);
780 } else if ((uval & 0xffff) == 0) {
781 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
782 } else {
783 tcg_out_insn(s, RIL, IIHF, ret, uval);
784 }
785 } else {
786 if (uval & 0xffff) {
787 tcg_out_insn(s, RI, IIHL, ret, uval);
788 }
789 if (uval & 0xffff0000) {
790 tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
791 }
792 }
793}
794
795
796/* Emit a load/store type instruction. Inputs are:
797 DATA: The register to be loaded or stored.
798 BASE+OFS: The effective address.
799 OPC_RX: If the operation has an RX format opcode (e.g. STC), otherwise 0.
800 OPC_RXY: The RXY format opcode for the operation (e.g. STCY). */
801
802static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
803 TCGReg data, TCGReg base, TCGReg index,
804 tcg_target_long ofs)
805{
806 if (ofs < -0x80000 || ofs >= 0x80000) {
807 /* Combine the low 16 bits of the offset with the actual load insn;
808 the high 48 bits must come from an immediate load. */
809 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs & ~0xffff);
810 ofs &= 0xffff;
811
812 /* If we were already given an index register, add it in. */
813 if (index != TCG_REG_NONE) {
814 tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
815 }
816 index = TCG_TMP0;
817 }
818
819 if (opc_rx && ofs >= 0 && ofs < 0x1000) {
820 tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
821 } else {
822 tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
823 }
2827822e
AG
824}
825
48bb3750 826
2827822e 827/* load data without address translation or endianness conversion */
48bb3750
RH
828static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
829 TCGReg base, tcg_target_long ofs)
2827822e 830{
48bb3750
RH
831 if (type == TCG_TYPE_I32) {
832 tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
833 } else {
834 tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
835 }
2827822e
AG
836}
837
48bb3750
RH
838static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
839 TCGReg base, tcg_target_long ofs)
2827822e 840{
48bb3750
RH
841 if (type == TCG_TYPE_I32) {
842 tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
843 } else {
844 tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
845 }
846}
847
848/* load data from an absolute host address */
849static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
850{
851 tcg_target_long addr = (tcg_target_long)abs;
852
853 if (facilities & FACILITY_GEN_INST_EXT) {
854 tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
855 if (disp == (int32_t)disp) {
856 if (type == TCG_TYPE_I32) {
857 tcg_out_insn(s, RIL, LRL, dest, disp);
858 } else {
859 tcg_out_insn(s, RIL, LGRL, dest, disp);
860 }
861 return;
862 }
863 }
864
865 tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
866 tcg_out_ld(s, type, dest, dest, addr & 0xffff);
867}
868
869static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
870{
871 if (facilities & FACILITY_EXT_IMM) {
872 tcg_out_insn(s, RRE, LGBR, dest, src);
873 return;
874 }
875
876 if (type == TCG_TYPE_I32) {
877 if (dest == src) {
878 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
879 } else {
880 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
881 }
882 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
883 } else {
884 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
885 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
886 }
887}
888
889static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
890{
891 if (facilities & FACILITY_EXT_IMM) {
892 tcg_out_insn(s, RRE, LLGCR, dest, src);
893 return;
894 }
895
896 if (dest == src) {
897 tcg_out_movi(s, type, TCG_TMP0, 0xff);
898 src = TCG_TMP0;
899 } else {
900 tcg_out_movi(s, type, dest, 0xff);
901 }
902 if (type == TCG_TYPE_I32) {
903 tcg_out_insn(s, RR, NR, dest, src);
904 } else {
905 tcg_out_insn(s, RRE, NGR, dest, src);
906 }
907}
908
909static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
910{
911 if (facilities & FACILITY_EXT_IMM) {
912 tcg_out_insn(s, RRE, LGHR, dest, src);
913 return;
914 }
915
916 if (type == TCG_TYPE_I32) {
917 if (dest == src) {
918 tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
919 } else {
920 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
921 }
922 tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
923 } else {
924 tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
925 tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
926 }
927}
928
929static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
930{
931 if (facilities & FACILITY_EXT_IMM) {
932 tcg_out_insn(s, RRE, LLGHR, dest, src);
933 return;
934 }
935
936 if (dest == src) {
937 tcg_out_movi(s, type, TCG_TMP0, 0xffff);
938 src = TCG_TMP0;
939 } else {
940 tcg_out_movi(s, type, dest, 0xffff);
941 }
942 if (type == TCG_TYPE_I32) {
943 tcg_out_insn(s, RR, NR, dest, src);
944 } else {
945 tcg_out_insn(s, RRE, NGR, dest, src);
946 }
947}
948
949static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
950{
951 tcg_out_insn(s, RRE, LGFR, dest, src);
952}
953
954static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
955{
956 tcg_out_insn(s, RRE, LLGFR, dest, src);
957}
958
959static inline void tgen32_addi(TCGContext *s, TCGReg dest, int32_t val)
960{
961 if (val == (int16_t)val) {
962 tcg_out_insn(s, RI, AHI, dest, val);
963 } else {
964 tcg_out_insn(s, RIL, AFI, dest, val);
965 }
966}
967
968static inline void tgen64_addi(TCGContext *s, TCGReg dest, int64_t val)
969{
970 if (val == (int16_t)val) {
971 tcg_out_insn(s, RI, AGHI, dest, val);
972 } else if (val == (int32_t)val) {
973 tcg_out_insn(s, RIL, AGFI, dest, val);
974 } else if (val == (uint32_t)val) {
975 tcg_out_insn(s, RIL, ALGFI, dest, val);
976 } else {
977 tcg_abort();
978 }
979
980}
981
982static void tgen64_andi(TCGContext *s, TCGReg dest, tcg_target_ulong val)
983{
984 static const S390Opcode ni_insns[4] = {
985 RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
986 };
987 static const S390Opcode nif_insns[2] = {
988 RIL_NILF, RIL_NIHF
989 };
990
991 int i;
992
993 /* Look for no-op. */
994 if (val == -1) {
995 return;
996 }
997
998 /* Look for the zero-extensions. */
999 if (val == 0xffffffff) {
1000 tgen_ext32u(s, dest, dest);
1001 return;
1002 }
1003
1004 if (facilities & FACILITY_EXT_IMM) {
1005 if (val == 0xff) {
1006 tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
1007 return;
1008 }
1009 if (val == 0xffff) {
1010 tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
1011 return;
1012 }
1013
1014 /* Try all 32-bit insns that can perform it in one go. */
1015 for (i = 0; i < 4; i++) {
1016 tcg_target_ulong mask = ~(0xffffull << i*16);
1017 if ((val & mask) == mask) {
1018 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1019 return;
1020 }
1021 }
1022
1023 /* Try all 48-bit insns that can perform it in one go. */
1024 if (facilities & FACILITY_EXT_IMM) {
1025 for (i = 0; i < 2; i++) {
1026 tcg_target_ulong mask = ~(0xffffffffull << i*32);
1027 if ((val & mask) == mask) {
1028 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1029 return;
1030 }
1031 }
1032 }
1033
1034 /* Perform the AND via sequential modifications to the high and low
1035 parts. Do this via recursion to handle 16-bit vs 32-bit masks in
1036 each half. */
1037 tgen64_andi(s, dest, val | 0xffffffff00000000ull);
1038 tgen64_andi(s, dest, val | 0x00000000ffffffffull);
1039 } else {
1040 /* With no extended-immediate facility, just emit the sequence. */
1041 for (i = 0; i < 4; i++) {
1042 tcg_target_ulong mask = 0xffffull << i*16;
1043 if ((val & mask) != mask) {
1044 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
1045 }
1046 }
1047 }
1048}
1049
1050static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1051{
1052 static const S390Opcode oi_insns[4] = {
1053 RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
1054 };
1055 static const S390Opcode nif_insns[2] = {
1056 RIL_OILF, RIL_OIHF
1057 };
1058
1059 int i;
1060
1061 /* Look for no-op. */
1062 if (val == 0) {
1063 return;
1064 }
1065
1066 if (facilities & FACILITY_EXT_IMM) {
1067 /* Try all 32-bit insns that can perform it in one go. */
1068 for (i = 0; i < 4; i++) {
1069 tcg_target_ulong mask = (0xffffull << i*16);
1070 if ((val & mask) != 0 && (val & ~mask) == 0) {
1071 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1072 return;
1073 }
1074 }
1075
1076 /* Try all 48-bit insns that can perform it in one go. */
1077 for (i = 0; i < 2; i++) {
1078 tcg_target_ulong mask = (0xffffffffull << i*32);
1079 if ((val & mask) != 0 && (val & ~mask) == 0) {
1080 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
1081 return;
1082 }
1083 }
1084
1085 /* Perform the OR via sequential modifications to the high and
1086 low parts. Do this via recursion to handle 16-bit vs 32-bit
1087 masks in each half. */
1088 tgen64_ori(s, dest, val & 0x00000000ffffffffull);
1089 tgen64_ori(s, dest, val & 0xffffffff00000000ull);
1090 } else {
1091 /* With no extended-immediate facility, we don't need to be so
1092 clever. Just iterate over the insns and mask in the constant. */
1093 for (i = 0; i < 4; i++) {
1094 tcg_target_ulong mask = (0xffffull << i*16);
1095 if ((val & mask) != 0) {
1096 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
1097 }
1098 }
1099 }
1100}
1101
1102static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1103{
1104 /* Perform the xor by parts. */
1105 if (val & 0xffffffff) {
1106 tcg_out_insn(s, RIL, XILF, dest, val);
1107 }
1108 if (val > 0xffffffff) {
1109 tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
1110 }
1111}
1112
1113static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
1114 TCGArg c2, int c2const)
1115{
bcc66562 1116 bool is_unsigned = is_unsigned_cond(c);
48bb3750
RH
1117 if (c2const) {
1118 if (c2 == 0) {
1119 if (type == TCG_TYPE_I32) {
1120 tcg_out_insn(s, RR, LTR, r1, r1);
1121 } else {
1122 tcg_out_insn(s, RRE, LTGR, r1, r1);
1123 }
1124 return tcg_cond_to_ltr_cond[c];
1125 } else {
1126 if (is_unsigned) {
1127 if (type == TCG_TYPE_I32) {
1128 tcg_out_insn(s, RIL, CLFI, r1, c2);
1129 } else {
1130 tcg_out_insn(s, RIL, CLGFI, r1, c2);
1131 }
1132 } else {
1133 if (type == TCG_TYPE_I32) {
1134 tcg_out_insn(s, RIL, CFI, r1, c2);
1135 } else {
1136 tcg_out_insn(s, RIL, CGFI, r1, c2);
1137 }
1138 }
1139 }
1140 } else {
1141 if (is_unsigned) {
1142 if (type == TCG_TYPE_I32) {
1143 tcg_out_insn(s, RR, CLR, r1, c2);
1144 } else {
1145 tcg_out_insn(s, RRE, CLGR, r1, c2);
1146 }
1147 } else {
1148 if (type == TCG_TYPE_I32) {
1149 tcg_out_insn(s, RR, CR, r1, c2);
1150 } else {
1151 tcg_out_insn(s, RRE, CGR, r1, c2);
1152 }
1153 }
1154 }
1155 return tcg_cond_to_s390_cond[c];
1156}
1157
1158static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
1159 TCGReg dest, TCGReg r1, TCGArg c2, int c2const)
1160{
1161 int cc = tgen_cmp(s, type, c, r1, c2, c2const);
1162
1163 /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over: */
1164 tcg_out_movi(s, type, dest, 1);
1165 tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
1166 tcg_out_movi(s, type, dest, 0);
1167}
1168
1169static void tgen_gotoi(TCGContext *s, int cc, tcg_target_long dest)
1170{
1171 tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1172 if (off > -0x8000 && off < 0x7fff) {
1173 tcg_out_insn(s, RI, BRC, cc, off);
1174 } else if (off == (int32_t)off) {
1175 tcg_out_insn(s, RIL, BRCL, cc, off);
1176 } else {
1177 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1178 tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
1179 }
1180}
1181
1182static void tgen_branch(TCGContext *s, int cc, int labelno)
1183{
1184 TCGLabel* l = &s->labels[labelno];
1185 if (l->has_value) {
1186 tgen_gotoi(s, cc, l->u.value);
1187 } else if (USE_LONG_BRANCHES) {
1188 tcg_out16(s, RIL_BRCL | (cc << 4));
1189 tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
1190 s->code_ptr += 4;
1191 } else {
1192 tcg_out16(s, RI_BRC | (cc << 4));
1193 tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
1194 s->code_ptr += 2;
1195 }
1196}
1197
1198static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
1199 TCGReg r1, TCGReg r2, int labelno)
1200{
1201 TCGLabel* l = &s->labels[labelno];
1202 tcg_target_long off;
1203
1204 if (l->has_value) {
1205 off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1206 } else {
1207 /* We need to keep the offset unchanged for retranslation. */
1208 off = ((int16_t *)s->code_ptr)[1];
1209 tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1210 }
1211
1212 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
1213 tcg_out16(s, off);
1214 tcg_out16(s, cc << 12 | (opc & 0xff));
1215}
1216
1217static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
1218 TCGReg r1, int i2, int labelno)
1219{
1220 TCGLabel* l = &s->labels[labelno];
1221 tcg_target_long off;
1222
1223 if (l->has_value) {
1224 off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
1225 } else {
1226 /* We need to keep the offset unchanged for retranslation. */
1227 off = ((int16_t *)s->code_ptr)[1];
1228 tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
1229 }
1230
1231 tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
1232 tcg_out16(s, off);
1233 tcg_out16(s, (i2 << 8) | (opc & 0xff));
1234}
1235
1236static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
1237 TCGReg r1, TCGArg c2, int c2const, int labelno)
1238{
1239 int cc;
1240
1241 if (facilities & FACILITY_GEN_INST_EXT) {
1242 bool is_unsigned = (c > TCG_COND_GT);
1243 bool in_range;
1244 S390Opcode opc;
1245
1246 cc = tcg_cond_to_s390_cond[c];
1247
1248 if (!c2const) {
1249 opc = (type == TCG_TYPE_I32
1250 ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
1251 : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
1252 tgen_compare_branch(s, opc, cc, r1, c2, labelno);
1253 return;
1254 }
1255
1256 /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
1257 If the immediate we've been given does not fit that range, we'll
1258 fall back to separate compare and branch instructions using the
1259 larger comparison range afforded by COMPARE IMMEDIATE. */
1260 if (type == TCG_TYPE_I32) {
1261 if (is_unsigned) {
1262 opc = RIE_CLIJ;
1263 in_range = (uint32_t)c2 == (uint8_t)c2;
1264 } else {
1265 opc = RIE_CIJ;
1266 in_range = (int32_t)c2 == (int8_t)c2;
1267 }
1268 } else {
1269 if (is_unsigned) {
1270 opc = RIE_CLGIJ;
1271 in_range = (uint64_t)c2 == (uint8_t)c2;
1272 } else {
1273 opc = RIE_CGIJ;
1274 in_range = (int64_t)c2 == (int8_t)c2;
1275 }
1276 }
1277 if (in_range) {
1278 tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
1279 return;
1280 }
1281 }
1282
1283 cc = tgen_cmp(s, type, c, r1, c2, c2const);
1284 tgen_branch(s, cc, labelno);
1285}
1286
1287static void tgen_calli(TCGContext *s, tcg_target_long dest)
1288{
1289 tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
1290 if (off == (int32_t)off) {
1291 tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
1292 } else {
1293 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
1294 tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
1295 }
1296}
1297
1298static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data,
1299 TCGReg base, TCGReg index, int disp)
1300{
1301#ifdef TARGET_WORDS_BIGENDIAN
1302 const int bswap = 0;
1303#else
1304 const int bswap = 1;
1305#endif
1306 switch (opc) {
1307 case LD_UINT8:
1308 tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
1309 break;
1310 case LD_INT8:
1311 tcg_out_insn(s, RXY, LGB, data, base, index, disp);
1312 break;
1313 case LD_UINT16:
1314 if (bswap) {
1315 /* swapped unsigned halfword load with upper bits zeroed */
1316 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1317 tgen_ext16u(s, TCG_TYPE_I64, data, data);
1318 } else {
1319 tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
1320 }
1321 break;
1322 case LD_INT16:
1323 if (bswap) {
1324 /* swapped sign-extended halfword load */
1325 tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
1326 tgen_ext16s(s, TCG_TYPE_I64, data, data);
1327 } else {
1328 tcg_out_insn(s, RXY, LGH, data, base, index, disp);
1329 }
1330 break;
1331 case LD_UINT32:
1332 if (bswap) {
1333 /* swapped unsigned int load with upper bits zeroed */
1334 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1335 tgen_ext32u(s, data, data);
1336 } else {
1337 tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
1338 }
1339 break;
1340 case LD_INT32:
1341 if (bswap) {
1342 /* swapped sign-extended int load */
1343 tcg_out_insn(s, RXY, LRV, data, base, index, disp);
1344 tgen_ext32s(s, data, data);
1345 } else {
1346 tcg_out_insn(s, RXY, LGF, data, base, index, disp);
1347 }
1348 break;
1349 case LD_UINT64:
1350 if (bswap) {
1351 tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
1352 } else {
1353 tcg_out_insn(s, RXY, LG, data, base, index, disp);
1354 }
1355 break;
1356 default:
1357 tcg_abort();
1358 }
1359}
1360
1361static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data,
1362 TCGReg base, TCGReg index, int disp)
1363{
1364#ifdef TARGET_WORDS_BIGENDIAN
1365 const int bswap = 0;
1366#else
1367 const int bswap = 1;
1368#endif
1369 switch (opc) {
1370 case LD_UINT8:
1371 if (disp >= 0 && disp < 0x1000) {
1372 tcg_out_insn(s, RX, STC, data, base, index, disp);
1373 } else {
1374 tcg_out_insn(s, RXY, STCY, data, base, index, disp);
1375 }
1376 break;
1377 case LD_UINT16:
1378 if (bswap) {
1379 tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
1380 } else if (disp >= 0 && disp < 0x1000) {
1381 tcg_out_insn(s, RX, STH, data, base, index, disp);
1382 } else {
1383 tcg_out_insn(s, RXY, STHY, data, base, index, disp);
1384 }
1385 break;
1386 case LD_UINT32:
1387 if (bswap) {
1388 tcg_out_insn(s, RXY, STRV, data, base, index, disp);
1389 } else if (disp >= 0 && disp < 0x1000) {
1390 tcg_out_insn(s, RX, ST, data, base, index, disp);
1391 } else {
1392 tcg_out_insn(s, RXY, STY, data, base, index, disp);
1393 }
1394 break;
1395 case LD_UINT64:
1396 if (bswap) {
1397 tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
1398 } else {
1399 tcg_out_insn(s, RXY, STG, data, base, index, disp);
1400 }
1401 break;
1402 default:
1403 tcg_abort();
1404 }
1405}
1406
1407#if defined(CONFIG_SOFTMMU)
1408static void tgen64_andi_tmp(TCGContext *s, TCGReg dest, tcg_target_ulong val)
1409{
1410 if (tcg_match_andi(0, val)) {
1411 tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, val);
1412 tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
1413 } else {
1414 tgen64_andi(s, dest, val);
1415 }
1416}
1417
1418static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
1419 TCGReg addr_reg, int mem_index, int opc,
1420 uint16_t **label2_ptr_p, int is_store)
1421{
1422 const TCGReg arg0 = TCG_REG_R2;
1423 const TCGReg arg1 = TCG_REG_R3;
1424 int s_bits = opc & 3;
1425 uint16_t *label1_ptr;
1426 tcg_target_long ofs;
1427
1428 if (TARGET_LONG_BITS == 32) {
1429 tgen_ext32u(s, arg0, addr_reg);
1430 } else {
1431 tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
1432 }
1433
1434 tcg_out_sh64(s, RSY_SRLG, arg1, addr_reg, TCG_REG_NONE,
1435 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1436
1437 tgen64_andi_tmp(s, arg0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1438 tgen64_andi_tmp(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1439
1440 if (is_store) {
9349b4f9 1441 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
48bb3750 1442 } else {
9349b4f9 1443 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
48bb3750
RH
1444 }
1445 assert(ofs < 0x80000);
1446
1447 if (TARGET_LONG_BITS == 32) {
1448 tcg_out_mem(s, RX_C, RXY_CY, arg0, arg1, TCG_AREG0, ofs);
1449 } else {
1450 tcg_out_mem(s, 0, RXY_CG, arg0, arg1, TCG_AREG0, ofs);
1451 }
1452
1453 if (TARGET_LONG_BITS == 32) {
1454 tgen_ext32u(s, arg0, addr_reg);
1455 } else {
1456 tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
1457 }
1458
1459 label1_ptr = (uint16_t*)s->code_ptr;
1460
1461 /* je label1 (offset will be patched in later) */
1462 tcg_out_insn(s, RI, BRC, S390_CC_EQ, 0);
1463
1464 /* call load/store helper */
1465 if (is_store) {
1466 /* Make sure to zero-extend the value to the full register
1467 for the calling convention. */
1468 switch (opc) {
1469 case LD_UINT8:
1470 tgen_ext8u(s, TCG_TYPE_I64, arg1, data_reg);
1471 break;
1472 case LD_UINT16:
1473 tgen_ext16u(s, TCG_TYPE_I64, arg1, data_reg);
1474 break;
1475 case LD_UINT32:
1476 tgen_ext32u(s, arg1, data_reg);
1477 break;
1478 case LD_UINT64:
1479 tcg_out_mov(s, TCG_TYPE_I64, arg1, data_reg);
1480 break;
1481 default:
1482 tcg_abort();
1483 }
1484 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
e141ab52 1485 /* XXX/FIXME: suboptimal */
6845df48
AJ
1486 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
1487 tcg_target_call_iarg_regs[2]);
1488 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
e141ab52 1489 tcg_target_call_iarg_regs[1]);
6845df48 1490 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
e141ab52 1491 tcg_target_call_iarg_regs[0]);
6845df48 1492 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
e141ab52 1493 TCG_AREG0);
48bb3750
RH
1494 tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
1495 } else {
1496 tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
e141ab52 1497 /* XXX/FIXME: suboptimal */
e141ab52
BS
1498 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
1499 tcg_target_call_iarg_regs[1]);
6845df48 1500 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
e141ab52 1501 tcg_target_call_iarg_regs[0]);
6845df48 1502 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
e141ab52 1503 TCG_AREG0);
48bb3750
RH
1504 tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
1505
1506 /* sign extension */
1507 switch (opc) {
1508 case LD_INT8:
1509 tgen_ext8s(s, TCG_TYPE_I64, data_reg, arg0);
1510 break;
1511 case LD_INT16:
1512 tgen_ext16s(s, TCG_TYPE_I64, data_reg, arg0);
1513 break;
1514 case LD_INT32:
1515 tgen_ext32s(s, data_reg, arg0);
1516 break;
1517 default:
1518 /* unsigned -> just copy */
1519 tcg_out_mov(s, TCG_TYPE_I64, data_reg, arg0);
1520 break;
1521 }
1522 }
1523
1524 /* jump to label2 (end) */
1525 *label2_ptr_p = (uint16_t*)s->code_ptr;
1526
1527 tcg_out_insn(s, RI, BRC, S390_CC_ALWAYS, 0);
1528
1529 /* this is label1, patch branch */
1530 *(label1_ptr + 1) = ((unsigned long)s->code_ptr -
1531 (unsigned long)label1_ptr) >> 1;
1532
9349b4f9 1533 ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
48bb3750
RH
1534 assert(ofs < 0x80000);
1535
1536 tcg_out_mem(s, 0, RXY_AG, arg0, arg1, TCG_AREG0, ofs);
1537}
1538
1539static void tcg_finish_qemu_ldst(TCGContext* s, uint16_t *label2_ptr)
1540{
1541 /* patch branch */
1542 *(label2_ptr + 1) = ((unsigned long)s->code_ptr -
1543 (unsigned long)label2_ptr) >> 1;
1544}
1545#else
1546static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
1547 TCGReg *index_reg, tcg_target_long *disp)
1548{
1549 if (TARGET_LONG_BITS == 32) {
1550 tgen_ext32u(s, TCG_TMP0, *addr_reg);
1551 *addr_reg = TCG_TMP0;
1552 }
1553 if (GUEST_BASE < 0x80000) {
1554 *index_reg = TCG_REG_NONE;
1555 *disp = GUEST_BASE;
1556 } else {
1557 *index_reg = TCG_GUEST_BASE_REG;
1558 *disp = 0;
1559 }
1560}
1561#endif /* CONFIG_SOFTMMU */
1562
1563/* load data with address translation (if applicable)
1564 and endianness conversion */
1565static void tcg_out_qemu_ld(TCGContext* s, const TCGArg* args, int opc)
1566{
1567 TCGReg addr_reg, data_reg;
1568#if defined(CONFIG_SOFTMMU)
1569 int mem_index;
1570 uint16_t *label2_ptr;
1571#else
1572 TCGReg index_reg;
1573 tcg_target_long disp;
1574#endif
1575
1576 data_reg = *args++;
1577 addr_reg = *args++;
1578
1579#if defined(CONFIG_SOFTMMU)
1580 mem_index = *args;
1581
1582 tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1583 opc, &label2_ptr, 0);
1584
1585 tcg_out_qemu_ld_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
1586
1587 tcg_finish_qemu_ldst(s, label2_ptr);
1588#else
1589 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1590 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1591#endif
1592}
1593
1594static void tcg_out_qemu_st(TCGContext* s, const TCGArg* args, int opc)
1595{
1596 TCGReg addr_reg, data_reg;
1597#if defined(CONFIG_SOFTMMU)
1598 int mem_index;
1599 uint16_t *label2_ptr;
1600#else
1601 TCGReg index_reg;
1602 tcg_target_long disp;
1603#endif
1604
1605 data_reg = *args++;
1606 addr_reg = *args++;
1607
1608#if defined(CONFIG_SOFTMMU)
1609 mem_index = *args;
1610
1611 tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
1612 opc, &label2_ptr, 1);
1613
1614 tcg_out_qemu_st_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
1615
1616 tcg_finish_qemu_ldst(s, label2_ptr);
1617#else
1618 tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
1619 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
1620#endif
2827822e
AG
1621}
1622
48bb3750
RH
1623#if TCG_TARGET_REG_BITS == 64
1624# define OP_32_64(x) \
1625 case glue(glue(INDEX_op_,x),_i32): \
1626 case glue(glue(INDEX_op_,x),_i64)
1627#else
1628# define OP_32_64(x) \
1629 case glue(glue(INDEX_op_,x),_i32)
1630#endif
1631
a9751609 1632static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
2827822e
AG
1633 const TCGArg *args, const int *const_args)
1634{
48bb3750
RH
1635 S390Opcode op;
1636
1637 switch (opc) {
1638 case INDEX_op_exit_tb:
1639 /* return value */
1640 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
1641 tgen_gotoi(s, S390_CC_ALWAYS, (unsigned long)tb_ret_addr);
1642 break;
1643
1644 case INDEX_op_goto_tb:
1645 if (s->tb_jmp_offset) {
1646 tcg_abort();
1647 } else {
1648 /* load address stored at s->tb_next + args[0] */
1649 tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0, s->tb_next + args[0]);
1650 /* and go there */
1651 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
1652 }
1653 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1654 break;
1655
1656 case INDEX_op_call:
1657 if (const_args[0]) {
1658 tgen_calli(s, args[0]);
1659 } else {
1660 tcg_out_insn(s, RR, BASR, TCG_REG_R14, args[0]);
1661 }
1662 break;
1663
1664 case INDEX_op_mov_i32:
1665 tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1666 break;
1667 case INDEX_op_movi_i32:
1668 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1669 break;
1670
1671 OP_32_64(ld8u):
1672 /* ??? LLC (RXY format) is only present with the extended-immediate
1673 facility, whereas LLGC is always present. */
1674 tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
1675 break;
1676
1677 OP_32_64(ld8s):
1678 /* ??? LB is no smaller than LGB, so no point to using it. */
1679 tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
1680 break;
1681
1682 OP_32_64(ld16u):
1683 /* ??? LLH (RXY format) is only present with the extended-immediate
1684 facility, whereas LLGH is always present. */
1685 tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
1686 break;
1687
1688 case INDEX_op_ld16s_i32:
1689 tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
1690 break;
1691
1692 case INDEX_op_ld_i32:
1693 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1694 break;
1695
1696 OP_32_64(st8):
1697 tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
1698 TCG_REG_NONE, args[2]);
1699 break;
1700
1701 OP_32_64(st16):
1702 tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
1703 TCG_REG_NONE, args[2]);
1704 break;
1705
1706 case INDEX_op_st_i32:
1707 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1708 break;
1709
1710 case INDEX_op_add_i32:
1711 if (const_args[2]) {
1712 tgen32_addi(s, args[0], args[2]);
1713 } else {
1714 tcg_out_insn(s, RR, AR, args[0], args[2]);
1715 }
1716 break;
1717 case INDEX_op_sub_i32:
1718 if (const_args[2]) {
1719 tgen32_addi(s, args[0], -args[2]);
1720 } else {
1721 tcg_out_insn(s, RR, SR, args[0], args[2]);
1722 }
1723 break;
1724
1725 case INDEX_op_and_i32:
1726 if (const_args[2]) {
1727 tgen64_andi(s, args[0], args[2] | 0xffffffff00000000ull);
1728 } else {
1729 tcg_out_insn(s, RR, NR, args[0], args[2]);
1730 }
1731 break;
1732 case INDEX_op_or_i32:
1733 if (const_args[2]) {
1734 tgen64_ori(s, args[0], args[2] & 0xffffffff);
1735 } else {
1736 tcg_out_insn(s, RR, OR, args[0], args[2]);
1737 }
1738 break;
1739 case INDEX_op_xor_i32:
1740 if (const_args[2]) {
1741 tgen64_xori(s, args[0], args[2] & 0xffffffff);
1742 } else {
1743 tcg_out_insn(s, RR, XR, args[0], args[2]);
1744 }
1745 break;
1746
1747 case INDEX_op_neg_i32:
1748 tcg_out_insn(s, RR, LCR, args[0], args[1]);
1749 break;
1750
1751 case INDEX_op_mul_i32:
1752 if (const_args[2]) {
1753 if ((int32_t)args[2] == (int16_t)args[2]) {
1754 tcg_out_insn(s, RI, MHI, args[0], args[2]);
1755 } else {
1756 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
1757 }
1758 } else {
1759 tcg_out_insn(s, RRE, MSR, args[0], args[2]);
1760 }
1761 break;
1762
1763 case INDEX_op_div2_i32:
1764 tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
1765 break;
1766 case INDEX_op_divu2_i32:
1767 tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
1768 break;
1769
1770 case INDEX_op_shl_i32:
1771 op = RS_SLL;
1772 do_shift32:
1773 if (const_args[2]) {
1774 tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
1775 } else {
1776 tcg_out_sh32(s, op, args[0], args[2], 0);
1777 }
1778 break;
1779 case INDEX_op_shr_i32:
1780 op = RS_SRL;
1781 goto do_shift32;
1782 case INDEX_op_sar_i32:
1783 op = RS_SRA;
1784 goto do_shift32;
1785
1786 case INDEX_op_rotl_i32:
1787 /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol. */
1788 if (const_args[2]) {
1789 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
1790 } else {
1791 tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
1792 }
1793 break;
1794 case INDEX_op_rotr_i32:
1795 if (const_args[2]) {
1796 tcg_out_sh64(s, RSY_RLL, args[0], args[1],
1797 TCG_REG_NONE, (32 - args[2]) & 31);
1798 } else {
1799 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
1800 tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
1801 }
1802 break;
1803
1804 case INDEX_op_ext8s_i32:
1805 tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
1806 break;
1807 case INDEX_op_ext16s_i32:
1808 tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
1809 break;
1810 case INDEX_op_ext8u_i32:
1811 tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
1812 break;
1813 case INDEX_op_ext16u_i32:
1814 tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
1815 break;
1816
1817 OP_32_64(bswap16):
1818 /* The TCG bswap definition requires bits 0-47 already be zero.
1819 Thus we don't need the G-type insns to implement bswap16_i64. */
1820 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1821 tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
1822 break;
1823 OP_32_64(bswap32):
1824 tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
1825 break;
1826
1827 case INDEX_op_br:
1828 tgen_branch(s, S390_CC_ALWAYS, args[0]);
1829 break;
1830
1831 case INDEX_op_brcond_i32:
1832 tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
1833 args[1], const_args[1], args[3]);
1834 break;
1835 case INDEX_op_setcond_i32:
1836 tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
1837 args[2], const_args[2]);
1838 break;
1839
1840 case INDEX_op_qemu_ld8u:
1841 tcg_out_qemu_ld(s, args, LD_UINT8);
1842 break;
1843 case INDEX_op_qemu_ld8s:
1844 tcg_out_qemu_ld(s, args, LD_INT8);
1845 break;
1846 case INDEX_op_qemu_ld16u:
1847 tcg_out_qemu_ld(s, args, LD_UINT16);
1848 break;
1849 case INDEX_op_qemu_ld16s:
1850 tcg_out_qemu_ld(s, args, LD_INT16);
1851 break;
1852 case INDEX_op_qemu_ld32:
1853 /* ??? Technically we can use a non-extending instruction. */
1854 tcg_out_qemu_ld(s, args, LD_UINT32);
1855 break;
1856 case INDEX_op_qemu_ld64:
1857 tcg_out_qemu_ld(s, args, LD_UINT64);
1858 break;
1859
1860 case INDEX_op_qemu_st8:
1861 tcg_out_qemu_st(s, args, LD_UINT8);
1862 break;
1863 case INDEX_op_qemu_st16:
1864 tcg_out_qemu_st(s, args, LD_UINT16);
1865 break;
1866 case INDEX_op_qemu_st32:
1867 tcg_out_qemu_st(s, args, LD_UINT32);
1868 break;
1869 case INDEX_op_qemu_st64:
1870 tcg_out_qemu_st(s, args, LD_UINT64);
1871 break;
1872
1873#if TCG_TARGET_REG_BITS == 64
1874 case INDEX_op_mov_i64:
1875 tcg_out_mov(s, TCG_TYPE_I64, args[0], args[1]);
1876 break;
1877 case INDEX_op_movi_i64:
1878 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1879 break;
1880
1881 case INDEX_op_ld16s_i64:
1882 tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
1883 break;
1884 case INDEX_op_ld32u_i64:
1885 tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
1886 break;
1887 case INDEX_op_ld32s_i64:
1888 tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
1889 break;
1890 case INDEX_op_ld_i64:
1891 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1892 break;
1893
1894 case INDEX_op_st32_i64:
1895 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1896 break;
1897 case INDEX_op_st_i64:
1898 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1899 break;
1900
1901 case INDEX_op_add_i64:
1902 if (const_args[2]) {
1903 tgen64_addi(s, args[0], args[2]);
1904 } else {
1905 tcg_out_insn(s, RRE, AGR, args[0], args[2]);
1906 }
1907 break;
1908 case INDEX_op_sub_i64:
1909 if (const_args[2]) {
1910 tgen64_addi(s, args[0], -args[2]);
1911 } else {
1912 tcg_out_insn(s, RRE, SGR, args[0], args[2]);
1913 }
1914 break;
1915
1916 case INDEX_op_and_i64:
1917 if (const_args[2]) {
1918 tgen64_andi(s, args[0], args[2]);
1919 } else {
1920 tcg_out_insn(s, RRE, NGR, args[0], args[2]);
1921 }
1922 break;
1923 case INDEX_op_or_i64:
1924 if (const_args[2]) {
1925 tgen64_ori(s, args[0], args[2]);
1926 } else {
1927 tcg_out_insn(s, RRE, OGR, args[0], args[2]);
1928 }
1929 break;
1930 case INDEX_op_xor_i64:
1931 if (const_args[2]) {
1932 tgen64_xori(s, args[0], args[2]);
1933 } else {
1934 tcg_out_insn(s, RRE, XGR, args[0], args[2]);
1935 }
1936 break;
1937
1938 case INDEX_op_neg_i64:
1939 tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
1940 break;
1941 case INDEX_op_bswap64_i64:
1942 tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
1943 break;
1944
1945 case INDEX_op_mul_i64:
1946 if (const_args[2]) {
1947 if (args[2] == (int16_t)args[2]) {
1948 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
1949 } else {
1950 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
1951 }
1952 } else {
1953 tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
1954 }
1955 break;
1956
1957 case INDEX_op_div2_i64:
1958 /* ??? We get an unnecessary sign-extension of the dividend
1959 into R3 with this definition, but as we do in fact always
1960 produce both quotient and remainder using INDEX_op_div_i64
1961 instead requires jumping through even more hoops. */
1962 tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
1963 break;
1964 case INDEX_op_divu2_i64:
1965 tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
1966 break;
1967
1968 case INDEX_op_shl_i64:
1969 op = RSY_SLLG;
1970 do_shift64:
1971 if (const_args[2]) {
1972 tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
1973 } else {
1974 tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
1975 }
1976 break;
1977 case INDEX_op_shr_i64:
1978 op = RSY_SRLG;
1979 goto do_shift64;
1980 case INDEX_op_sar_i64:
1981 op = RSY_SRAG;
1982 goto do_shift64;
1983
1984 case INDEX_op_rotl_i64:
1985 if (const_args[2]) {
1986 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
1987 TCG_REG_NONE, args[2]);
1988 } else {
1989 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
1990 }
1991 break;
1992 case INDEX_op_rotr_i64:
1993 if (const_args[2]) {
1994 tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
1995 TCG_REG_NONE, (64 - args[2]) & 63);
1996 } else {
1997 /* We can use the smaller 32-bit negate because only the
1998 low 6 bits are examined for the rotate. */
1999 tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
2000 tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
2001 }
2002 break;
2003
2004 case INDEX_op_ext8s_i64:
2005 tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
2006 break;
2007 case INDEX_op_ext16s_i64:
2008 tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
2009 break;
2010 case INDEX_op_ext32s_i64:
2011 tgen_ext32s(s, args[0], args[1]);
2012 break;
2013 case INDEX_op_ext8u_i64:
2014 tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
2015 break;
2016 case INDEX_op_ext16u_i64:
2017 tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
2018 break;
2019 case INDEX_op_ext32u_i64:
2020 tgen_ext32u(s, args[0], args[1]);
2021 break;
2022
2023 case INDEX_op_brcond_i64:
2024 tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
2025 args[1], const_args[1], args[3]);
2026 break;
2027 case INDEX_op_setcond_i64:
2028 tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
2029 args[2], const_args[2]);
2030 break;
2031
2032 case INDEX_op_qemu_ld32u:
2033 tcg_out_qemu_ld(s, args, LD_UINT32);
2034 break;
2035 case INDEX_op_qemu_ld32s:
2036 tcg_out_qemu_ld(s, args, LD_INT32);
2037 break;
2038#endif /* TCG_TARGET_REG_BITS == 64 */
2039
48bb3750
RH
2040 default:
2041 fprintf(stderr,"unimplemented opc 0x%x\n",opc);
2042 tcg_abort();
2043 }
2827822e
AG
2044}
2045
48bb3750
RH
2046static const TCGTargetOpDef s390_op_defs[] = {
2047 { INDEX_op_exit_tb, { } },
2048 { INDEX_op_goto_tb, { } },
2049 { INDEX_op_call, { "ri" } },
48bb3750
RH
2050 { INDEX_op_br, { } },
2051
2052 { INDEX_op_mov_i32, { "r", "r" } },
2053 { INDEX_op_movi_i32, { "r" } },
2054
2055 { INDEX_op_ld8u_i32, { "r", "r" } },
2056 { INDEX_op_ld8s_i32, { "r", "r" } },
2057 { INDEX_op_ld16u_i32, { "r", "r" } },
2058 { INDEX_op_ld16s_i32, { "r", "r" } },
2059 { INDEX_op_ld_i32, { "r", "r" } },
2060 { INDEX_op_st8_i32, { "r", "r" } },
2061 { INDEX_op_st16_i32, { "r", "r" } },
2062 { INDEX_op_st_i32, { "r", "r" } },
2063
2064 { INDEX_op_add_i32, { "r", "0", "rWI" } },
2065 { INDEX_op_sub_i32, { "r", "0", "rWNI" } },
2066 { INDEX_op_mul_i32, { "r", "0", "rK" } },
2067
2068 { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
2069 { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
2070
2071 { INDEX_op_and_i32, { "r", "0", "rWA" } },
2072 { INDEX_op_or_i32, { "r", "0", "rWO" } },
2073 { INDEX_op_xor_i32, { "r", "0", "rWX" } },
2074
2075 { INDEX_op_neg_i32, { "r", "r" } },
2076
2077 { INDEX_op_shl_i32, { "r", "0", "Ri" } },
2078 { INDEX_op_shr_i32, { "r", "0", "Ri" } },
2079 { INDEX_op_sar_i32, { "r", "0", "Ri" } },
2080
2081 { INDEX_op_rotl_i32, { "r", "r", "Ri" } },
2082 { INDEX_op_rotr_i32, { "r", "r", "Ri" } },
2083
2084 { INDEX_op_ext8s_i32, { "r", "r" } },
2085 { INDEX_op_ext8u_i32, { "r", "r" } },
2086 { INDEX_op_ext16s_i32, { "r", "r" } },
2087 { INDEX_op_ext16u_i32, { "r", "r" } },
2088
2089 { INDEX_op_bswap16_i32, { "r", "r" } },
2090 { INDEX_op_bswap32_i32, { "r", "r" } },
2091
2092 { INDEX_op_brcond_i32, { "r", "rWC" } },
2093 { INDEX_op_setcond_i32, { "r", "r", "rWC" } },
2094
2095 { INDEX_op_qemu_ld8u, { "r", "L" } },
2096 { INDEX_op_qemu_ld8s, { "r", "L" } },
2097 { INDEX_op_qemu_ld16u, { "r", "L" } },
2098 { INDEX_op_qemu_ld16s, { "r", "L" } },
2099 { INDEX_op_qemu_ld32, { "r", "L" } },
2100 { INDEX_op_qemu_ld64, { "r", "L" } },
2101
2102 { INDEX_op_qemu_st8, { "L", "L" } },
2103 { INDEX_op_qemu_st16, { "L", "L" } },
2104 { INDEX_op_qemu_st32, { "L", "L" } },
2105 { INDEX_op_qemu_st64, { "L", "L" } },
2106
2107#if defined(__s390x__)
2108 { INDEX_op_mov_i64, { "r", "r" } },
2109 { INDEX_op_movi_i64, { "r" } },
2110
2111 { INDEX_op_ld8u_i64, { "r", "r" } },
2112 { INDEX_op_ld8s_i64, { "r", "r" } },
2113 { INDEX_op_ld16u_i64, { "r", "r" } },
2114 { INDEX_op_ld16s_i64, { "r", "r" } },
2115 { INDEX_op_ld32u_i64, { "r", "r" } },
2116 { INDEX_op_ld32s_i64, { "r", "r" } },
2117 { INDEX_op_ld_i64, { "r", "r" } },
2118
2119 { INDEX_op_st8_i64, { "r", "r" } },
2120 { INDEX_op_st16_i64, { "r", "r" } },
2121 { INDEX_op_st32_i64, { "r", "r" } },
2122 { INDEX_op_st_i64, { "r", "r" } },
2123
2124 { INDEX_op_add_i64, { "r", "0", "rI" } },
2125 { INDEX_op_sub_i64, { "r", "0", "rNI" } },
2126 { INDEX_op_mul_i64, { "r", "0", "rK" } },
2127
2128 { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
2129 { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
2130
2131 { INDEX_op_and_i64, { "r", "0", "rA" } },
2132 { INDEX_op_or_i64, { "r", "0", "rO" } },
2133 { INDEX_op_xor_i64, { "r", "0", "rX" } },
2134
2135 { INDEX_op_neg_i64, { "r", "r" } },
2136
2137 { INDEX_op_shl_i64, { "r", "r", "Ri" } },
2138 { INDEX_op_shr_i64, { "r", "r", "Ri" } },
2139 { INDEX_op_sar_i64, { "r", "r", "Ri" } },
2140
2141 { INDEX_op_rotl_i64, { "r", "r", "Ri" } },
2142 { INDEX_op_rotr_i64, { "r", "r", "Ri" } },
2143
2144 { INDEX_op_ext8s_i64, { "r", "r" } },
2145 { INDEX_op_ext8u_i64, { "r", "r" } },
2146 { INDEX_op_ext16s_i64, { "r", "r" } },
2147 { INDEX_op_ext16u_i64, { "r", "r" } },
2148 { INDEX_op_ext32s_i64, { "r", "r" } },
2149 { INDEX_op_ext32u_i64, { "r", "r" } },
2150
2151 { INDEX_op_bswap16_i64, { "r", "r" } },
2152 { INDEX_op_bswap32_i64, { "r", "r" } },
2153 { INDEX_op_bswap64_i64, { "r", "r" } },
2154
2155 { INDEX_op_brcond_i64, { "r", "rC" } },
2156 { INDEX_op_setcond_i64, { "r", "r", "rC" } },
2157
2158 { INDEX_op_qemu_ld32u, { "r", "L" } },
2159 { INDEX_op_qemu_ld32s, { "r", "L" } },
2160#endif
2161
2162 { -1 },
2163};
2164
2165/* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
2166 this information. However, getting at that entry is not easy this far
2167 away from main. Our options are: start searching from environ, but
2168 that fails as soon as someone does a setenv in between. Read the data
2169 from /proc/self/auxv. Or do the probing ourselves. The only thing
2170 extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
2171 that the kernel saves all 64-bits of the registers around traps while
2172 in 31-bit mode. But this is true of all "recent" kernels (ought to dig
2173 back and see from when this might not be true). */
2174
2175#include <signal.h>
2176
2177static volatile sig_atomic_t got_sigill;
2178
2179static void sigill_handler(int sig)
2827822e 2180{
48bb3750 2181 got_sigill = 1;
2827822e
AG
2182}
2183
48bb3750
RH
2184static void query_facilities(void)
2185{
2186 struct sigaction sa_old, sa_new;
2187 register int r0 __asm__("0");
2188 register void *r1 __asm__("1");
2189 int fail;
2190
2191 memset(&sa_new, 0, sizeof(sa_new));
2192 sa_new.sa_handler = sigill_handler;
2193 sigaction(SIGILL, &sa_new, &sa_old);
2194
2195 /* First, try STORE FACILITY LIST EXTENDED. If this is present, then
2196 we need not do any more probing. Unfortunately, this itself is an
2197 extension and the original STORE FACILITY LIST instruction is
2198 kernel-only, storing its results at absolute address 200. */
2199 /* stfle 0(%r1) */
2200 r1 = &facilities;
2201 asm volatile(".word 0xb2b0,0x1000"
2202 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
2203
2204 if (got_sigill) {
2205 /* STORE FACILITY EXTENDED is not available. Probe for one of each
2206 kind of instruction that we're interested in. */
2207 /* ??? Possibly some of these are in practice never present unless
2208 the store-facility-extended facility is also present. But since
2209 that isn't documented it's just better to probe for each. */
2210
2211 /* Test for z/Architecture. Required even in 31-bit mode. */
2212 got_sigill = 0;
2213 /* agr %r0,%r0 */
2214 asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
2215 if (!got_sigill) {
2216 facilities |= FACILITY_ZARCH_ACTIVE;
2217 }
2218
2219 /* Test for long displacement. */
2220 got_sigill = 0;
2221 /* ly %r0,0(%r1) */
2222 r1 = &facilities;
2223 asm volatile(".word 0xe300,0x1000,0x0058"
2224 : "=r"(r0) : "r"(r1) : "cc");
2225 if (!got_sigill) {
2226 facilities |= FACILITY_LONG_DISP;
2227 }
2228
2229 /* Test for extended immediates. */
2230 got_sigill = 0;
2231 /* afi %r0,0 */
2232 asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
2233 if (!got_sigill) {
2234 facilities |= FACILITY_EXT_IMM;
2235 }
2236
2237 /* Test for general-instructions-extension. */
2238 got_sigill = 0;
2239 /* msfi %r0,1 */
2240 asm volatile(".word 0xc201,0x0000,0x0001");
2241 if (!got_sigill) {
2242 facilities |= FACILITY_GEN_INST_EXT;
2243 }
2244 }
2245
2246 sigaction(SIGILL, &sa_old, NULL);
2247
2248 /* The translator currently uses these extensions unconditionally.
2249 Pruning this back to the base ESA/390 architecture doesn't seem
2250 worthwhile, since even the KVM target requires z/Arch. */
2251 fail = 0;
2252 if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
2253 fprintf(stderr, "TCG: z/Arch facility is required.\n");
2254 fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
2255 fail = 1;
2256 }
2257 if ((facilities & FACILITY_LONG_DISP) == 0) {
2258 fprintf(stderr, "TCG: long-displacement facility is required.\n");
2259 fail = 1;
2260 }
2261
2262 /* So far there's just enough support for 31-bit mode to let the
2263 compile succeed. This is good enough to run QEMU with KVM. */
2264 if (sizeof(void *) != 8) {
2265 fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
2266 fail = 1;
2267 }
2268
2269 if (fail) {
2270 exit(-1);
2271 }
2272}
2273
2274static void tcg_target_init(TCGContext *s)
2827822e 2275{
48bb3750
RH
2276#if !defined(CONFIG_USER_ONLY)
2277 /* fail safe */
2278 if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) {
2279 tcg_abort();
2280 }
2281#endif
2282
2283 query_facilities();
2284
2285 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2286 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2287
2288 tcg_regset_clear(tcg_target_call_clobber_regs);
2289 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2290 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2291 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2292 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2293 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2294 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2295 /* The return register can be considered call-clobbered. */
2296 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2297
2298 tcg_regset_clear(s->reserved_regs);
2299 tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
2300 /* XXX many insns can't be used with R0, so we better avoid it for now */
2301 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2302 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2303
2304 tcg_add_target_add_op_defs(s390_op_defs);
9349b4f9 2305 tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
614f104d 2306 CPU_TEMP_BUF_NLONGS * sizeof(long));
2827822e
AG
2307}
2308
48bb3750 2309static void tcg_target_qemu_prologue(TCGContext *s)
2827822e 2310{
48bb3750
RH
2311 /* stmg %r6,%r15,48(%r15) (save registers) */
2312 tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
2313
2314 /* aghi %r15,-160 (stack frame) */
2315 tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -160);
2316
2317 if (GUEST_BASE >= 0x80000) {
2318 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
2319 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2320 }
2321
cea5f9a2
BS
2322 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2323 /* br %r3 (go to TB) */
2324 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
48bb3750
RH
2325
2326 tb_ret_addr = s->code_ptr;
2327
2328 /* lmg %r6,%r15,208(%r15) (restore registers) */
2329 tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 208);
2330
2331 /* br %r14 (return) */
2332 tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
2827822e 2333}