2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2009-2010 Aurelien Jarno <aurelien@aurel32.net>
5 * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * Register definitions
31 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
32 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
33 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
34 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
35 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
36 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
37 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
38 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
39 "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
43 #ifdef CONFIG_USE_GUEST_BASE
44 #define TCG_GUEST_BASE_REG TCG_REG_R55
46 #define TCG_GUEST_BASE_REG TCG_REG_R0
52 /* Branch registers */
64 /* Floating point registers */
84 /* Predicate registers */
104 /* Application registers */
109 static const int tcg_target_reg_alloc_order[] = {
163 static const int tcg_target_call_iarg_regs[8] = {
174 static const int tcg_target_call_oarg_regs[] = {
182 /* bundle templates: stops (double bar in the IA64 manual) are marked with
183 an uppercase letter. */
212 OPC_ADD_A1 = 0x10000000000ull,
213 OPC_AND_A1 = 0x10060000000ull,
214 OPC_AND_A3 = 0x10160000000ull,
215 OPC_ANDCM_A1 = 0x10068000000ull,
216 OPC_ANDCM_A3 = 0x10168000000ull,
217 OPC_ADDS_A4 = 0x10800000000ull,
218 OPC_ADDL_A5 = 0x12000000000ull,
219 OPC_ALLOC_M34 = 0x02c00000000ull,
220 OPC_BR_DPTK_FEW_B1 = 0x08400000000ull,
221 OPC_BR_SPTK_MANY_B1 = 0x08000001000ull,
222 OPC_BR_CALL_SPNT_FEW_B3 = 0x0a200000000ull,
223 OPC_BR_SPTK_MANY_B4 = 0x00100001000ull,
224 OPC_BR_CALL_SPTK_MANY_B5 = 0x02100001000ull,
225 OPC_BR_RET_SPTK_MANY_B4 = 0x00108001100ull,
226 OPC_BRL_SPTK_MANY_X3 = 0x18000001000ull,
227 OPC_BRL_CALL_SPNT_MANY_X4 = 0x1a200001000ull,
228 OPC_BRL_CALL_SPTK_MANY_X4 = 0x1a000001000ull,
229 OPC_CMP_LT_A6 = 0x18000000000ull,
230 OPC_CMP_LTU_A6 = 0x1a000000000ull,
231 OPC_CMP_EQ_A6 = 0x1c000000000ull,
232 OPC_CMP4_LT_A6 = 0x18400000000ull,
233 OPC_CMP4_LTU_A6 = 0x1a400000000ull,
234 OPC_CMP4_EQ_A6 = 0x1c400000000ull,
235 OPC_DEP_I14 = 0x0ae00000000ull,
236 OPC_DEP_I15 = 0x08000000000ull,
237 OPC_DEP_Z_I12 = 0x0a600000000ull,
238 OPC_EXTR_I11 = 0x0a400002000ull,
239 OPC_EXTR_U_I11 = 0x0a400000000ull,
240 OPC_FCVT_FX_TRUNC_S1_F10 = 0x004d0000000ull,
241 OPC_FCVT_FXU_TRUNC_S1_F10 = 0x004d8000000ull,
242 OPC_FCVT_XF_F11 = 0x000e0000000ull,
243 OPC_FMA_S1_F1 = 0x10400000000ull,
244 OPC_FNMA_S1_F1 = 0x18400000000ull,
245 OPC_FRCPA_S1_F6 = 0x00600000000ull,
246 OPC_GETF_SIG_M19 = 0x08708000000ull,
247 OPC_LD1_M1 = 0x08000000000ull,
248 OPC_LD1_M3 = 0x0a000000000ull,
249 OPC_LD2_M1 = 0x08040000000ull,
250 OPC_LD2_M3 = 0x0a040000000ull,
251 OPC_LD4_M1 = 0x08080000000ull,
252 OPC_LD4_M3 = 0x0a080000000ull,
253 OPC_LD8_M1 = 0x080c0000000ull,
254 OPC_LD8_M3 = 0x0a0c0000000ull,
255 OPC_MUX1_I3 = 0x0eca0000000ull,
256 OPC_NOP_B9 = 0x04008000000ull,
257 OPC_NOP_F16 = 0x00008000000ull,
258 OPC_NOP_I18 = 0x00008000000ull,
259 OPC_NOP_M48 = 0x00008000000ull,
260 OPC_MOV_I21 = 0x00e00100000ull,
261 OPC_MOV_RET_I21 = 0x00e00500000ull,
262 OPC_MOV_I22 = 0x00188000000ull,
263 OPC_MOV_I_I26 = 0x00150000000ull,
264 OPC_MOVL_X2 = 0x0c000000000ull,
265 OPC_OR_A1 = 0x10070000000ull,
266 OPC_OR_A3 = 0x10170000000ull,
267 OPC_SETF_EXP_M18 = 0x0c748000000ull,
268 OPC_SETF_SIG_M18 = 0x0c708000000ull,
269 OPC_SHL_I7 = 0x0f240000000ull,
270 OPC_SHR_I5 = 0x0f220000000ull,
271 OPC_SHR_U_I5 = 0x0f200000000ull,
272 OPC_SHRP_I10 = 0x0ac00000000ull,
273 OPC_SXT1_I29 = 0x000a0000000ull,
274 OPC_SXT2_I29 = 0x000a8000000ull,
275 OPC_SXT4_I29 = 0x000b0000000ull,
276 OPC_ST1_M4 = 0x08c00000000ull,
277 OPC_ST2_M4 = 0x08c40000000ull,
278 OPC_ST4_M4 = 0x08c80000000ull,
279 OPC_ST8_M4 = 0x08cc0000000ull,
280 OPC_SUB_A1 = 0x10028000000ull,
281 OPC_SUB_A3 = 0x10128000000ull,
282 OPC_UNPACK4_L_I2 = 0x0f860000000ull,
283 OPC_XMA_L_F2 = 0x1d000000000ull,
284 OPC_XOR_A1 = 0x10078000000ull,
285 OPC_XOR_A3 = 0x10178000000ull,
286 OPC_ZXT1_I29 = 0x00080000000ull,
287 OPC_ZXT2_I29 = 0x00088000000ull,
288 OPC_ZXT4_I29 = 0x00090000000ull,
290 INSN_NOP_M = OPC_NOP_M48, /* nop.m 0 */
291 INSN_NOP_I = OPC_NOP_I18, /* nop.i 0 */
294 static inline uint64_t tcg_opc_a1(int qp, uint64_t opc, int r1,
298 | ((r3 & 0x7f) << 20)
299 | ((r2 & 0x7f) << 13)
304 static inline uint64_t tcg_opc_a3(int qp, uint64_t opc, int r1,
305 uint64_t imm, int r3)
308 | ((imm & 0x80) << 29) /* s */
309 | ((imm & 0x7f) << 13) /* imm7b */
310 | ((r3 & 0x7f) << 20)
315 static inline uint64_t tcg_opc_a4(int qp, uint64_t opc, int r1,
316 uint64_t imm, int r3)
319 | ((imm & 0x2000) << 23) /* s */
320 | ((imm & 0x1f80) << 20) /* imm6d */
321 | ((imm & 0x007f) << 13) /* imm7b */
322 | ((r3 & 0x7f) << 20)
327 static inline uint64_t tcg_opc_a5(int qp, uint64_t opc, int r1,
328 uint64_t imm, int r3)
331 | ((imm & 0x200000) << 15) /* s */
332 | ((imm & 0x1f0000) << 6) /* imm5c */
333 | ((imm & 0x00ff80) << 20) /* imm9d */
334 | ((imm & 0x00007f) << 13) /* imm7b */
335 | ((r3 & 0x03) << 20)
340 static inline uint64_t tcg_opc_a6(int qp, uint64_t opc, int p1,
341 int p2, int r2, int r3)
344 | ((p2 & 0x3f) << 27)
345 | ((r3 & 0x7f) << 20)
346 | ((r2 & 0x7f) << 13)
351 static inline uint64_t tcg_opc_b1(int qp, uint64_t opc, uint64_t imm)
354 | ((imm & 0x100000) << 16) /* s */
355 | ((imm & 0x0fffff) << 13) /* imm20b */
359 static inline uint64_t tcg_opc_b3(int qp, uint64_t opc, int b1, uint64_t imm)
362 | ((imm & 0x100000) << 16) /* s */
363 | ((imm & 0x0fffff) << 13) /* imm20b */
368 static inline uint64_t tcg_opc_b4(int qp, uint64_t opc, int b2)
375 static inline uint64_t tcg_opc_b5(int qp, uint64_t opc, int b1, int b2)
384 static inline uint64_t tcg_opc_b9(int qp, uint64_t opc, uint64_t imm)
387 | ((imm & 0x100000) << 16) /* i */
388 | ((imm & 0x0fffff) << 6) /* imm20a */
392 static inline uint64_t tcg_opc_f1(int qp, uint64_t opc, int f1,
393 int f3, int f4, int f2)
396 | ((f4 & 0x7f) << 27)
397 | ((f3 & 0x7f) << 20)
398 | ((f2 & 0x7f) << 13)
403 static inline uint64_t tcg_opc_f2(int qp, uint64_t opc, int f1,
404 int f3, int f4, int f2)
407 | ((f4 & 0x7f) << 27)
408 | ((f3 & 0x7f) << 20)
409 | ((f2 & 0x7f) << 13)
414 static inline uint64_t tcg_opc_f6(int qp, uint64_t opc, int f1,
415 int p2, int f2, int f3)
418 | ((p2 & 0x3f) << 27)
419 | ((f3 & 0x7f) << 20)
420 | ((f2 & 0x7f) << 13)
425 static inline uint64_t tcg_opc_f10(int qp, uint64_t opc, int f1, int f2)
428 | ((f2 & 0x7f) << 13)
433 static inline uint64_t tcg_opc_f11(int qp, uint64_t opc, int f1, int f2)
436 | ((f2 & 0x7f) << 13)
441 static inline uint64_t tcg_opc_f16(int qp, uint64_t opc, uint64_t imm)
444 | ((imm & 0x100000) << 16) /* i */
445 | ((imm & 0x0fffff) << 6) /* imm20a */
449 static inline uint64_t tcg_opc_i2(int qp, uint64_t opc, int r1,
453 | ((r3 & 0x7f) << 20)
454 | ((r2 & 0x7f) << 13)
459 static inline uint64_t tcg_opc_i3(int qp, uint64_t opc, int r1,
463 | ((mbtype & 0x0f) << 20)
464 | ((r2 & 0x7f) << 13)
469 static inline uint64_t tcg_opc_i5(int qp, uint64_t opc, int r1,
473 | ((r3 & 0x7f) << 20)
474 | ((r2 & 0x7f) << 13)
479 static inline uint64_t tcg_opc_i7(int qp, uint64_t opc, int r1,
483 | ((r3 & 0x7f) << 20)
484 | ((r2 & 0x7f) << 13)
489 static inline uint64_t tcg_opc_i10(int qp, uint64_t opc, int r1,
490 int r2, int r3, uint64_t count)
493 | ((count & 0x3f) << 27)
494 | ((r3 & 0x7f) << 20)
495 | ((r2 & 0x7f) << 13)
500 static inline uint64_t tcg_opc_i11(int qp, uint64_t opc, int r1,
501 int r3, uint64_t pos, uint64_t len)
504 | ((len & 0x3f) << 27)
505 | ((r3 & 0x7f) << 20)
506 | ((pos & 0x3f) << 14)
511 static inline uint64_t tcg_opc_i12(int qp, uint64_t opc, int r1,
512 int r2, uint64_t pos, uint64_t len)
515 | ((len & 0x3f) << 27)
516 | ((pos & 0x3f) << 20)
517 | ((r2 & 0x7f) << 13)
522 static inline uint64_t tcg_opc_i14(int qp, uint64_t opc, int r1, uint64_t imm,
523 int r3, uint64_t pos, uint64_t len)
526 | ((imm & 0x01) << 36)
527 | ((len & 0x3f) << 27)
528 | ((r3 & 0x7f) << 20)
529 | ((pos & 0x3f) << 14)
534 static inline uint64_t tcg_opc_i15(int qp, uint64_t opc, int r1, int r2,
535 int r3, uint64_t pos, uint64_t len)
538 | ((pos & 0x3f) << 31)
539 | ((len & 0x0f) << 27)
540 | ((r3 & 0x7f) << 20)
541 | ((r2 & 0x7f) << 13)
546 static inline uint64_t tcg_opc_i18(int qp, uint64_t opc, uint64_t imm)
549 | ((imm & 0x100000) << 16) /* i */
550 | ((imm & 0x0fffff) << 6) /* imm20a */
554 static inline uint64_t tcg_opc_i21(int qp, uint64_t opc, int b1,
555 int r2, uint64_t imm)
558 | ((imm & 0x1ff) << 24)
559 | ((r2 & 0x7f) << 13)
564 static inline uint64_t tcg_opc_i22(int qp, uint64_t opc, int r1, int b2)
572 static inline uint64_t tcg_opc_i26(int qp, uint64_t opc, int ar3, int r2)
575 | ((ar3 & 0x7f) << 20)
576 | ((r2 & 0x7f) << 13)
580 static inline uint64_t tcg_opc_i29(int qp, uint64_t opc, int r1, int r3)
583 | ((r3 & 0x7f) << 20)
588 static inline uint64_t tcg_opc_l2(uint64_t imm)
590 return (imm & 0x7fffffffffc00000ull) >> 22;
593 static inline uint64_t tcg_opc_l3(uint64_t imm)
595 return (imm & 0x07fffffffff00000ull) >> 18;
598 #define tcg_opc_l4 tcg_opc_l3
600 static inline uint64_t tcg_opc_m1(int qp, uint64_t opc, int r1, int r3)
603 | ((r3 & 0x7f) << 20)
608 static inline uint64_t tcg_opc_m3(int qp, uint64_t opc, int r1,
609 int r3, uint64_t imm)
612 | ((imm & 0x100) << 28) /* s */
613 | ((imm & 0x080) << 20) /* i */
614 | ((imm & 0x07f) << 13) /* imm7b */
615 | ((r3 & 0x7f) << 20)
620 static inline uint64_t tcg_opc_m4(int qp, uint64_t opc, int r2, int r3)
623 | ((r3 & 0x7f) << 20)
624 | ((r2 & 0x7f) << 13)
628 static inline uint64_t tcg_opc_m18(int qp, uint64_t opc, int f1, int r2)
631 | ((r2 & 0x7f) << 13)
636 static inline uint64_t tcg_opc_m19(int qp, uint64_t opc, int r1, int f2)
639 | ((f2 & 0x7f) << 13)
644 static inline uint64_t tcg_opc_m34(int qp, uint64_t opc, int r1,
645 int sof, int sol, int sor)
648 | ((sor & 0x0f) << 27)
649 | ((sol & 0x7f) << 20)
650 | ((sof & 0x7f) << 13)
655 static inline uint64_t tcg_opc_m48(int qp, uint64_t opc, uint64_t imm)
658 | ((imm & 0x100000) << 16) /* i */
659 | ((imm & 0x0fffff) << 6) /* imm20a */
663 static inline uint64_t tcg_opc_x2(int qp, uint64_t opc,
664 int r1, uint64_t imm)
667 | ((imm & 0x8000000000000000ull) >> 27) /* i */
668 | (imm & 0x0000000000200000ull) /* ic */
669 | ((imm & 0x00000000001f0000ull) << 6) /* imm5c */
670 | ((imm & 0x000000000000ff80ull) << 20) /* imm9d */
671 | ((imm & 0x000000000000007full) << 13) /* imm7b */
676 static inline uint64_t tcg_opc_x3(int qp, uint64_t opc, uint64_t imm)
679 | ((imm & 0x0800000000000000ull) >> 23) /* i */
680 | ((imm & 0x00000000000fffffull) << 13) /* imm20b */
684 static inline uint64_t tcg_opc_x4(int qp, uint64_t opc, int b1, uint64_t imm)
687 | ((imm & 0x0800000000000000ull) >> 23) /* i */
688 | ((imm & 0x00000000000fffffull) << 13) /* imm20b */
698 static inline void reloc_pcrel21b(void *pc, intptr_t target)
704 slot = (intptr_t)pc & 3;
705 pc = (void *)((intptr_t)pc & ~3);
707 disp = target - (intptr_t)pc;
708 imm = (uint64_t) disp >> 4;
712 *(uint64_t *)(pc + 0) = (*(uint64_t *)(pc + 8) & 0xfffffdc00003ffffull)
713 | ((imm & 0x100000) << 21) /* s */
714 | ((imm & 0x0fffff) << 18); /* imm20b */
717 *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xfffffffffffb8000ull)
718 | ((imm & 0x100000) >> 2) /* s */
719 | ((imm & 0x0fffe0) >> 5); /* imm20b */
720 *(uint64_t *)(pc + 0) = (*(uint64_t *)(pc + 0) & 0x07ffffffffffffffull)
721 | ((imm & 0x00001f) << 59); /* imm20b */
724 *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xf700000fffffffffull)
725 | ((imm & 0x100000) << 39) /* s */
726 | ((imm & 0x0fffff) << 36); /* imm20b */
731 static inline uint64_t get_reloc_pcrel21b (void *pc)
736 slot = (tcg_target_long) pc & 3;
737 pc = (void *)((tcg_target_long) pc & ~3);
739 low = (*(uint64_t *)(pc + 0));
740 high = (*(uint64_t *)(pc + 8));
744 return ((low >> 21) & 0x100000) + /* s */
745 ((low >> 18) & 0x0fffff); /* imm20b */
747 return ((high << 2) & 0x100000) + /* s */
748 ((high << 5) & 0x0fffe0) + /* imm20b */
749 ((low >> 59) & 0x00001f); /* imm20b */
751 return ((high >> 39) & 0x100000) + /* s */
752 ((high >> 36) & 0x0fffff); /* imm20b */
758 static inline void reloc_pcrel60b(void *pc, intptr_t target)
763 disp = target - (intptr_t)pc;
764 imm = (uint64_t) disp >> 4;
766 *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xf700000fff800000ull)
767 | (imm & 0x0800000000000000ull) /* s */
768 | ((imm & 0x07fffff000000000ull) >> 36) /* imm39 */
769 | ((imm & 0x00000000000fffffull) << 36); /* imm20b */
770 *(uint64_t *)(pc + 0) = (*(uint64_t *)(pc + 0) & 0x00003fffffffffffull)
771 | ((imm & 0x0000000ffff00000ull) << 28); /* imm39 */
774 static inline uint64_t get_reloc_pcrel60b (void *pc)
778 low = (*(uint64_t *)(pc + 0));
779 high = (*(uint64_t *)(pc + 8));
781 return ((high) & 0x0800000000000000ull) + /* s */
782 ((high >> 36) & 0x00000000000fffffull) + /* imm20b */
783 ((high << 36) & 0x07fffff000000000ull) + /* imm39 */
784 ((low >> 28) & 0x0000000ffff00000ull); /* imm39 */
788 static void patch_reloc(uint8_t *code_ptr, int type,
789 intptr_t value, intptr_t addend)
793 case R_IA64_PCREL21B:
794 reloc_pcrel21b(code_ptr, value);
796 case R_IA64_PCREL60B:
797 reloc_pcrel60b(code_ptr, value);
807 /* parse target specific constraints */
808 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
815 ct->ct |= TCG_CT_REG;
816 tcg_regset_set(ct->u.regs, 0xffffffffffffffffull);
819 ct->ct |= TCG_CT_CONST_S22;
822 ct->ct |= TCG_CT_REG;
823 tcg_regset_set(ct->u.regs, 0xffffffffffffffffull);
824 #if defined(CONFIG_SOFTMMU)
825 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R56);
826 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R57);
827 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R58);
831 /* We are cheating a bit here, using the fact that the register
832 r0 is also the register number 0. Hence there is no need
833 to check for const_args in each instruction. */
834 ct->ct |= TCG_CT_CONST_ZERO;
844 /* test if a constant matches the constraint */
845 static inline int tcg_target_const_match(tcg_target_long val,
846 const TCGArgConstraint *arg_ct)
850 if (ct & TCG_CT_CONST)
852 else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
854 else if ((ct & TCG_CT_CONST_S22) && val == ((int32_t)val << 10) >> 10)
864 static uint8_t *tb_ret_addr;
866 static inline void tcg_out_bundle(TCGContext *s, int template,
867 uint64_t slot0, uint64_t slot1,
870 template &= 0x1f; /* 5 bits */
871 slot0 &= 0x1ffffffffffull; /* 41 bits */
872 slot1 &= 0x1ffffffffffull; /* 41 bits */
873 slot2 &= 0x1ffffffffffull; /* 41 bits */
875 *(uint64_t *)(s->code_ptr + 0) = (slot1 << 46) | (slot0 << 5) | template;
876 *(uint64_t *)(s->code_ptr + 8) = (slot2 << 23) | (slot1 >> 18);
880 static inline uint64_t tcg_opc_mov_a(int qp, TCGReg dst, TCGReg src)
882 return tcg_opc_a4(qp, OPC_ADDS_A4, dst, 0, src);
885 static inline void tcg_out_mov(TCGContext *s, TCGType type,
886 TCGReg ret, TCGReg arg)
888 tcg_out_bundle(s, mmI,
891 tcg_opc_mov_a(TCG_REG_P0, ret, arg));
894 static inline uint64_t tcg_opc_movi_a(int qp, TCGReg dst, int64_t src)
896 assert(src == sextract64(src, 0, 22));
897 return tcg_opc_a5(qp, OPC_ADDL_A5, dst, src, TCG_REG_R0);
900 static inline void tcg_out_movi(TCGContext *s, TCGType type,
901 TCGReg reg, tcg_target_long arg)
903 tcg_out_bundle(s, mLX,
906 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, reg, arg));
909 static void tcg_out_br(TCGContext *s, int label_index)
911 TCGLabel *l = &s->labels[label_index];
913 /* We pay attention here to not modify the branch target by reading
914 the existing value and using it again. This ensure that caches and
915 memory are kept coherent during retranslation. */
916 tcg_out_bundle(s, mmB,
919 tcg_opc_b1 (TCG_REG_P0, OPC_BR_SPTK_MANY_B1,
920 get_reloc_pcrel21b(s->code_ptr + 2)));
923 reloc_pcrel21b((s->code_ptr - 16) + 2, l->u.value);
925 tcg_out_reloc(s, (s->code_ptr - 16) + 2,
926 R_IA64_PCREL21B, label_index, 0);
930 static inline void tcg_out_calli(TCGContext *s, uintptr_t addr)
932 /* Look through the function descriptor. */
933 uintptr_t disp, *desc = (uintptr_t *)addr;
934 tcg_out_bundle(s, mlx,
936 tcg_opc_l2 (desc[1]),
937 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R1, desc[1]));
938 disp = (desc[0] - (uintptr_t)s->code_ptr) >> 4;
939 tcg_out_bundle(s, mLX,
942 tcg_opc_x4 (TCG_REG_P0, OPC_BRL_CALL_SPTK_MANY_X4,
946 static inline void tcg_out_callr(TCGContext *s, TCGReg addr)
948 tcg_out_bundle(s, MmI,
949 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1, TCG_REG_R2, addr),
950 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R3, 8, addr),
951 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
952 TCG_REG_B6, TCG_REG_R2, 0));
953 tcg_out_bundle(s, mmB,
954 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R3),
956 tcg_opc_b5 (TCG_REG_P0, OPC_BR_CALL_SPTK_MANY_B5,
957 TCG_REG_B0, TCG_REG_B6));
960 static void tcg_out_exit_tb(TCGContext *s, tcg_target_long arg)
965 /* At least arg == 0 is a common operation. */
966 if (arg == sextract64(arg, 0, 22)) {
967 opc1 = tcg_opc_movi_a(TCG_REG_P0, TCG_REG_R8, arg);
969 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R8, arg);
973 disp = tb_ret_addr - s->code_ptr;
974 imm = (uint64_t)disp >> 4;
976 tcg_out_bundle(s, mLX,
979 tcg_opc_x3 (TCG_REG_P0, OPC_BRL_SPTK_MANY_X3, imm));
982 static inline void tcg_out_goto_tb(TCGContext *s, TCGArg arg)
984 if (s->tb_jmp_offset) {
985 /* direct jump method */
988 /* indirect jump method */
989 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2,
990 (tcg_target_long)(s->tb_next + arg));
991 tcg_out_bundle(s, MmI,
992 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1,
993 TCG_REG_R2, TCG_REG_R2),
995 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, TCG_REG_B6,
997 tcg_out_bundle(s, mmB,
1000 tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4,
1003 s->tb_next_offset[arg] = s->code_ptr - s->code_buf;
1006 static inline void tcg_out_jmp(TCGContext *s, TCGArg addr)
1008 tcg_out_bundle(s, mmI,
1011 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, TCG_REG_B6, addr, 0));
1012 tcg_out_bundle(s, mmB,
1015 tcg_opc_b4(TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
1018 static inline void tcg_out_ld_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg,
1019 TCGArg arg1, tcg_target_long arg2)
1021 if (arg2 == ((int16_t)arg2 >> 2) << 2) {
1022 tcg_out_bundle(s, MmI,
1023 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4,
1024 TCG_REG_R2, arg2, arg1),
1025 tcg_opc_m1 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1028 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, arg2);
1029 tcg_out_bundle(s, MmI,
1030 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1,
1031 TCG_REG_R2, TCG_REG_R2, arg1),
1032 tcg_opc_m1 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1037 static inline void tcg_out_st_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg,
1038 TCGArg arg1, tcg_target_long arg2)
1040 if (arg2 == ((int16_t)arg2 >> 2) << 2) {
1041 tcg_out_bundle(s, MmI,
1042 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4,
1043 TCG_REG_R2, arg2, arg1),
1044 tcg_opc_m4 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1047 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, arg2);
1048 tcg_out_bundle(s, MmI,
1049 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1,
1050 TCG_REG_R2, TCG_REG_R2, arg1),
1051 tcg_opc_m4 (TCG_REG_P0, opc_m4, arg, TCG_REG_R2),
1056 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
1057 TCGReg arg1, intptr_t arg2)
1059 if (type == TCG_TYPE_I32) {
1060 tcg_out_ld_rel(s, OPC_LD4_M1, arg, arg1, arg2);
1062 tcg_out_ld_rel(s, OPC_LD8_M1, arg, arg1, arg2);
1066 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1067 TCGReg arg1, intptr_t arg2)
1069 if (type == TCG_TYPE_I32) {
1070 tcg_out_st_rel(s, OPC_ST4_M4, arg, arg1, arg2);
1072 tcg_out_st_rel(s, OPC_ST8_M4, arg, arg1, arg2);
1076 static inline void tcg_out_alu(TCGContext *s, uint64_t opc_a1, uint64_t opc_a3,
1077 TCGReg ret, TCGArg arg1, int const_arg1,
1078 TCGArg arg2, int const_arg2)
1080 uint64_t opc1 = 0, opc2 = 0, opc3 = 0;
1082 if (const_arg2 && arg2 != 0) {
1083 opc2 = tcg_opc_movi_a(TCG_REG_P0, TCG_REG_R3, arg2);
1086 if (const_arg1 && arg1 != 0) {
1087 if (opc_a3 && arg1 == (int8_t)arg1) {
1088 opc3 = tcg_opc_a3(TCG_REG_P0, opc_a3, ret, arg1, arg2);
1090 opc1 = tcg_opc_movi_a(TCG_REG_P0, TCG_REG_R2, arg1);
1095 opc3 = tcg_opc_a1(TCG_REG_P0, opc_a1, ret, arg1, arg2);
1098 tcg_out_bundle(s, (opc1 || opc2 ? mII : miI),
1099 opc1 ? opc1 : INSN_NOP_M,
1100 opc2 ? opc2 : INSN_NOP_I,
1104 static inline void tcg_out_add(TCGContext *s, TCGReg ret, TCGReg arg1,
1105 TCGArg arg2, int const_arg2)
1107 if (const_arg2 && arg2 == sextract64(arg2, 0, 14)) {
1108 tcg_out_bundle(s, mmI,
1111 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4, ret, arg2, arg1));
1113 tcg_out_alu(s, OPC_ADD_A1, 0, ret, arg1, 0, arg2, const_arg2);
1117 static inline void tcg_out_sub(TCGContext *s, TCGReg ret, TCGArg arg1,
1118 int const_arg1, TCGArg arg2, int const_arg2)
1120 if (!const_arg1 && const_arg2 && -arg2 == sextract64(-arg2, 0, 14)) {
1121 tcg_out_bundle(s, mmI,
1124 tcg_opc_a4(TCG_REG_P0, OPC_ADDS_A4, ret, -arg2, arg1));
1126 tcg_out_alu(s, OPC_SUB_A1, OPC_SUB_A3, ret,
1127 arg1, const_arg1, arg2, const_arg2);
1131 static inline void tcg_out_eqv(TCGContext *s, TCGArg ret,
1132 TCGArg arg1, int const_arg1,
1133 TCGArg arg2, int const_arg2)
1135 tcg_out_bundle(s, mII,
1137 tcg_opc_a1 (TCG_REG_P0, OPC_XOR_A1, ret, arg1, arg2),
1138 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, ret, -1, ret));
1141 static inline void tcg_out_nand(TCGContext *s, TCGArg ret,
1142 TCGArg arg1, int const_arg1,
1143 TCGArg arg2, int const_arg2)
1145 tcg_out_bundle(s, mII,
1147 tcg_opc_a1 (TCG_REG_P0, OPC_AND_A1, ret, arg1, arg2),
1148 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, ret, -1, ret));
1151 static inline void tcg_out_nor(TCGContext *s, TCGArg ret,
1152 TCGArg arg1, int const_arg1,
1153 TCGArg arg2, int const_arg2)
1155 tcg_out_bundle(s, mII,
1157 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret, arg1, arg2),
1158 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, ret, -1, ret));
1161 static inline void tcg_out_orc(TCGContext *s, TCGArg ret,
1162 TCGArg arg1, int const_arg1,
1163 TCGArg arg2, int const_arg2)
1165 tcg_out_bundle(s, mII,
1167 tcg_opc_a3 (TCG_REG_P0, OPC_ANDCM_A3, TCG_REG_R2, -1, arg2),
1168 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret, arg1, TCG_REG_R2));
1171 static inline void tcg_out_mul(TCGContext *s, TCGArg ret,
1172 TCGArg arg1, TCGArg arg2)
1174 tcg_out_bundle(s, mmI,
1175 tcg_opc_m18(TCG_REG_P0, OPC_SETF_SIG_M18, TCG_REG_F6, arg1),
1176 tcg_opc_m18(TCG_REG_P0, OPC_SETF_SIG_M18, TCG_REG_F7, arg2),
1178 tcg_out_bundle(s, mmF,
1181 tcg_opc_f2 (TCG_REG_P0, OPC_XMA_L_F2, TCG_REG_F6, TCG_REG_F6,
1182 TCG_REG_F7, TCG_REG_F0));
1183 tcg_out_bundle(s, miI,
1184 tcg_opc_m19(TCG_REG_P0, OPC_GETF_SIG_M19, ret, TCG_REG_F6),
1189 static inline void tcg_out_sar_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1190 TCGArg arg2, int const_arg2)
1193 tcg_out_bundle(s, miI,
1196 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_I11,
1197 ret, arg1, arg2, 31 - arg2));
1199 tcg_out_bundle(s, mII,
1200 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3,
1201 TCG_REG_R3, 0x1f, arg2),
1202 tcg_opc_i29(TCG_REG_P0, OPC_SXT4_I29, TCG_REG_R2, arg1),
1203 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_I5, ret,
1204 TCG_REG_R2, TCG_REG_R3));
1208 static inline void tcg_out_sar_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1209 TCGArg arg2, int const_arg2)
1212 tcg_out_bundle(s, miI,
1215 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_I11,
1216 ret, arg1, arg2, 63 - arg2));
1218 tcg_out_bundle(s, miI,
1221 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_I5, ret, arg1, arg2));
1225 static inline void tcg_out_shl_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1226 TCGArg arg2, int const_arg2)
1229 tcg_out_bundle(s, miI,
1232 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret,
1233 arg1, 63 - arg2, 31 - arg2));
1235 tcg_out_bundle(s, mII,
1237 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R2,
1239 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, ret,
1244 static inline void tcg_out_shl_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1245 TCGArg arg2, int const_arg2)
1248 tcg_out_bundle(s, miI,
1251 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret,
1252 arg1, 63 - arg2, 63 - arg2));
1254 tcg_out_bundle(s, miI,
1257 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, ret,
1262 static inline void tcg_out_shr_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1263 TCGArg arg2, int const_arg2)
1266 tcg_out_bundle(s, miI,
1269 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1270 arg1, arg2, 31 - arg2));
1272 tcg_out_bundle(s, mII,
1273 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R3,
1275 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29, TCG_REG_R2, arg1),
1276 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1277 TCG_REG_R2, TCG_REG_R3));
1281 static inline void tcg_out_shr_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1282 TCGArg arg2, int const_arg2)
1285 tcg_out_bundle(s, miI,
1288 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1289 arg1, arg2, 63 - arg2));
1291 tcg_out_bundle(s, miI,
1294 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1299 static inline void tcg_out_rotl_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1300 TCGArg arg2, int const_arg2)
1303 tcg_out_bundle(s, mII,
1305 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1306 TCG_REG_R2, arg1, arg1),
1307 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1308 TCG_REG_R2, 32 - arg2, 31));
1310 tcg_out_bundle(s, miI,
1312 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1313 TCG_REG_R2, arg1, arg1),
1314 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R3,
1316 tcg_out_bundle(s, mII,
1318 tcg_opc_a3 (TCG_REG_P0, OPC_SUB_A3, TCG_REG_R3,
1320 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1321 TCG_REG_R2, TCG_REG_R3));
1325 static inline void tcg_out_rotl_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1326 TCGArg arg2, int const_arg2)
1329 tcg_out_bundle(s, miI,
1332 tcg_opc_i10(TCG_REG_P0, OPC_SHRP_I10, ret, arg1,
1333 arg1, 0x40 - arg2));
1335 tcg_out_bundle(s, mII,
1336 tcg_opc_a3 (TCG_REG_P0, OPC_SUB_A3, TCG_REG_R2,
1338 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, TCG_REG_R3,
1340 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, TCG_REG_R2,
1342 tcg_out_bundle(s, miI,
1345 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret,
1346 TCG_REG_R2, TCG_REG_R3));
1350 static inline void tcg_out_rotr_i32(TCGContext *s, TCGArg ret, TCGArg arg1,
1351 TCGArg arg2, int const_arg2)
1354 tcg_out_bundle(s, mII,
1356 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1357 TCG_REG_R2, arg1, arg1),
1358 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, ret,
1359 TCG_REG_R2, arg2, 31));
1361 tcg_out_bundle(s, mII,
1362 tcg_opc_a3 (TCG_REG_P0, OPC_AND_A3, TCG_REG_R3,
1364 tcg_opc_i2 (TCG_REG_P0, OPC_UNPACK4_L_I2,
1365 TCG_REG_R2, arg1, arg1),
1366 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, ret,
1367 TCG_REG_R2, TCG_REG_R3));
1371 static inline void tcg_out_rotr_i64(TCGContext *s, TCGArg ret, TCGArg arg1,
1372 TCGArg arg2, int const_arg2)
1375 tcg_out_bundle(s, miI,
1378 tcg_opc_i10(TCG_REG_P0, OPC_SHRP_I10, ret, arg1,
1381 tcg_out_bundle(s, mII,
1382 tcg_opc_a3 (TCG_REG_P0, OPC_SUB_A3, TCG_REG_R2,
1384 tcg_opc_i5 (TCG_REG_P0, OPC_SHR_U_I5, TCG_REG_R3,
1386 tcg_opc_i7 (TCG_REG_P0, OPC_SHL_I7, TCG_REG_R2,
1388 tcg_out_bundle(s, miI,
1391 tcg_opc_a1 (TCG_REG_P0, OPC_OR_A1, ret,
1392 TCG_REG_R2, TCG_REG_R3));
1396 static const uint64_t opc_ext_i29[8] = {
1397 OPC_ZXT1_I29, OPC_ZXT2_I29, OPC_ZXT4_I29, 0,
1398 OPC_SXT1_I29, OPC_SXT2_I29, OPC_SXT4_I29, 0
1401 static inline uint64_t tcg_opc_ext_i(int qp, TCGMemOp opc, TCGReg d, TCGReg s)
1403 if ((opc & MO_SIZE) == MO_64) {
1404 return tcg_opc_mov_a(qp, d, s);
1406 return tcg_opc_i29(qp, opc_ext_i29[opc & MO_SSIZE], d, s);
1410 static inline void tcg_out_ext(TCGContext *s, uint64_t opc_i29,
1411 TCGArg ret, TCGArg arg)
1413 tcg_out_bundle(s, miI,
1416 tcg_opc_i29(TCG_REG_P0, opc_i29, ret, arg));
1419 static inline uint64_t tcg_opc_bswap64_i(int qp, TCGReg d, TCGReg s)
1421 return tcg_opc_i3(qp, OPC_MUX1_I3, d, s, 0xb);
1424 static inline void tcg_out_bswap16(TCGContext *s, TCGArg ret, TCGArg arg)
1426 tcg_out_bundle(s, mII,
1428 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret, arg, 15, 15),
1429 tcg_opc_bswap64_i(TCG_REG_P0, ret, ret));
1432 static inline void tcg_out_bswap32(TCGContext *s, TCGArg ret, TCGArg arg)
1434 tcg_out_bundle(s, mII,
1436 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, ret, arg, 31, 31),
1437 tcg_opc_bswap64_i(TCG_REG_P0, ret, ret));
1440 static inline void tcg_out_bswap64(TCGContext *s, TCGArg ret, TCGArg arg)
1442 tcg_out_bundle(s, miI,
1445 tcg_opc_bswap64_i(TCG_REG_P0, ret, arg));
1448 static inline void tcg_out_deposit(TCGContext *s, TCGArg ret, TCGArg a1,
1449 TCGArg a2, int const_a2, int pos, int len)
1451 uint64_t i1 = 0, i2 = 0;
1452 int cpos = 63 - pos, lm1 = len - 1;
1455 /* Truncate the value of a constant a2 to the width of the field. */
1456 int mask = (1u << len) - 1;
1459 if (a2 == 0 || a2 == mask) {
1460 /* 1-bit signed constant inserted into register. */
1461 i2 = tcg_opc_i14(TCG_REG_P0, OPC_DEP_I14, ret, a2, a1, cpos, lm1);
1463 /* Otherwise, load any constant into a temporary. Do this into
1464 the first I slot to help out with cross-unit delays. */
1465 i1 = tcg_opc_movi_a(TCG_REG_P0, TCG_REG_R2, a2);
1470 i2 = tcg_opc_i15(TCG_REG_P0, OPC_DEP_I15, ret, a2, a1, cpos, lm1);
1472 tcg_out_bundle(s, (i1 ? mII : miI),
1474 i1 ? i1 : INSN_NOP_I,
1478 static inline uint64_t tcg_opc_cmp_a(int qp, TCGCond cond, TCGArg arg1,
1479 TCGArg arg2, int cmp4)
1481 uint64_t opc_eq_a6, opc_lt_a6, opc_ltu_a6;
1484 opc_eq_a6 = OPC_CMP4_EQ_A6;
1485 opc_lt_a6 = OPC_CMP4_LT_A6;
1486 opc_ltu_a6 = OPC_CMP4_LTU_A6;
1488 opc_eq_a6 = OPC_CMP_EQ_A6;
1489 opc_lt_a6 = OPC_CMP_LT_A6;
1490 opc_ltu_a6 = OPC_CMP_LTU_A6;
1495 return tcg_opc_a6 (qp, opc_eq_a6, TCG_REG_P6, TCG_REG_P7, arg1, arg2);
1497 return tcg_opc_a6 (qp, opc_eq_a6, TCG_REG_P7, TCG_REG_P6, arg1, arg2);
1499 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P6, TCG_REG_P7, arg1, arg2);
1501 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P6, TCG_REG_P7, arg1, arg2);
1503 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P7, TCG_REG_P6, arg1, arg2);
1505 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P7, TCG_REG_P6, arg1, arg2);
1507 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P7, TCG_REG_P6, arg2, arg1);
1509 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P7, TCG_REG_P6, arg2, arg1);
1511 return tcg_opc_a6 (qp, opc_lt_a6, TCG_REG_P6, TCG_REG_P7, arg2, arg1);
1513 return tcg_opc_a6 (qp, opc_ltu_a6, TCG_REG_P6, TCG_REG_P7, arg2, arg1);
1520 static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
1521 TCGReg arg2, int label_index, int cmp4)
1523 TCGLabel *l = &s->labels[label_index];
1525 tcg_out_bundle(s, miB,
1527 tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4),
1528 tcg_opc_b1(TCG_REG_P6, OPC_BR_DPTK_FEW_B1,
1529 get_reloc_pcrel21b(s->code_ptr + 2)));
1532 reloc_pcrel21b((s->code_ptr - 16) + 2, l->u.value);
1534 tcg_out_reloc(s, (s->code_ptr - 16) + 2,
1535 R_IA64_PCREL21B, label_index, 0);
1539 static inline void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGArg ret,
1540 TCGArg arg1, TCGArg arg2, int cmp4)
1542 tcg_out_bundle(s, MmI,
1543 tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4),
1544 tcg_opc_movi_a(TCG_REG_P6, ret, 1),
1545 tcg_opc_movi_a(TCG_REG_P7, ret, 0));
1548 static inline void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGArg ret,
1549 TCGArg c1, TCGArg c2,
1550 TCGArg v1, int const_v1,
1551 TCGArg v2, int const_v2, int cmp4)
1553 uint64_t opc1, opc2;
1556 opc1 = tcg_opc_movi_a(TCG_REG_P6, ret, v1);
1557 } else if (ret == v1) {
1560 opc1 = tcg_opc_mov_a(TCG_REG_P6, ret, v1);
1563 opc2 = tcg_opc_movi_a(TCG_REG_P7, ret, v2);
1564 } else if (ret == v2) {
1567 opc2 = tcg_opc_mov_a(TCG_REG_P7, ret, v2);
1570 tcg_out_bundle(s, MmI,
1571 tcg_opc_cmp_a(TCG_REG_P0, cond, c1, c2, cmp4),
1576 #if defined(CONFIG_SOFTMMU)
1577 /* We're expecting to use an signed 22-bit immediate add. */
1578 QEMU_BUILD_BUG_ON(offsetof(CPUArchState, tlb_table[NB_MMU_MODES - 1][1])
1581 /* Load and compare a TLB entry, and return the result in (p6, p7).
1582 R2 is loaded with the addend TLB entry.
1583 R57 is loaded with the address, zero extented on 32-bit targets.
1584 R1, R3 are clobbered, leaving R56 free for...
1585 BSWAP_1, BSWAP_2 and I-slot insns for swapping data for store. */
1586 static inline void tcg_out_qemu_tlb(TCGContext *s, TCGReg addr_reg,
1587 TCGMemOp s_bits, int off_rw, int off_add,
1588 uint64_t bswap1, uint64_t bswap2)
1593 extr.u r3 = addr_reg, ... # extract tlb page
1594 zxt4 r57 = addr_reg # or mov for 64-bit guest
1598 shl r3 = r3, cteb # via dep.z
1599 dep r1 = 0, r57, ... # zero page ofs, keep align
1604 ld4 r3 = [r2], off_add-off_rw # or ld8 for 64-bit guest
1609 cmp.eq p6, p7 = r3, r58
1613 tcg_out_bundle(s, miI,
1614 tcg_opc_movi_a(TCG_REG_P0, TCG_REG_R2, off_rw),
1615 tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11, TCG_REG_R3,
1616 addr_reg, TARGET_PAGE_BITS, CPU_TLB_BITS - 1),
1617 tcg_opc_ext_i(TCG_REG_P0,
1618 TARGET_LONG_BITS == 32 ? MO_UL : MO_Q,
1619 TCG_REG_R57, addr_reg));
1620 tcg_out_bundle(s, miI,
1621 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1622 TCG_REG_R2, TCG_AREG0),
1623 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12, TCG_REG_R3,
1624 TCG_REG_R3, 63 - CPU_TLB_ENTRY_BITS,
1625 63 - CPU_TLB_ENTRY_BITS),
1626 tcg_opc_i14(TCG_REG_P0, OPC_DEP_I14, TCG_REG_R1, 0,
1627 TCG_REG_R57, 63 - s_bits,
1628 TARGET_PAGE_BITS - s_bits - 1));
1629 tcg_out_bundle(s, MmI,
1630 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1,
1631 TCG_REG_R2, TCG_REG_R2, TCG_REG_R3),
1632 tcg_opc_m3 (TCG_REG_P0,
1633 (TARGET_LONG_BITS == 32
1634 ? OPC_LD4_M3 : OPC_LD8_M3), TCG_REG_R3,
1635 TCG_REG_R2, off_add - off_rw),
1637 tcg_out_bundle(s, mmI,
1638 tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1, TCG_REG_R2, TCG_REG_R2),
1639 tcg_opc_a6 (TCG_REG_P0, OPC_CMP_EQ_A6, TCG_REG_P6,
1640 TCG_REG_P7, TCG_REG_R1, TCG_REG_R3),
1644 #define TCG_MAX_QEMU_LDST 640
1646 typedef struct TCGLabelQemuLdst {
1649 uint8_t *label_ptr; /* label pointers to be updated */
1652 typedef struct TCGBackendData {
1654 TCGLabelQemuLdst ldst_labels[TCG_MAX_QEMU_LDST];
1657 static inline void tcg_out_tb_init(TCGContext *s)
1659 s->be->nb_ldst_labels = 0;
1662 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc,
1665 TCGBackendData *be = s->be;
1666 TCGLabelQemuLdst *l = &be->ldst_labels[be->nb_ldst_labels++];
1668 assert(be->nb_ldst_labels <= TCG_MAX_QEMU_LDST);
1670 l->size = opc & MO_SIZE;
1671 l->label_ptr = label_ptr;
1674 static void tcg_out_tb_finalize(TCGContext *s)
1676 static const void * const helpers[8] = {
1681 helper_ret_ldub_mmu,
1686 uintptr_t thunks[8] = { };
1687 TCGBackendData *be = s->be;
1688 size_t i, n = be->nb_ldst_labels;
1690 for (i = 0; i < n; i++) {
1691 TCGLabelQemuLdst *l = &be->ldst_labels[i];
1692 long x = l->is_ld * 4 + l->size;
1693 uintptr_t dest = thunks[x];
1695 /* The out-of-line thunks are all the same; load the return address
1696 from B0, load the GP, and branch to the code. Note that we are
1697 always post-call, so the register window has rolled, so we're
1698 using incomming parameter register numbers, not outgoing. */
1700 uintptr_t disp, *desc = (uintptr_t *)helpers[x];
1702 thunks[x] = dest = (uintptr_t)s->code_ptr;
1704 tcg_out_bundle(s, mlx,
1706 tcg_opc_l2 (desc[1]),
1707 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2,
1708 TCG_REG_R1, desc[1]));
1709 tcg_out_bundle(s, mii,
1712 tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
1713 l->is_ld ? TCG_REG_R35 : TCG_REG_R36,
1715 disp = (desc[0] - (uintptr_t)s->code_ptr) >> 4;
1716 tcg_out_bundle(s, mLX,
1719 tcg_opc_x3 (TCG_REG_P0, OPC_BRL_SPTK_MANY_X3, disp));
1722 reloc_pcrel21b(l->label_ptr, dest);
1726 static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1729 static const uint64_t opc_ld_m1[4] = {
1730 OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1
1732 int addr_reg, data_reg, mem_index;
1734 uint64_t fin1, fin2;
1740 s_bits = opc & MO_SIZE;
1742 /* Read the TLB entry */
1743 tcg_out_qemu_tlb(s, addr_reg, s_bits,
1744 offsetof(CPUArchState, tlb_table[mem_index][0].addr_read),
1745 offsetof(CPUArchState, tlb_table[mem_index][0].addend),
1746 INSN_NOP_I, INSN_NOP_I);
1748 /* P6 is the fast path, and P7 the slow path */
1751 if (opc & MO_BSWAP) {
1752 fin1 = tcg_opc_bswap64_i(TCG_REG_P0, data_reg, TCG_REG_R8);
1753 if (s_bits < MO_64) {
1754 int shift = 64 - (8 << s_bits);
1755 fin2 = (opc & MO_SIGN ? OPC_EXTR_I11 : OPC_EXTR_U_I11);
1756 fin2 = tcg_opc_i11(TCG_REG_P0, fin2,
1757 data_reg, data_reg, shift, 63 - shift);
1760 fin1 = tcg_opc_ext_i(TCG_REG_P0, opc, data_reg, TCG_REG_R8);
1763 tcg_out_bundle(s, mmI,
1764 tcg_opc_mov_a(TCG_REG_P7, TCG_REG_R56, TCG_AREG0),
1765 tcg_opc_a1 (TCG_REG_P6, OPC_ADD_A1, TCG_REG_R2,
1766 TCG_REG_R2, TCG_REG_R57),
1767 tcg_opc_movi_a(TCG_REG_P7, TCG_REG_R58, mem_index));
1768 label_ptr = s->code_ptr + 2;
1769 tcg_out_bundle(s, miB,
1770 tcg_opc_m1 (TCG_REG_P6, opc_ld_m1[s_bits],
1771 TCG_REG_R8, TCG_REG_R2),
1773 tcg_opc_b3 (TCG_REG_P7, OPC_BR_CALL_SPNT_FEW_B3, TCG_REG_B0,
1774 get_reloc_pcrel21b(label_ptr)));
1776 add_qemu_ldst_label(s, 1, opc, label_ptr);
1778 /* Note that we always use LE helper functions, so the bswap insns
1779 here for the fast path also apply to the slow path. */
1780 tcg_out_bundle(s, (fin2 ? mII : miI),
1783 fin2 ? fin2 : INSN_NOP_I);
1786 static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1789 static const uint64_t opc_st_m4[4] = {
1790 OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4
1792 TCGReg addr_reg, data_reg;
1794 uint64_t pre1, pre2;
1801 s_bits = opc & MO_SIZE;
1803 /* Note that we always use LE helper functions, so the bswap insns
1804 that are here for the fast path also apply to the slow path,
1805 and move the data into the argument register. */
1807 if (opc & MO_BSWAP) {
1808 pre1 = tcg_opc_bswap64_i(TCG_REG_P0, TCG_REG_R58, data_reg);
1809 if (s_bits < MO_64) {
1810 int shift = 64 - (8 << s_bits);
1811 pre2 = tcg_opc_i11(TCG_REG_P0, OPC_EXTR_U_I11,
1812 TCG_REG_R58, TCG_REG_R58, shift, 63 - shift);
1815 /* Just move the data into place for the slow path. */
1816 pre1 = tcg_opc_ext_i(TCG_REG_P0, opc, TCG_REG_R58, data_reg);
1819 tcg_out_qemu_tlb(s, addr_reg, s_bits,
1820 offsetof(CPUArchState, tlb_table[mem_index][0].addr_write),
1821 offsetof(CPUArchState, tlb_table[mem_index][0].addend),
1824 /* P6 is the fast path, and P7 the slow path */
1825 tcg_out_bundle(s, mmI,
1826 tcg_opc_mov_a(TCG_REG_P7, TCG_REG_R56, TCG_AREG0),
1827 tcg_opc_a1 (TCG_REG_P6, OPC_ADD_A1, TCG_REG_R2,
1828 TCG_REG_R2, TCG_REG_R57),
1829 tcg_opc_movi_a(TCG_REG_P7, TCG_REG_R59, mem_index));
1830 label_ptr = s->code_ptr + 2;
1831 tcg_out_bundle(s, miB,
1832 tcg_opc_m4 (TCG_REG_P6, opc_st_m4[s_bits],
1833 TCG_REG_R58, TCG_REG_R2),
1835 tcg_opc_b3 (TCG_REG_P7, OPC_BR_CALL_SPNT_FEW_B3, TCG_REG_B0,
1836 get_reloc_pcrel21b(label_ptr)));
1838 add_qemu_ldst_label(s, 0, opc, label_ptr);
1841 #else /* !CONFIG_SOFTMMU */
1842 # include "tcg-be-null.h"
1844 static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1847 static uint64_t const opc_ld_m1[4] = {
1848 OPC_LD1_M1, OPC_LD2_M1, OPC_LD4_M1, OPC_LD8_M1
1850 int addr_reg, data_reg;
1851 TCGMemOp s_bits, bswap;
1855 s_bits = opc & MO_SIZE;
1856 bswap = opc & MO_BSWAP;
1858 #if TARGET_LONG_BITS == 32
1859 if (GUEST_BASE != 0) {
1860 tcg_out_bundle(s, mII,
1862 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1863 TCG_REG_R3, addr_reg),
1864 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1865 TCG_GUEST_BASE_REG, TCG_REG_R3));
1867 tcg_out_bundle(s, miI,
1869 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1870 TCG_REG_R2, addr_reg),
1875 if (!(opc & MO_SIGN)) {
1876 tcg_out_bundle(s, miI,
1877 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1878 data_reg, TCG_REG_R2),
1882 tcg_out_bundle(s, mII,
1883 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1884 data_reg, TCG_REG_R2),
1886 tcg_opc_ext_i(TCG_REG_P0, opc, data_reg, data_reg));
1888 } else if (s_bits == MO_64) {
1889 tcg_out_bundle(s, mII,
1890 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1891 data_reg, TCG_REG_R2),
1893 tcg_opc_bswap64_i(TCG_REG_P0, data_reg, data_reg));
1895 if (s_bits == MO_16) {
1896 tcg_out_bundle(s, mII,
1897 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1898 data_reg, TCG_REG_R2),
1900 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1901 data_reg, data_reg, 15, 15));
1903 tcg_out_bundle(s, mII,
1904 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1905 data_reg, TCG_REG_R2),
1907 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1908 data_reg, data_reg, 31, 31));
1910 if (!(opc & MO_SIGN)) {
1911 tcg_out_bundle(s, miI,
1914 tcg_opc_bswap64_i(TCG_REG_P0, data_reg, data_reg));
1916 tcg_out_bundle(s, mII,
1918 tcg_opc_bswap64_i(TCG_REG_P0, data_reg, data_reg),
1919 tcg_opc_ext_i(TCG_REG_P0, opc, data_reg, data_reg));
1923 if (GUEST_BASE != 0) {
1924 tcg_out_bundle(s, MmI,
1925 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1926 TCG_GUEST_BASE_REG, addr_reg),
1927 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1928 data_reg, TCG_REG_R2),
1931 tcg_out_bundle(s, mmI,
1933 tcg_opc_m1 (TCG_REG_P0, opc_ld_m1[s_bits],
1934 data_reg, addr_reg),
1938 if (bswap && s_bits == MO_16) {
1939 tcg_out_bundle(s, mII,
1941 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1942 data_reg, data_reg, 15, 15),
1943 tcg_opc_bswap64_i(TCG_REG_P0, data_reg, data_reg));
1944 } else if (bswap && s_bits == MO_32) {
1945 tcg_out_bundle(s, mII,
1947 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
1948 data_reg, data_reg, 31, 31),
1949 tcg_opc_bswap64_i(TCG_REG_P0, data_reg, data_reg));
1950 } else if (bswap && s_bits == MO_64) {
1951 tcg_out_bundle(s, miI,
1954 tcg_opc_bswap64_i(TCG_REG_P0, data_reg, data_reg));
1956 if (opc & MO_SIGN) {
1957 tcg_out_bundle(s, miI,
1960 tcg_opc_ext_i(TCG_REG_P0, opc, data_reg, data_reg));
1965 static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1968 static uint64_t const opc_st_m4[4] = {
1969 OPC_ST1_M4, OPC_ST2_M4, OPC_ST4_M4, OPC_ST8_M4
1971 int addr_reg, data_reg;
1972 #if TARGET_LONG_BITS == 64
1973 uint64_t add_guest_base;
1975 TCGMemOp s_bits, bswap;
1979 s_bits = opc & MO_SIZE;
1980 bswap = opc & MO_BSWAP;
1982 #if TARGET_LONG_BITS == 32
1983 if (GUEST_BASE != 0) {
1984 tcg_out_bundle(s, mII,
1986 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1987 TCG_REG_R3, addr_reg),
1988 tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
1989 TCG_GUEST_BASE_REG, TCG_REG_R3));
1991 tcg_out_bundle(s, miI,
1993 tcg_opc_i29(TCG_REG_P0, OPC_ZXT4_I29,
1994 TCG_REG_R2, addr_reg),
1999 if (s_bits == MO_16) {
2000 tcg_out_bundle(s, mII,
2002 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
2003 TCG_REG_R3, data_reg, 15, 15),
2004 tcg_opc_bswap64_i(TCG_REG_P0,
2005 TCG_REG_R3, TCG_REG_R3));
2006 data_reg = TCG_REG_R3;
2007 } else if (s_bits == MO_32) {
2008 tcg_out_bundle(s, mII,
2010 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
2011 TCG_REG_R3, data_reg, 31, 31),
2012 tcg_opc_bswap64_i(TCG_REG_P0,
2013 TCG_REG_R3, TCG_REG_R3));
2014 data_reg = TCG_REG_R3;
2015 } else if (s_bits == MO_64) {
2016 tcg_out_bundle(s, miI,
2019 tcg_opc_bswap64_i(TCG_REG_P0, TCG_REG_R3, data_reg));
2020 data_reg = TCG_REG_R3;
2023 tcg_out_bundle(s, mmI,
2024 tcg_opc_m4 (TCG_REG_P0, opc_st_m4[s_bits],
2025 data_reg, TCG_REG_R2),
2029 if (GUEST_BASE != 0) {
2030 add_guest_base = tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
2031 TCG_GUEST_BASE_REG, addr_reg);
2032 addr_reg = TCG_REG_R2;
2034 add_guest_base = INSN_NOP_M;
2038 tcg_out_bundle(s, (GUEST_BASE ? MmI : mmI),
2040 tcg_opc_m4 (TCG_REG_P0, opc_st_m4[s_bits],
2041 data_reg, addr_reg),
2044 if (s_bits == MO_16) {
2045 tcg_out_bundle(s, mII,
2047 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
2048 TCG_REG_R3, data_reg, 15, 15),
2049 tcg_opc_bswap64_i(TCG_REG_P0,
2050 TCG_REG_R3, TCG_REG_R3));
2051 data_reg = TCG_REG_R3;
2052 } else if (s_bits == MO_32) {
2053 tcg_out_bundle(s, mII,
2055 tcg_opc_i12(TCG_REG_P0, OPC_DEP_Z_I12,
2056 TCG_REG_R3, data_reg, 31, 31),
2057 tcg_opc_bswap64_i(TCG_REG_P0,
2058 TCG_REG_R3, TCG_REG_R3));
2059 data_reg = TCG_REG_R3;
2060 } else if (s_bits == MO_64) {
2061 tcg_out_bundle(s, miI,
2064 tcg_opc_bswap64_i(TCG_REG_P0, TCG_REG_R3, data_reg));
2065 data_reg = TCG_REG_R3;
2067 tcg_out_bundle(s, miI,
2068 tcg_opc_m4 (TCG_REG_P0, opc_st_m4[s_bits],
2069 data_reg, addr_reg),
2078 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
2079 const TCGArg *args, const int *const_args)
2082 case INDEX_op_exit_tb:
2083 tcg_out_exit_tb(s, args[0]);
2086 tcg_out_br(s, args[0]);
2089 if (likely(const_args[0])) {
2090 tcg_out_calli(s, args[0]);
2092 tcg_out_callr(s, args[0]);
2095 case INDEX_op_goto_tb:
2096 tcg_out_goto_tb(s, args[0]);
2099 case INDEX_op_movi_i32:
2100 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
2102 case INDEX_op_movi_i64:
2103 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
2106 case INDEX_op_ld8u_i32:
2107 case INDEX_op_ld8u_i64:
2108 tcg_out_ld_rel(s, OPC_LD1_M1, args[0], args[1], args[2]);
2110 case INDEX_op_ld8s_i32:
2111 case INDEX_op_ld8s_i64:
2112 tcg_out_ld_rel(s, OPC_LD1_M1, args[0], args[1], args[2]);
2113 tcg_out_ext(s, OPC_SXT1_I29, args[0], args[0]);
2115 case INDEX_op_ld16u_i32:
2116 case INDEX_op_ld16u_i64:
2117 tcg_out_ld_rel(s, OPC_LD2_M1, args[0], args[1], args[2]);
2119 case INDEX_op_ld16s_i32:
2120 case INDEX_op_ld16s_i64:
2121 tcg_out_ld_rel(s, OPC_LD2_M1, args[0], args[1], args[2]);
2122 tcg_out_ext(s, OPC_SXT2_I29, args[0], args[0]);
2124 case INDEX_op_ld_i32:
2125 case INDEX_op_ld32u_i64:
2126 tcg_out_ld_rel(s, OPC_LD4_M1, args[0], args[1], args[2]);
2128 case INDEX_op_ld32s_i64:
2129 tcg_out_ld_rel(s, OPC_LD4_M1, args[0], args[1], args[2]);
2130 tcg_out_ext(s, OPC_SXT4_I29, args[0], args[0]);
2132 case INDEX_op_ld_i64:
2133 tcg_out_ld_rel(s, OPC_LD8_M1, args[0], args[1], args[2]);
2135 case INDEX_op_st8_i32:
2136 case INDEX_op_st8_i64:
2137 tcg_out_st_rel(s, OPC_ST1_M4, args[0], args[1], args[2]);
2139 case INDEX_op_st16_i32:
2140 case INDEX_op_st16_i64:
2141 tcg_out_st_rel(s, OPC_ST2_M4, args[0], args[1], args[2]);
2143 case INDEX_op_st_i32:
2144 case INDEX_op_st32_i64:
2145 tcg_out_st_rel(s, OPC_ST4_M4, args[0], args[1], args[2]);
2147 case INDEX_op_st_i64:
2148 tcg_out_st_rel(s, OPC_ST8_M4, args[0], args[1], args[2]);
2151 case INDEX_op_add_i32:
2152 case INDEX_op_add_i64:
2153 tcg_out_add(s, args[0], args[1], args[2], const_args[2]);
2155 case INDEX_op_sub_i32:
2156 case INDEX_op_sub_i64:
2157 tcg_out_sub(s, args[0], args[1], const_args[1], args[2], const_args[2]);
2160 case INDEX_op_and_i32:
2161 case INDEX_op_and_i64:
2162 /* TCG expects arg2 constant; A3 expects arg1 constant. Swap. */
2163 tcg_out_alu(s, OPC_AND_A1, OPC_AND_A3, args[0],
2164 args[2], const_args[2], args[1], const_args[1]);
2166 case INDEX_op_andc_i32:
2167 case INDEX_op_andc_i64:
2168 tcg_out_alu(s, OPC_ANDCM_A1, OPC_ANDCM_A3, args[0],
2169 args[1], const_args[1], args[2], const_args[2]);
2171 case INDEX_op_eqv_i32:
2172 case INDEX_op_eqv_i64:
2173 tcg_out_eqv(s, args[0], args[1], const_args[1],
2174 args[2], const_args[2]);
2176 case INDEX_op_nand_i32:
2177 case INDEX_op_nand_i64:
2178 tcg_out_nand(s, args[0], args[1], const_args[1],
2179 args[2], const_args[2]);
2181 case INDEX_op_nor_i32:
2182 case INDEX_op_nor_i64:
2183 tcg_out_nor(s, args[0], args[1], const_args[1],
2184 args[2], const_args[2]);
2186 case INDEX_op_or_i32:
2187 case INDEX_op_or_i64:
2188 /* TCG expects arg2 constant; A3 expects arg1 constant. Swap. */
2189 tcg_out_alu(s, OPC_OR_A1, OPC_OR_A3, args[0],
2190 args[2], const_args[2], args[1], const_args[1]);
2192 case INDEX_op_orc_i32:
2193 case INDEX_op_orc_i64:
2194 tcg_out_orc(s, args[0], args[1], const_args[1],
2195 args[2], const_args[2]);
2197 case INDEX_op_xor_i32:
2198 case INDEX_op_xor_i64:
2199 /* TCG expects arg2 constant; A3 expects arg1 constant. Swap. */
2200 tcg_out_alu(s, OPC_XOR_A1, OPC_XOR_A3, args[0],
2201 args[2], const_args[2], args[1], const_args[1]);
2204 case INDEX_op_mul_i32:
2205 case INDEX_op_mul_i64:
2206 tcg_out_mul(s, args[0], args[1], args[2]);
2209 case INDEX_op_sar_i32:
2210 tcg_out_sar_i32(s, args[0], args[1], args[2], const_args[2]);
2212 case INDEX_op_sar_i64:
2213 tcg_out_sar_i64(s, args[0], args[1], args[2], const_args[2]);
2215 case INDEX_op_shl_i32:
2216 tcg_out_shl_i32(s, args[0], args[1], args[2], const_args[2]);
2218 case INDEX_op_shl_i64:
2219 tcg_out_shl_i64(s, args[0], args[1], args[2], const_args[2]);
2221 case INDEX_op_shr_i32:
2222 tcg_out_shr_i32(s, args[0], args[1], args[2], const_args[2]);
2224 case INDEX_op_shr_i64:
2225 tcg_out_shr_i64(s, args[0], args[1], args[2], const_args[2]);
2227 case INDEX_op_rotl_i32:
2228 tcg_out_rotl_i32(s, args[0], args[1], args[2], const_args[2]);
2230 case INDEX_op_rotl_i64:
2231 tcg_out_rotl_i64(s, args[0], args[1], args[2], const_args[2]);
2233 case INDEX_op_rotr_i32:
2234 tcg_out_rotr_i32(s, args[0], args[1], args[2], const_args[2]);
2236 case INDEX_op_rotr_i64:
2237 tcg_out_rotr_i64(s, args[0], args[1], args[2], const_args[2]);
2240 case INDEX_op_ext8s_i32:
2241 case INDEX_op_ext8s_i64:
2242 tcg_out_ext(s, OPC_SXT1_I29, args[0], args[1]);
2244 case INDEX_op_ext8u_i32:
2245 case INDEX_op_ext8u_i64:
2246 tcg_out_ext(s, OPC_ZXT1_I29, args[0], args[1]);
2248 case INDEX_op_ext16s_i32:
2249 case INDEX_op_ext16s_i64:
2250 tcg_out_ext(s, OPC_SXT2_I29, args[0], args[1]);
2252 case INDEX_op_ext16u_i32:
2253 case INDEX_op_ext16u_i64:
2254 tcg_out_ext(s, OPC_ZXT2_I29, args[0], args[1]);
2256 case INDEX_op_ext32s_i64:
2257 tcg_out_ext(s, OPC_SXT4_I29, args[0], args[1]);
2259 case INDEX_op_ext32u_i64:
2260 tcg_out_ext(s, OPC_ZXT4_I29, args[0], args[1]);
2263 case INDEX_op_bswap16_i32:
2264 case INDEX_op_bswap16_i64:
2265 tcg_out_bswap16(s, args[0], args[1]);
2267 case INDEX_op_bswap32_i32:
2268 case INDEX_op_bswap32_i64:
2269 tcg_out_bswap32(s, args[0], args[1]);
2271 case INDEX_op_bswap64_i64:
2272 tcg_out_bswap64(s, args[0], args[1]);
2275 case INDEX_op_deposit_i32:
2276 case INDEX_op_deposit_i64:
2277 tcg_out_deposit(s, args[0], args[1], args[2], const_args[2],
2281 case INDEX_op_brcond_i32:
2282 tcg_out_brcond(s, args[2], args[0], args[1], args[3], 1);
2284 case INDEX_op_brcond_i64:
2285 tcg_out_brcond(s, args[2], args[0], args[1], args[3], 0);
2287 case INDEX_op_setcond_i32:
2288 tcg_out_setcond(s, args[3], args[0], args[1], args[2], 1);
2290 case INDEX_op_setcond_i64:
2291 tcg_out_setcond(s, args[3], args[0], args[1], args[2], 0);
2293 case INDEX_op_movcond_i32:
2294 tcg_out_movcond(s, args[5], args[0], args[1], args[2],
2295 args[3], const_args[3], args[4], const_args[4], 1);
2297 case INDEX_op_movcond_i64:
2298 tcg_out_movcond(s, args[5], args[0], args[1], args[2],
2299 args[3], const_args[3], args[4], const_args[4], 0);
2302 case INDEX_op_qemu_ld8u:
2303 tcg_out_qemu_ld(s, args, MO_UB);
2305 case INDEX_op_qemu_ld8s:
2306 tcg_out_qemu_ld(s, args, MO_SB);
2308 case INDEX_op_qemu_ld16u:
2309 tcg_out_qemu_ld(s, args, MO_TEUW);
2311 case INDEX_op_qemu_ld16s:
2312 tcg_out_qemu_ld(s, args, MO_TESW);
2314 case INDEX_op_qemu_ld32:
2315 case INDEX_op_qemu_ld32u:
2316 tcg_out_qemu_ld(s, args, MO_TEUL);
2318 case INDEX_op_qemu_ld32s:
2319 tcg_out_qemu_ld(s, args, MO_TESL);
2321 case INDEX_op_qemu_ld64:
2322 tcg_out_qemu_ld(s, args, MO_TEQ);
2325 case INDEX_op_qemu_st8:
2326 tcg_out_qemu_st(s, args, MO_UB);
2328 case INDEX_op_qemu_st16:
2329 tcg_out_qemu_st(s, args, MO_TEUW);
2331 case INDEX_op_qemu_st32:
2332 tcg_out_qemu_st(s, args, MO_TEUL);
2334 case INDEX_op_qemu_st64:
2335 tcg_out_qemu_st(s, args, MO_TEQ);
2343 static const TCGTargetOpDef ia64_op_defs[] = {
2344 { INDEX_op_br, { } },
2345 { INDEX_op_call, { "ri" } },
2346 { INDEX_op_exit_tb, { } },
2347 { INDEX_op_goto_tb, { } },
2349 { INDEX_op_mov_i32, { "r", "r" } },
2350 { INDEX_op_movi_i32, { "r" } },
2352 { INDEX_op_ld8u_i32, { "r", "r" } },
2353 { INDEX_op_ld8s_i32, { "r", "r" } },
2354 { INDEX_op_ld16u_i32, { "r", "r" } },
2355 { INDEX_op_ld16s_i32, { "r", "r" } },
2356 { INDEX_op_ld_i32, { "r", "r" } },
2357 { INDEX_op_st8_i32, { "rZ", "r" } },
2358 { INDEX_op_st16_i32, { "rZ", "r" } },
2359 { INDEX_op_st_i32, { "rZ", "r" } },
2361 { INDEX_op_add_i32, { "r", "rZ", "rI" } },
2362 { INDEX_op_sub_i32, { "r", "rI", "rI" } },
2364 { INDEX_op_and_i32, { "r", "rI", "rI" } },
2365 { INDEX_op_andc_i32, { "r", "rI", "rI" } },
2366 { INDEX_op_eqv_i32, { "r", "rZ", "rZ" } },
2367 { INDEX_op_nand_i32, { "r", "rZ", "rZ" } },
2368 { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
2369 { INDEX_op_or_i32, { "r", "rI", "rI" } },
2370 { INDEX_op_orc_i32, { "r", "rZ", "rZ" } },
2371 { INDEX_op_xor_i32, { "r", "rI", "rI" } },
2373 { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
2375 { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
2376 { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
2377 { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
2378 { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
2379 { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
2381 { INDEX_op_ext8s_i32, { "r", "rZ"} },
2382 { INDEX_op_ext8u_i32, { "r", "rZ"} },
2383 { INDEX_op_ext16s_i32, { "r", "rZ"} },
2384 { INDEX_op_ext16u_i32, { "r", "rZ"} },
2386 { INDEX_op_bswap16_i32, { "r", "rZ" } },
2387 { INDEX_op_bswap32_i32, { "r", "rZ" } },
2389 { INDEX_op_brcond_i32, { "rZ", "rZ" } },
2390 { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
2391 { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rI", "rI" } },
2393 { INDEX_op_mov_i64, { "r", "r" } },
2394 { INDEX_op_movi_i64, { "r" } },
2396 { INDEX_op_ld8u_i64, { "r", "r" } },
2397 { INDEX_op_ld8s_i64, { "r", "r" } },
2398 { INDEX_op_ld16u_i64, { "r", "r" } },
2399 { INDEX_op_ld16s_i64, { "r", "r" } },
2400 { INDEX_op_ld32u_i64, { "r", "r" } },
2401 { INDEX_op_ld32s_i64, { "r", "r" } },
2402 { INDEX_op_ld_i64, { "r", "r" } },
2403 { INDEX_op_st8_i64, { "rZ", "r" } },
2404 { INDEX_op_st16_i64, { "rZ", "r" } },
2405 { INDEX_op_st32_i64, { "rZ", "r" } },
2406 { INDEX_op_st_i64, { "rZ", "r" } },
2408 { INDEX_op_add_i64, { "r", "rZ", "rI" } },
2409 { INDEX_op_sub_i64, { "r", "rI", "rI" } },
2411 { INDEX_op_and_i64, { "r", "rI", "rI" } },
2412 { INDEX_op_andc_i64, { "r", "rI", "rI" } },
2413 { INDEX_op_eqv_i64, { "r", "rZ", "rZ" } },
2414 { INDEX_op_nand_i64, { "r", "rZ", "rZ" } },
2415 { INDEX_op_nor_i64, { "r", "rZ", "rZ" } },
2416 { INDEX_op_or_i64, { "r", "rI", "rI" } },
2417 { INDEX_op_orc_i64, { "r", "rZ", "rZ" } },
2418 { INDEX_op_xor_i64, { "r", "rI", "rI" } },
2420 { INDEX_op_mul_i64, { "r", "rZ", "rZ" } },
2422 { INDEX_op_sar_i64, { "r", "rZ", "ri" } },
2423 { INDEX_op_shl_i64, { "r", "rZ", "ri" } },
2424 { INDEX_op_shr_i64, { "r", "rZ", "ri" } },
2425 { INDEX_op_rotl_i64, { "r", "rZ", "ri" } },
2426 { INDEX_op_rotr_i64, { "r", "rZ", "ri" } },
2428 { INDEX_op_ext8s_i64, { "r", "rZ"} },
2429 { INDEX_op_ext8u_i64, { "r", "rZ"} },
2430 { INDEX_op_ext16s_i64, { "r", "rZ"} },
2431 { INDEX_op_ext16u_i64, { "r", "rZ"} },
2432 { INDEX_op_ext32s_i64, { "r", "rZ"} },
2433 { INDEX_op_ext32u_i64, { "r", "rZ"} },
2435 { INDEX_op_bswap16_i64, { "r", "rZ" } },
2436 { INDEX_op_bswap32_i64, { "r", "rZ" } },
2437 { INDEX_op_bswap64_i64, { "r", "rZ" } },
2439 { INDEX_op_brcond_i64, { "rZ", "rZ" } },
2440 { INDEX_op_setcond_i64, { "r", "rZ", "rZ" } },
2441 { INDEX_op_movcond_i64, { "r", "rZ", "rZ", "rI", "rI" } },
2443 { INDEX_op_deposit_i32, { "r", "rZ", "ri" } },
2444 { INDEX_op_deposit_i64, { "r", "rZ", "ri" } },
2446 { INDEX_op_qemu_ld8u, { "r", "r" } },
2447 { INDEX_op_qemu_ld8s, { "r", "r" } },
2448 { INDEX_op_qemu_ld16u, { "r", "r" } },
2449 { INDEX_op_qemu_ld16s, { "r", "r" } },
2450 { INDEX_op_qemu_ld32, { "r", "r" } },
2451 { INDEX_op_qemu_ld32u, { "r", "r" } },
2452 { INDEX_op_qemu_ld32s, { "r", "r" } },
2453 { INDEX_op_qemu_ld64, { "r", "r" } },
2455 { INDEX_op_qemu_st8, { "SZ", "r" } },
2456 { INDEX_op_qemu_st16, { "SZ", "r" } },
2457 { INDEX_op_qemu_st32, { "SZ", "r" } },
2458 { INDEX_op_qemu_st64, { "SZ", "r" } },
2463 /* Generate global QEMU prologue and epilogue code */
2464 static void tcg_target_qemu_prologue(TCGContext *s)
2468 /* reserve some stack space */
2469 frame_size = TCG_STATIC_CALL_ARGS_SIZE +
2470 CPU_TEMP_BUF_NLONGS * sizeof(long);
2471 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
2472 ~(TCG_TARGET_STACK_ALIGN - 1);
2473 tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2474 CPU_TEMP_BUF_NLONGS * sizeof(long));
2476 /* First emit adhoc function descriptor */
2477 *(uint64_t *)(s->code_ptr) = (uint64_t)s->code_ptr + 16; /* entry point */
2478 s->code_ptr += 16; /* skip GP */
2481 tcg_out_bundle(s, miI,
2482 tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34,
2483 TCG_REG_R34, 32, 24, 0),
2485 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
2486 TCG_REG_B6, TCG_REG_R33, 0));
2488 /* ??? If GUEST_BASE < 0x200000, we could load the register via
2489 an ADDL in the M slot of the next bundle. */
2490 if (GUEST_BASE != 0) {
2491 tcg_out_bundle(s, mlx,
2493 tcg_opc_l2 (GUEST_BASE),
2494 tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2,
2495 TCG_GUEST_BASE_REG, GUEST_BASE));
2496 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2499 tcg_out_bundle(s, miB,
2500 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
2501 TCG_REG_R12, -frame_size, TCG_REG_R12),
2502 tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
2503 TCG_REG_R33, TCG_REG_B0),
2504 tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
2507 tb_ret_addr = s->code_ptr;
2508 tcg_out_bundle(s, miI,
2510 tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
2511 TCG_REG_B0, TCG_REG_R33, 0),
2512 tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
2513 TCG_REG_R12, frame_size, TCG_REG_R12));
2514 tcg_out_bundle(s, miB,
2516 tcg_opc_i26(TCG_REG_P0, OPC_MOV_I_I26,
2517 TCG_REG_PFS, TCG_REG_R34),
2518 tcg_opc_b4 (TCG_REG_P0, OPC_BR_RET_SPTK_MANY_B4,
2522 static void tcg_target_init(TCGContext *s)
2524 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32],
2525 0xffffffffffffffffull);
2526 tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64],
2527 0xffffffffffffffffull);
2529 tcg_regset_clear(tcg_target_call_clobber_regs);
2530 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2531 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2532 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2533 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2534 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2535 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R15);
2536 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R16);
2537 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R17);
2538 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R18);
2539 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R19);
2540 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R20);
2541 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R21);
2542 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R22);
2543 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R23);
2544 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R24);
2545 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R25);
2546 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R26);
2547 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R27);
2548 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R28);
2549 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R29);
2550 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R30);
2551 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R31);
2552 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R56);
2553 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R57);
2554 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R58);
2555 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R59);
2556 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R60);
2557 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R61);
2558 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R62);
2559 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R63);
2561 tcg_regset_clear(s->reserved_regs);
2562 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* zero register */
2563 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* global pointer */
2564 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* internal use */
2565 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3); /* internal use */
2566 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12); /* stack pointer */
2567 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
2568 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R33); /* return address */
2569 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R34); /* PFS */
2571 /* The following 4 are not in use, are call-saved, but *not* saved
2572 by the prologue. Therefore we cannot use them without modifying
2573 the prologue. There doesn't seem to be any good reason to use
2574 these as opposed to the windowed registers. */
2575 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R4);
2576 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R5);
2577 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
2578 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R7);
2580 tcg_add_target_add_op_defs(ia64_op_defs);