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