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