@samitouri / QOSamiQemu / commits / 586663f1fa

buildsys: Remove MIPS TCG backend

We removed support for MIPS host. Remove the now unreachable TCG host code. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20260511135312.38705-6-philmd@linaro.org>

Philippe Mathieu-Daudé committed May 11, 2026 at 11:19 UTC 586663f1fa29e5ba009a5e35df305bdecb60a138
12 files changed +2 -3013
MAINTAINERS
-9
@@ -4148,15 +4148,6 @@ M: WANG Xuerui <git@xen0n.name>
4148 S: Maintained
4149 F: tcg/loongarch64/
4150
4151 -MIPS TCG target
4152 -M: Philippe Mathieu-Daudé <philmd@linaro.org>
4153 -R: Aurelien Jarno <aurelien@aurel32.net>
4154 -R: Huacai Chen <chenhuacai@kernel.org>
4155 -R: Jiaxun Yang <jiaxun.yang@flygoat.com>
4156 -R: Aleksandar Rikalo <arikalo@gmail.com>
4157 -S: Odd Fixes
4158 -F: tcg/mips64/
4159 -
4151 PPC TCG target
4152 M: Richard Henderson <richard.henderson@linaro.org>
4153 S: Odd Fixes
common-user/host/mips64/safe-syscall.inc.S deleted
-114
@@ -1,114 +0,0 @@
1 -/*
2 - * safe-syscall.inc.S : host-specific assembly fragment
3 - * to handle signals occurring at the same time as system calls.
4 - * This is intended to be included by common-user/safe-syscall.S
5 - *
6 - * Written by Richard Henderson <richard.henderson@linaro.org>
7 - * Copyright (C) 2021 Linaro, Inc.
8 - *
9 - * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 - * See the COPYING file in the top-level directory.
11 - */
12 -
13 -#include "sys/regdef.h"
14 -#include "sys/asm.h"
15 -
16 - .text
17 - .set nomips16
18 - .set reorder
19 -
20 - .global safe_syscall_start
21 - .global safe_syscall_end
22 - .type safe_syscall_start, @function
23 - .type safe_syscall_end, @function
24 -
25 - /*
26 - * This is the entry point for making a system call. The calling
27 - * convention here is that of a C varargs function with the
28 - * first argument an 'int *' to the signal_pending flag, the
29 - * second one the system call number (as a 'long'), and all further
30 - * arguments being syscall arguments (also 'long').
31 - */
32 -
33 -/* 1 * 8 for s0 save; 1 * 8 for align. */
34 -#define FRAME 16
35 -#define OFS_S0 0
36 -
37 -
38 -NESTED(safe_syscall_base, FRAME, ra)
39 - .cfi_startproc
40 - PTR_ADDIU sp, sp, -FRAME
41 - .cfi_adjust_cfa_offset FRAME
42 - REG_S s0, OFS_S0(sp)
43 - .cfi_rel_offset s0, OFS_S0
44 - /*
45 - * The syscall calling convention is nearly the same as C:
46 - * we enter with a0 == &signal_pending
47 - * a1 == syscall number
48 - * a2 ... a7 == syscall arguments
49 - * and return the result in a0
50 - * and the syscall instruction needs
51 - * v0 == syscall number
52 - * a0 ... a5 == syscall arguments
53 - * and returns the result in v0
54 - * Shuffle everything around appropriately.
55 - */
56 - move s0, a0 /* signal_pending pointer */
57 - move v0, a1 /* syscall number */
58 - move a0, a2 /* syscall arguments */
59 - move a1, a3
60 - move a2, a4
61 - move a3, a5
62 - move a4, a6
63 - move a5, a7
64 -
65 - /*
66 - * This next sequence of code works in conjunction with the
67 - * rewind_if_safe_syscall_function(). If a signal is taken
68 - * and the interrupted PC is anywhere between 'safe_syscall_start'
69 - * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
70 - * The code sequence must therefore be able to cope with this, and
71 - * the syscall instruction must be the final one in the sequence.
72 - */
73 -safe_syscall_start:
74 - /* If signal_pending is non-zero, don't do the call */
75 - lw t1, 0(s0)
76 - bnez t1, 2f
77 - syscall
78 -safe_syscall_end:
79 -
80 - /* code path for having successfully executed the syscall */
81 - REG_L s0, OFS_S0(sp)
82 - PTR_ADDIU sp, sp, FRAME
83 - .cfi_remember_state
84 - .cfi_adjust_cfa_offset -FRAME
85 - .cfi_restore s0
86 - bnez a3, 1f
87 - jr ra
88 - .cfi_restore_state
89 -
90 - /* code path when we didn't execute the syscall */
91 -2: REG_L s0, OFS_S0(sp)
92 - PTR_ADDIU sp, sp, FRAME
93 - .cfi_adjust_cfa_offset -FRAME
94 - .cfi_restore s0
95 - li v0, QEMU_ERESTARTSYS
96 -
97 - /* code path setting errno */
98 - /*
99 - * We didn't setup GP on entry, optimistic of the syscall success.
100 - * We must do so now to load the address of the helper, as required
101 - * by the ABI, into t9.
102 - *
103 - * Note that SETUP_GPX and SETUP_GPX64 are themselves conditional,
104 - * so we can simply let the one that's not empty succeed.
105 - */
106 -1: USE_ALT_CP(t0)
107 - SETUP_GPX(t1)
108 - SETUP_GPX64(t0, t1)
109 - move a0, v0
110 - PTR_LA t9, safe_syscall_set_errno_tail
111 - jr t9
112 -
113 - .cfi_endproc
114 -END(safe_syscall_base)
include/user/thunk.h
+1 -1
@@ -115,7 +115,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
115 if (is_host) {
116 #if defined(HOST_X86_64)
117 return 8;
118 -#elif defined(HOST_MIPS) || defined(HOST_SPARC64)
118 +#elif defined(HOST_SPARC64)
119 return 4;
120 #elif defined(HOST_PPC)
121 return sizeof(void *);
linux-user/include/host/mips64/host-signal.h deleted
-75
@@ -1,75 +0,0 @@
1 -/*
2 - * host-signal.h: signal info dependent on the host architecture
3 - *
4 - * Copyright (c) 2003-2005 Fabrice Bellard
5 - * Copyright (c) 2021 Linaro Limited
6 - *
7 - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
8 - * See the COPYING file in the top-level directory.
9 - */
10 -
11 -#ifndef MIPS_HOST_SIGNAL_H
12 -#define MIPS_HOST_SIGNAL_H
13 -
14 -/* The third argument to a SA_SIGINFO handler is ucontext_t. */
15 -typedef ucontext_t host_sigcontext;
16 -
17 -static inline uintptr_t host_signal_pc(host_sigcontext *uc)
18 -{
19 - return uc->uc_mcontext.pc;
20 -}
21 -
22 -static inline void host_signal_set_pc(host_sigcontext *uc, uintptr_t pc)
23 -{
24 - uc->uc_mcontext.pc = pc;
25 -}
26 -
27 -static inline void *host_signal_mask(host_sigcontext *uc)
28 -{
29 - return &uc->uc_sigmask;
30 -}
31 -
32 -#if defined(__misp16) || defined(__mips_micromips)
33 -#error "Unsupported encoding"
34 -#endif
35 -
36 -static inline bool host_signal_write(siginfo_t *info, host_sigcontext *uc)
37 -{
38 - uint32_t insn = *(uint32_t *)host_signal_pc(uc);
39 -
40 - /* Detect all store instructions at program counter. */
41 - switch ((insn >> 26) & 077) {
42 - case 050: /* SB */
43 - case 051: /* SH */
44 - case 052: /* SWL */
45 - case 053: /* SW */
46 - case 054: /* SDL */
47 - case 055: /* SDR */
48 - case 056: /* SWR */
49 - case 070: /* SC */
50 - case 071: /* SWC1 */
51 - case 074: /* SCD */
52 - case 075: /* SDC1 */
53 - case 077: /* SD */
54 -#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
55 - case 072: /* SWC2 */
56 - case 076: /* SDC2 */
57 -#endif
58 - return true;
59 - case 023: /* COP1X */
60 - /*
61 - * Required in all versions of MIPS64 since
62 - * MIPS64r1 and subsequent versions of MIPS32r2.
63 - */
64 - switch (insn & 077) {
65 - case 010: /* SWXC1 */
66 - case 011: /* SDXC1 */
67 - case 015: /* SUXC1 */
68 - return true;
69 - }
70 - break;
71 - }
72 - return false;
73 -}
74 -
75 -#endif
linux-user/mmap.c
+1 -1
@@ -1351,7 +1351,7 @@ static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
1351 }
1352 #endif
1353
1354 -#if defined(__mips__) || defined(__sparc__)
1354 +#if defined(__sparc__)
1355 #define HOST_FORCE_SHMLBA 1
1356 #else
1357 #define HOST_FORCE_SHMLBA 0
tcg/mips64/tcg-target-con-set.h deleted
-30
@@ -1,30 +0,0 @@
1 -/* SPDX-License-Identifier: MIT */
2 -/*
3 - * Define MIPS target-specific constraint sets.
4 - * Copyright (c) 2021 Linaro
5 - */
6 -
7 -/*
8 - * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
9 - * Each operand should be a sequence of constraint letters as defined by
10 - * tcg-target-con-str.h; the constraint combination is inclusive or.
11 - */
12 -C_O0_I1(r)
13 -C_O0_I2(r, rz)
14 -C_O0_I2(rz, r)
15 -C_O0_I3(rz, rz, r)
16 -C_O0_I4(r, r, rz, rz)
17 -C_O1_I1(r, r)
18 -C_O1_I2(r, 0, rz)
19 -C_O1_I2(r, r, r)
20 -C_O1_I2(r, r, ri)
21 -C_O1_I2(r, r, rI)
22 -C_O1_I2(r, r, rIK)
23 -C_O1_I2(r, r, rJ)
24 -C_O1_I2(r, r, rz)
25 -C_O1_I2(r, r, rzW)
26 -C_O1_I4(r, r, rz, rz, 0)
27 -C_O1_I4(r, r, rz, rz, rz)
28 -C_O1_I4(r, r, r, rz, rz)
29 -C_O2_I1(r, r, r)
30 -C_O2_I2(r, r, r, r)
tcg/mips64/tcg-target-con-str.h deleted
-20
@@ -1,20 +0,0 @@
1 -/* SPDX-License-Identifier: MIT */
2 -/*
3 - * Define MIPS target-specific operand constraints.
4 - * Copyright (c) 2021 Linaro
5 - */
6 -
7 -/*
8 - * Define constraint letters for register sets:
9 - * REGS(letter, register_mask)
10 - */
11 -REGS('r', ALL_GENERAL_REGS)
12 -
13 -/*
14 - * Define constraint letters for constants:
15 - * CONST(letter, TCG_CT_CONST_* bit set)
16 - */
17 -CONST('I', TCG_CT_CONST_U16)
18 -CONST('J', TCG_CT_CONST_S16)
19 -CONST('K', TCG_CT_CONST_P2M1)
20 -CONST('W', TCG_CT_CONST_WSZ)
tcg/mips64/tcg-target-has.h deleted
-69
@@ -1,69 +0,0 @@
1 -/* SPDX-License-Identifier: MIT */
2 -/*
3 - * Define target-specific opcode support
4 - * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5 - * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6 - */
7 -
8 -#ifndef TCG_TARGET_HAS_H
9 -#define TCG_TARGET_HAS_H
10 -
11 -/* MOVN/MOVZ instructions detection */
12 -#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
13 - defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
14 - defined(_MIPS_ARCH_MIPS4)
15 -#define use_movnz_instructions 1
16 -#else
17 -extern bool use_movnz_instructions;
18 -#endif
19 -
20 -/* MIPS32 instruction set detection */
21 -#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
22 -#define use_mips32_instructions 1
23 -#else
24 -extern bool use_mips32_instructions;
25 -#endif
26 -
27 -/* MIPS32R2 instruction set detection */
28 -#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
29 -#define use_mips32r2_instructions 1
30 -#else
31 -extern bool use_mips32r2_instructions;
32 -#endif
33 -
34 -/* MIPS32R6 instruction set detection */
35 -#if defined(__mips_isa_rev) && (__mips_isa_rev >= 6)
36 -#define use_mips32r6_instructions 1
37 -#else
38 -#define use_mips32r6_instructions 0
39 -#endif
40 -
41 -/* optional instructions */
42 -#define TCG_TARGET_HAS_extr_i64_i32 1
43 -#define TCG_TARGET_HAS_ext32s_i64 1
44 -#define TCG_TARGET_HAS_ext32u_i64 1
45 -
46 -/* optional instructions detected at runtime */
47 -#define TCG_TARGET_HAS_qemu_ldst_i128 0
48 -#define TCG_TARGET_HAS_tst 0
49 -
50 -#define TCG_TARGET_extract_valid(type, ofs, len) use_mips32r2_instructions
51 -#define TCG_TARGET_deposit_valid(type, ofs, len) use_mips32r2_instructions
52 -
53 -static inline bool
54 -tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len)
55 -{
56 - if (ofs == 0) {
57 - switch (len) {
58 - case 8:
59 - case 16:
60 - return use_mips32r2_instructions;
61 - case 32:
62 - return type == TCG_TYPE_I64;
63 - }
64 - }
65 - return false;
66 -}
67 -#define TCG_TARGET_sextract_valid tcg_target_sextract_valid
68 -
69 -#endif
tcg/mips64/tcg-target-mo.h deleted
-13
@@ -1,13 +0,0 @@
1 -/* SPDX-License-Identifier: MIT */
2 -/*
3 - * Define target-specific memory model
4 - * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5 - * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6 - */
7 -
8 -#ifndef TCG_TARGET_MO_H
9 -#define TCG_TARGET_MO_H
10 -
11 -#define TCG_TARGET_DEFAULT_MO 0
12 -
13 -#endif
tcg/mips64/tcg-target-opc.h.inc deleted
-1
@@ -1 +0,0 @@
1 -/* No target specific opcodes. */
tcg/mips64/tcg-target.c.inc deleted
-2605
@@ -1,2605 +0,0 @@
1 -/*
2 - * Tiny Code Generator for QEMU
3 - *
4 - * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5 - * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6 - * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
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 -/* used for function call generation */
28 -#define TCG_TARGET_STACK_ALIGN 16
29 -#define TCG_TARGET_CALL_STACK_OFFSET 0
30 -#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
31 -#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
32 -#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
33 -#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
34 -
35 -#ifdef CONFIG_DEBUG_TCG
36 -static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
37 - "zero",
38 - "at",
39 - "v0",
40 - "v1",
41 - "a0",
42 - "a1",
43 - "a2",
44 - "a3",
45 - "t0",
46 - "t1",
47 - "t2",
48 - "t3",
49 - "t4",
50 - "t5",
51 - "t6",
52 - "t7",
53 - "s0",
54 - "s1",
55 - "s2",
56 - "s3",
57 - "s4",
58 - "s5",
59 - "s6",
60 - "s7",
61 - "t8",
62 - "t9",
63 - "k0",
64 - "k1",
65 - "gp",
66 - "sp",
67 - "s8",
68 - "ra",
69 -};
70 -#endif
71 -
72 -#define TCG_TMP0 TCG_REG_AT
73 -#define TCG_TMP1 TCG_REG_T9
74 -#define TCG_TMP2 TCG_REG_T8
75 -#define TCG_TMP3 TCG_REG_T7
76 -
77 -#define TCG_GUEST_BASE_REG TCG_REG_S7
78 -#define TCG_REG_TB TCG_REG_S6
79 -
80 -/* check if we really need so many registers :P */
81 -static const int tcg_target_reg_alloc_order[] = {
82 - /* Call saved registers. */
83 - TCG_REG_S0,
84 - TCG_REG_S1,
85 - TCG_REG_S2,
86 - TCG_REG_S3,
87 - TCG_REG_S4,
88 - TCG_REG_S5,
89 - TCG_REG_S6,
90 - TCG_REG_S7,
91 - TCG_REG_S8,
92 -
93 - /* Call clobbered registers. */
94 - TCG_REG_T4,
95 - TCG_REG_T5,
96 - TCG_REG_T6,
97 - TCG_REG_T7,
98 - TCG_REG_T8,
99 - TCG_REG_T9,
100 - TCG_REG_V1,
101 - TCG_REG_V0,
102 -
103 - /* Argument registers, opposite order of allocation. */
104 - TCG_REG_T3,
105 - TCG_REG_T2,
106 - TCG_REG_T1,
107 - TCG_REG_T0,
108 - TCG_REG_A3,
109 - TCG_REG_A2,
110 - TCG_REG_A1,
111 - TCG_REG_A0,
112 -};
113 -
114 -static const TCGReg tcg_target_call_iarg_regs[] = {
115 - TCG_REG_A0,
116 - TCG_REG_A1,
117 - TCG_REG_A2,
118 - TCG_REG_A3,
119 - TCG_REG_T0,
120 - TCG_REG_T1,
121 - TCG_REG_T2,
122 - TCG_REG_T3,
123 -};
124 -
125 -static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
126 -{
127 - tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
128 - tcg_debug_assert(slot >= 0 && slot <= 1);
129 - return TCG_REG_V0 + slot;
130 -}
131 -
132 -static const tcg_insn_unit *tb_ret_addr;
133 -static const tcg_insn_unit *bswap32_addr;
134 -static const tcg_insn_unit *bswap32u_addr;
135 -static const tcg_insn_unit *bswap64_addr;
136 -
137 -static bool reloc_pc16(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
138 -{
139 - /* Let the compiler perform the right-shift as part of the arithmetic. */
140 - const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
141 - ptrdiff_t disp = target - (src_rx + 1);
142 - if (disp == (int16_t)disp) {
143 - *src_rw = deposit32(*src_rw, 0, 16, disp);
144 - return true;
145 - }
146 - return false;
147 -}
148 -
149 -static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
150 - intptr_t value, intptr_t addend)
151 -{
152 - value += addend;
153 - switch (type) {
154 - case R_MIPS_PC16:
155 - return reloc_pc16(code_ptr, (const tcg_insn_unit *)value);
156 - case R_MIPS_16:
157 - if (value != (int16_t)value) {
158 - return false;
159 - }
160 - *code_ptr = deposit32(*code_ptr, 0, 16, value);
161 - return true;
162 - }
163 - g_assert_not_reached();
164 -}
165 -
166 -#define TCG_CT_CONST_U16 0x100 /* Unsigned 16-bit: 0 - 0xffff. */
167 -#define TCG_CT_CONST_S16 0x200 /* Signed 16-bit: -32768 - 32767 */
168 -#define TCG_CT_CONST_P2M1 0x400 /* Power of 2 minus 1. */
169 -#define TCG_CT_CONST_WSZ 0x800 /* word size */
170 -
171 -#define ALL_GENERAL_REGS 0xffffffffu
172 -
173 -static bool is_p2m1(tcg_target_long val)
174 -{
175 - return val && ((val + 1) & val) == 0;
176 -}
177 -
178 -/* test if a constant matches the constraint */
179 -static bool tcg_target_const_match(int64_t val, int ct,
180 - TCGType type, TCGCond cond, int vece)
181 -{
182 - if (ct & TCG_CT_CONST) {
183 - return 1;
184 - } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
185 - return 1;
186 - } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
187 - return 1;
188 - } else if ((ct & TCG_CT_CONST_P2M1)
189 - && use_mips32r2_instructions && is_p2m1(val)) {
190 - return 1;
191 - } else if ((ct & TCG_CT_CONST_WSZ)
192 - && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
193 - return 1;
194 - }
195 - return 0;
196 -}
197 -
198 -/* instruction opcodes */
199 -typedef enum {
200 - OPC_J = 002 << 26,
201 - OPC_JAL = 003 << 26,
202 - OPC_BEQ = 004 << 26,
203 - OPC_BNE = 005 << 26,
204 - OPC_BLEZ = 006 << 26,
205 - OPC_BGTZ = 007 << 26,
206 - OPC_ADDIU = 011 << 26,
207 - OPC_SLTI = 012 << 26,
208 - OPC_SLTIU = 013 << 26,
209 - OPC_ANDI = 014 << 26,
210 - OPC_ORI = 015 << 26,
211 - OPC_XORI = 016 << 26,
212 - OPC_LUI = 017 << 26,
213 - OPC_BNEL = 025 << 26,
214 - OPC_BNEZALC_R6 = 030 << 26,
215 - OPC_DADDIU = 031 << 26,
216 - OPC_LDL = 032 << 26,
217 - OPC_LDR = 033 << 26,
218 - OPC_LB = 040 << 26,
219 - OPC_LH = 041 << 26,
220 - OPC_LWL = 042 << 26,
221 - OPC_LW = 043 << 26,
222 - OPC_LBU = 044 << 26,
223 - OPC_LHU = 045 << 26,
224 - OPC_LWR = 046 << 26,
225 - OPC_LWU = 047 << 26,
226 - OPC_SB = 050 << 26,
227 - OPC_SH = 051 << 26,
228 - OPC_SWL = 052 << 26,
229 - OPC_SW = 053 << 26,
230 - OPC_SDL = 054 << 26,
231 - OPC_SDR = 055 << 26,
232 - OPC_SWR = 056 << 26,
233 - OPC_LD = 067 << 26,
234 - OPC_SD = 077 << 26,
235 -
236 - OPC_SPECIAL = 000 << 26,
237 - OPC_SLL = OPC_SPECIAL | 000,
238 - OPC_SRL = OPC_SPECIAL | 002,
239 - OPC_ROTR = OPC_SPECIAL | 002 | (1 << 21),
240 - OPC_SRA = OPC_SPECIAL | 003,
241 - OPC_SLLV = OPC_SPECIAL | 004,
242 - OPC_SRLV = OPC_SPECIAL | 006,
243 - OPC_ROTRV = OPC_SPECIAL | 006 | 0100,
244 - OPC_SRAV = OPC_SPECIAL | 007,
245 - OPC_JR_R5 = OPC_SPECIAL | 010,
246 - OPC_JALR = OPC_SPECIAL | 011,
247 - OPC_MOVZ = OPC_SPECIAL | 012,
248 - OPC_MOVN = OPC_SPECIAL | 013,
249 - OPC_SYNC = OPC_SPECIAL | 017,
250 - OPC_MFHI = OPC_SPECIAL | 020,
251 - OPC_MFLO = OPC_SPECIAL | 022,
252 - OPC_DSLLV = OPC_SPECIAL | 024,
253 - OPC_DSRLV = OPC_SPECIAL | 026,
254 - OPC_DROTRV = OPC_SPECIAL | 026 | 0100,
255 - OPC_DSRAV = OPC_SPECIAL | 027,
256 - OPC_MULT = OPC_SPECIAL | 030,
257 - OPC_MUL_R6 = OPC_SPECIAL | 030 | 0200,
258 - OPC_MUH = OPC_SPECIAL | 030 | 0300,
259 - OPC_MULTU = OPC_SPECIAL | 031,
260 - OPC_MULU = OPC_SPECIAL | 031 | 0200,
261 - OPC_MUHU = OPC_SPECIAL | 031 | 0300,
262 - OPC_DIV = OPC_SPECIAL | 032,
263 - OPC_DIV_R6 = OPC_SPECIAL | 032 | 0200,
264 - OPC_MOD = OPC_SPECIAL | 032 | 0300,
265 - OPC_DIVU = OPC_SPECIAL | 033,
266 - OPC_DIVU_R6 = OPC_SPECIAL | 033 | 0200,
267 - OPC_MODU = OPC_SPECIAL | 033 | 0300,
268 - OPC_DMULT = OPC_SPECIAL | 034,
269 - OPC_DMUL = OPC_SPECIAL | 034 | 0200,
270 - OPC_DMUH = OPC_SPECIAL | 034 | 0300,
271 - OPC_DMULTU = OPC_SPECIAL | 035,
272 - OPC_DMULU = OPC_SPECIAL | 035 | 0200,
273 - OPC_DMUHU = OPC_SPECIAL | 035 | 0300,
274 - OPC_DDIV = OPC_SPECIAL | 036,
275 - OPC_DDIV_R6 = OPC_SPECIAL | 036 | 0200,
276 - OPC_DMOD = OPC_SPECIAL | 036 | 0300,
277 - OPC_DDIVU = OPC_SPECIAL | 037,
278 - OPC_DDIVU_R6 = OPC_SPECIAL | 037 | 0200,
279 - OPC_DMODU = OPC_SPECIAL | 037 | 0300,
280 - OPC_ADDU = OPC_SPECIAL | 041,
281 - OPC_SUBU = OPC_SPECIAL | 043,
282 - OPC_AND = OPC_SPECIAL | 044,
283 - OPC_OR = OPC_SPECIAL | 045,
284 - OPC_XOR = OPC_SPECIAL | 046,
285 - OPC_NOR = OPC_SPECIAL | 047,
286 - OPC_SLT = OPC_SPECIAL | 052,
287 - OPC_SLTU = OPC_SPECIAL | 053,
288 - OPC_DADDU = OPC_SPECIAL | 055,
289 - OPC_DSUBU = OPC_SPECIAL | 057,
290 - OPC_SELEQZ = OPC_SPECIAL | 065,
291 - OPC_SELNEZ = OPC_SPECIAL | 067,
292 - OPC_DSLL = OPC_SPECIAL | 070,
293 - OPC_DSRL = OPC_SPECIAL | 072,
294 - OPC_DROTR = OPC_SPECIAL | 072 | (1 << 21),
295 - OPC_DSRA = OPC_SPECIAL | 073,
296 - OPC_DSLL32 = OPC_SPECIAL | 074,
297 - OPC_DSRL32 = OPC_SPECIAL | 076,
298 - OPC_DROTR32 = OPC_SPECIAL | 076 | (1 << 21),
299 - OPC_DSRA32 = OPC_SPECIAL | 077,
300 - OPC_CLZ_R6 = OPC_SPECIAL | 0120,
301 - OPC_DCLZ_R6 = OPC_SPECIAL | 0122,
302 -
303 - OPC_REGIMM = 001 << 26,
304 - OPC_BLTZ = OPC_REGIMM | (000 << 16),
305 - OPC_BGEZ = OPC_REGIMM | (001 << 16),
306 -
307 - OPC_SPECIAL2 = 034 << 26,
308 - OPC_MUL_R5 = OPC_SPECIAL2 | 002,
309 - OPC_CLZ = OPC_SPECIAL2 | 040,
310 - OPC_DCLZ = OPC_SPECIAL2 | 044,
311 -
312 - OPC_SPECIAL3 = 037 << 26,
313 - OPC_EXT = OPC_SPECIAL3 | 000,
314 - OPC_DEXTM = OPC_SPECIAL3 | 001,
315 - OPC_DEXTU = OPC_SPECIAL3 | 002,
316 - OPC_DEXT = OPC_SPECIAL3 | 003,
317 - OPC_INS = OPC_SPECIAL3 | 004,
318 - OPC_DINSM = OPC_SPECIAL3 | 005,
319 - OPC_DINSU = OPC_SPECIAL3 | 006,
320 - OPC_DINS = OPC_SPECIAL3 | 007,
321 - OPC_WSBH = OPC_SPECIAL3 | 00240,
322 - OPC_DSBH = OPC_SPECIAL3 | 00244,
323 - OPC_DSHD = OPC_SPECIAL3 | 00544,
324 - OPC_SEB = OPC_SPECIAL3 | 02040,
325 - OPC_SEH = OPC_SPECIAL3 | 03040,
326 -
327 - /* MIPS r6 doesn't have JR, JALR should be used instead */
328 - OPC_JR = use_mips32r6_instructions ? OPC_JALR : OPC_JR_R5,
329 -
330 - /*
331 - * MIPS r6 replaces MUL with an alternative encoding which is
332 - * backwards-compatible at the assembly level.
333 - */
334 - OPC_MUL = use_mips32r6_instructions ? OPC_MUL_R6 : OPC_MUL_R5,
335 -
336 - /* MIPS r6 introduced names for weaker variants of SYNC. These are
337 - backward compatible to previous architecture revisions. */
338 - OPC_SYNC_WMB = OPC_SYNC | 0x04 << 6,
339 - OPC_SYNC_MB = OPC_SYNC | 0x10 << 6,
340 - OPC_SYNC_ACQUIRE = OPC_SYNC | 0x11 << 6,
341 - OPC_SYNC_RELEASE = OPC_SYNC | 0x12 << 6,
342 - OPC_SYNC_RMB = OPC_SYNC | 0x13 << 6,
343 -} MIPSInsn;
344 -
345 -/*
346 - * Type reg
347 - */
348 -static void tcg_out_opc_reg(TCGContext *s, MIPSInsn opc,
349 - TCGReg rd, TCGReg rs, TCGReg rt)
350 -{
351 - int32_t inst;
352 -
353 - inst = opc;
354 - inst |= (rs & 0x1F) << 21;
355 - inst |= (rt & 0x1F) << 16;
356 - inst |= (rd & 0x1F) << 11;
357 - tcg_out32(s, inst);
358 -}
359 -
360 -/*
361 - * Type immediate
362 - */
363 -static void tcg_out_opc_imm(TCGContext *s, MIPSInsn opc,
364 - TCGReg rt, TCGReg rs, TCGArg imm)
365 -{
366 - int32_t inst;
367 -
368 - inst = opc;
369 - inst |= (rs & 0x1F) << 21;
370 - inst |= (rt & 0x1F) << 16;
371 - inst |= (imm & 0xffff);
372 - tcg_out32(s, inst);
373 -}
374 -
375 -/*
376 - * Type bitfield
377 - */
378 -static void tcg_out_opc_bf(TCGContext *s, MIPSInsn opc, TCGReg rt,
379 - TCGReg rs, int msb, int lsb)
380 -{
381 - int32_t inst;
382 -
383 - inst = opc;
384 - inst |= (rs & 0x1F) << 21;
385 - inst |= (rt & 0x1F) << 16;
386 - inst |= (msb & 0x1F) << 11;
387 - inst |= (lsb & 0x1F) << 6;
388 - tcg_out32(s, inst);
389 -}
390 -
391 -static void tcg_out_opc_bf64(TCGContext *s, MIPSInsn opc, MIPSInsn opm,
392 - MIPSInsn oph, TCGReg rt, TCGReg rs,
393 - int msb, int lsb)
394 -{
395 - if (lsb >= 32) {
396 - opc = oph;
397 - msb -= 32;
398 - lsb -= 32;
399 - } else if (msb >= 32) {
400 - opc = opm;
401 - msb -= 32;
402 - }
403 - tcg_out_opc_bf(s, opc, rt, rs, msb, lsb);
404 -}
405 -
406 -/*
407 - * Type branch
408 - */
409 -static void tcg_out_opc_br(TCGContext *s, MIPSInsn opc, TCGReg rt, TCGReg rs)
410 -{
411 - tcg_out_opc_imm(s, opc, rt, rs, 0);
412 -}
413 -
414 -/*
415 - * Type sa
416 - */
417 -static void tcg_out_opc_sa(TCGContext *s, MIPSInsn opc,
418 - TCGReg rd, TCGReg rt, TCGArg sa)
419 -{
420 - int32_t inst;
421 -
422 - inst = opc;
423 - inst |= (rt & 0x1F) << 16;
424 - inst |= (rd & 0x1F) << 11;
425 - inst |= (sa & 0x1F) << 6;
426 - tcg_out32(s, inst);
427 -
428 -}
429 -
430 -static void tcg_out_opc_sa64(TCGContext *s, MIPSInsn opc1, MIPSInsn opc2,
431 - TCGReg rd, TCGReg rt, TCGArg sa)
432 -{
433 - int32_t inst;
434 -
435 - inst = (sa & 32 ? opc2 : opc1);
436 - inst |= (rt & 0x1F) << 16;
437 - inst |= (rd & 0x1F) << 11;
438 - inst |= (sa & 0x1F) << 6;
439 - tcg_out32(s, inst);
440 -}
441 -
442 -/*
443 - * Type jump.
444 - * Returns true if the branch was in range and the insn was emitted.
445 - */
446 -static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, const void *target)
447 -{
448 - uintptr_t dest = (uintptr_t)target;
449 - uintptr_t from = (uintptr_t)tcg_splitwx_to_rx(s->code_ptr) + 4;
450 - int32_t inst;
451 -
452 - /* The pc-region branch happens within the 256MB region of
453 - the delay slot (thus the +4). */
454 - if ((from ^ dest) & -(1 << 28)) {
455 - return false;
456 - }
457 - tcg_debug_assert((dest & 3) == 0);
458 -
459 - inst = opc;
460 - inst |= (dest >> 2) & 0x3ffffff;
461 - tcg_out32(s, inst);
462 - return true;
463 -}
464 -
465 -static void tcg_out_nop(TCGContext *s)
466 -{
467 - tcg_out32(s, 0);
468 -}
469 -
470 -static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
471 -{
472 - memset(p, 0, count * sizeof(tcg_insn_unit));
473 -}
474 -
475 -static void tcg_out_dsll(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
476 -{
477 - tcg_out_opc_sa64(s, OPC_DSLL, OPC_DSLL32, rd, rt, sa);
478 -}
479 -
480 -static void tcg_out_dsrl(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
481 -{
482 - tcg_out_opc_sa64(s, OPC_DSRL, OPC_DSRL32, rd, rt, sa);
483 -}
484 -
485 -static void tcg_out_dsra(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
486 -{
487 - tcg_out_opc_sa64(s, OPC_DSRA, OPC_DSRA32, rd, rt, sa);
488 -}
489 -
490 -static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
491 -{
492 - /* Simple reg-reg move, optimising out the 'do nothing' case */
493 - if (ret != arg) {
494 - tcg_out_opc_reg(s, OPC_OR, ret, arg, TCG_REG_ZERO);
495 - }
496 - return true;
497 -}
498 -
499 -static bool tcg_out_movi_one(TCGContext *s, TCGReg ret, tcg_target_long arg)
500 -{
501 - if (arg == (int16_t)arg) {
502 - tcg_out_opc_imm(s, OPC_ADDIU, ret, TCG_REG_ZERO, arg);
503 - return true;
504 - }
505 - if (arg == (uint16_t)arg) {
506 - tcg_out_opc_imm(s, OPC_ORI, ret, TCG_REG_ZERO, arg);
507 - return true;
508 - }
509 - if (arg == (int32_t)arg && (arg & 0xffff) == 0) {
510 - tcg_out_opc_imm(s, OPC_LUI, ret, TCG_REG_ZERO, arg >> 16);
511 - return true;
512 - }
513 - return false;
514 -}
515 -
516 -static bool tcg_out_movi_two(TCGContext *s, TCGReg ret, tcg_target_long arg)
517 -{
518 - /*
519 - * All signed 32-bit constants are loadable with two immediates,
520 - * and everything else requires more work.
521 - */
522 - if (arg == (int32_t)arg) {
523 - if (!tcg_out_movi_one(s, ret, arg)) {
524 - tcg_out_opc_imm(s, OPC_LUI, ret, TCG_REG_ZERO, arg >> 16);
525 - tcg_out_opc_imm(s, OPC_ORI, ret, ret, arg & 0xffff);
526 - }
527 - return true;
528 - }
529 - return false;
530 -}
531 -
532 -static void tcg_out_movi_pool(TCGContext *s, TCGReg ret,
533 - tcg_target_long arg, TCGReg tbreg)
534 -{
535 - new_pool_label(s, arg, R_MIPS_16, s->code_ptr, tcg_tbrel_diff(s, NULL));
536 - tcg_out_opc_imm(s, OPC_LD, ret, tbreg, 0);
537 -}
538 -
539 -static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
540 - tcg_target_long arg, TCGReg tbreg)
541 -{
542 - tcg_target_long tmp;
543 - int sh, lo;
544 -
545 - if (type == TCG_TYPE_I32) {
546 - arg = (int32_t)arg;
547 - }
548 -
549 - /* Load all 32-bit constants. */
550 - if (tcg_out_movi_two(s, ret, arg)) {
551 - return;
552 - }
553 -
554 - /* Load addresses within 2GB of TB with 1 or 3 insns. */
555 - tmp = tcg_tbrel_diff(s, (void *)arg);
556 - if (tmp == (int16_t)tmp) {
557 - tcg_out_opc_imm(s, OPC_DADDIU, ret, tbreg, tmp);
558 - return;
559 - }
560 - if (tcg_out_movi_two(s, ret, tmp)) {
561 - tcg_out_opc_reg(s, OPC_DADDU, ret, ret, tbreg);
562 - return;
563 - }
564 -
565 - /*
566 - * Load bitmasks with a right-shift. This is good for things
567 - * like 0x0fff_ffff_ffff_fff0: ADDUI r,0,0xff00 + DSRL r,r,4.
568 - * or similarly using LUI. For this to work, bit 31 must be set.
569 - */
570 - if (arg > 0 && (int32_t)arg < 0) {
571 - sh = clz64(arg);
572 - if (tcg_out_movi_one(s, ret, arg << sh)) {
573 - tcg_out_dsrl(s, ret, ret, sh);
574 - return;
575 - }
576 - }
577 -
578 - /*
579 - * Load slightly larger constants using left-shift.
580 - * Limit this sequence to 3 insns to avoid too much expansion.
581 - */
582 - sh = ctz64(arg);
583 - if (sh && tcg_out_movi_two(s, ret, arg >> sh)) {
584 - tcg_out_dsll(s, ret, ret, sh);
585 - return;
586 - }
587 -
588 - /*
589 - * Load slightly larger constants using left-shift and add/or.
590 - * Prefer addi with a negative immediate when that would produce
591 - * a larger shift. For this to work, bits 15 and 16 must be set.
592 - */
593 - lo = arg & 0xffff;
594 - if (lo) {
595 - if ((arg & 0x18000) == 0x18000) {
596 - lo = (int16_t)arg;
597 - }
598 - tmp = arg - lo;
599 - sh = ctz64(tmp);
600 - tmp >>= sh;
601 - if (tcg_out_movi_one(s, ret, tmp)) {
602 - tcg_out_dsll(s, ret, ret, sh);
603 - tcg_out_opc_imm(s, lo < 0 ? OPC_DADDIU : OPC_ORI, ret, ret, lo);
604 - return;
605 - }
606 - }
607 -
608 - /* Otherwise, put 64-bit constants into the constant pool. */
609 - tcg_out_movi_pool(s, ret, arg, tbreg);
610 -}
611 -
612 -static void tcg_out_movi(TCGContext *s, TCGType type,
613 - TCGReg ret, tcg_target_long arg)
614 -{
615 - tcg_out_movi_int(s, type, ret, arg, TCG_REG_TB);
616 -}
617 -
618 -static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
619 -{
620 - tcg_debug_assert(use_mips32r2_instructions);
621 - tcg_out_opc_reg(s, OPC_SEB, rd, TCG_REG_ZERO, rs);
622 -}
623 -
624 -static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
625 -{
626 - tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xff);
627 -}
628 -
629 -static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
630 -{
631 - tcg_debug_assert(use_mips32r2_instructions);
632 - tcg_out_opc_reg(s, OPC_SEH, rd, TCG_REG_ZERO, rs);
633 -}
634 -
635 -static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
636 -{
637 - tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xffff);
638 -}
639 -
640 -static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
641 -{
642 - tcg_out_opc_sa(s, OPC_SLL, rd, rs, 0);
643 -}
644 -
645 -static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
646 -{
647 - if (rd != rs) {
648 - tcg_out_ext32s(s, rd, rs);
649 - }
650 -}
651 -
652 -static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
653 -{
654 - tcg_out_ext32u(s, rd, rs);
655 -}
656 -
657 -static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
658 -{
659 - tcg_out_ext32s(s, rd, rs);
660 -}
661 -
662 -static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
663 -{
664 - return false;
665 -}
666 -
667 -static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
668 - tcg_target_long imm)
669 -{
670 - /* This function is only used for passing structs by reference. */
671 - g_assert_not_reached();
672 -}
673 -
674 -static void tcg_out_bswap_subr(TCGContext *s, const tcg_insn_unit *sub)
675 -{
676 - if (!tcg_out_opc_jmp(s, OPC_JAL, sub)) {
677 - tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP1, (uintptr_t)sub);
678 - tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_TMP1, 0);
679 - }
680 -}
681 -
682 -static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
683 -{
684 - if (use_mips32r2_instructions) {
685 - tcg_out_opc_bf(s, OPC_DEXT, ret, arg, 31, 0);
686 - } else {
687 - tcg_out_dsll(s, ret, arg, 32);
688 - tcg_out_dsrl(s, ret, ret, 32);
689 - }
690 -}
691 -
692 -static void tcg_out_ldst(TCGContext *s, MIPSInsn opc, TCGReg data,
693 - TCGReg addr, intptr_t ofs)
694 -{
695 - int16_t lo = ofs;
696 - if (ofs != lo) {
697 - tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - lo);
698 - if (addr != TCG_REG_ZERO) {
699 - tcg_out_opc_reg(s, OPC_DADDU, TCG_TMP0, TCG_TMP0, addr);
700 - }
701 - addr = TCG_TMP0;
702 - }
703 - tcg_out_opc_imm(s, opc, data, addr, lo);
704 -}
705 -
706 -static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
707 - TCGReg arg1, intptr_t arg2)
708 -{
709 - MIPSInsn opc = type == TCG_TYPE_I32 ? OPC_LW : OPC_LD;
710 - tcg_out_ldst(s, opc, arg, arg1, arg2);
711 -}
712 -
713 -static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
714 - TCGReg arg1, intptr_t arg2)
715 -{
716 - MIPSInsn opc = type == TCG_TYPE_I32 ? OPC_SW : OPC_SD;
717 - tcg_out_ldst(s, opc, arg, arg1, arg2);
718 -}
719 -
720 -static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
721 - TCGReg base, intptr_t ofs)
722 -{
723 - if (val == 0) {
724 - tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
725 - return true;
726 - }
727 - return false;
728 -}
729 -
730 -#define SETCOND_INV TCG_TARGET_NB_REGS
731 -#define SETCOND_NEZ (SETCOND_INV << 1)
732 -#define SETCOND_FLAGS (SETCOND_INV | SETCOND_NEZ)
733 -
734 -static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
735 - TCGReg arg1, TCGReg arg2)
736 -{
737 - int flags = 0;
738 -
739 - switch (cond) {
740 - case TCG_COND_EQ: /* -> NE */
741 - case TCG_COND_GE: /* -> LT */
742 - case TCG_COND_GEU: /* -> LTU */
743 - case TCG_COND_LE: /* -> GT */
744 - case TCG_COND_LEU: /* -> GTU */
745 - cond = tcg_invert_cond(cond);
746 - flags ^= SETCOND_INV;
747 - break;
748 - default:
749 - break;
750 - }
751 -
752 - switch (cond) {
753 - case TCG_COND_NE:
754 - flags |= SETCOND_NEZ;
755 - if (arg2 == 0) {
756 - return arg1 | flags;
757 - }
758 - tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
759 - break;
760 - case TCG_COND_LT:
761 - tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
762 - break;
763 - case TCG_COND_LTU:
764 - tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
765 - break;
766 - case TCG_COND_GT:
767 - tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
768 - break;
769 - case TCG_COND_GTU:
770 - tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
771 - break;
772 - default:
773 - g_assert_not_reached();
774 - }
775 - return ret | flags;
776 -}
777 -
778 -static void tcg_out_setcond_end(TCGContext *s, TCGReg ret, int tmpflags)
779 -{
780 - if (tmpflags != ret) {
781 - TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
782 -
783 - switch (tmpflags & SETCOND_FLAGS) {
784 - case SETCOND_INV:
785 - /* Intermediate result is boolean: simply invert. */
786 - tcg_out_opc_imm(s, OPC_XORI, ret, tmp, 1);
787 - break;
788 - case SETCOND_NEZ:
789 - /* Intermediate result is zero/non-zero: test != 0. */
790 - tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp);
791 - break;
792 - case SETCOND_NEZ | SETCOND_INV:
793 - /* Intermediate result is zero/non-zero: test == 0. */
794 - tcg_out_opc_imm(s, OPC_SLTIU, ret, tmp, 1);
795 - break;
796 - default:
797 - g_assert_not_reached();
798 - }
799 - }
800 -}
801 -
802 -static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
803 - TCGReg ret, TCGReg arg1, TCGReg arg2)
804 -{
805 - int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2);
806 - tcg_out_setcond_end(s, ret, tmpflags);
807 -}
808 -
809 -static const TCGOutOpSetcond outop_setcond = {
810 - .base.static_constraint = C_O1_I2(r, r, rz),
811 - .out_rrr = tgen_setcond,
812 -};
813 -
814 -static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
815 - TCGReg ret, TCGReg arg1, TCGReg arg2)
816 -{
817 - int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2);
818 - TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
819 -
820 - /* If intermediate result is zero/non-zero: test != 0. */
821 - if (tmpflags & SETCOND_NEZ) {
822 - tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp);
823 - tmp = ret;
824 - }
825 - /* Produce the 0/-1 result. */
826 - if (tmpflags & SETCOND_INV) {
827 - tcg_out_opc_imm(s, OPC_ADDIU, ret, tmp, -1);
828 - } else {
829 - tcg_out_opc_reg(s, OPC_SUBU, ret, TCG_REG_ZERO, tmp);
830 - }
831 -}
832 -
833 -static const TCGOutOpSetcond outop_negsetcond = {
834 - .base.static_constraint = C_O1_I2(r, r, rz),
835 - .out_rrr = tgen_negsetcond,
836 -};
837 -
838 -static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
839 - TCGReg arg1, TCGReg arg2, TCGLabel *l)
840 -{
841 - static const MIPSInsn b_zero[16] = {
842 - [TCG_COND_LT] = OPC_BLTZ,
843 - [TCG_COND_GT] = OPC_BGTZ,
844 - [TCG_COND_LE] = OPC_BLEZ,
845 - [TCG_COND_GE] = OPC_BGEZ,
846 - };
847 -
848 - MIPSInsn b_opc = 0;
849 -
850 - switch (cond) {
851 - case TCG_COND_EQ:
852 - b_opc = OPC_BEQ;
853 - break;
854 - case TCG_COND_NE:
855 - b_opc = OPC_BNE;
856 - break;
857 - case TCG_COND_LT:
858 - case TCG_COND_GT:
859 - case TCG_COND_LE:
860 - case TCG_COND_GE:
861 - if (arg2 == 0) {
862 - b_opc = b_zero[cond];
863 - arg2 = arg1;
864 - arg1 = 0;
865 - }
866 - break;
867 - default:
868 - break;
869 - }
870 -
871 - if (b_opc == 0) {
872 - int tmpflags = tcg_out_setcond_int(s, cond, TCG_TMP0, arg1, arg2);
873 -
874 - arg2 = TCG_REG_ZERO;
875 - arg1 = tmpflags & ~SETCOND_FLAGS;
876 - b_opc = tmpflags & SETCOND_INV ? OPC_BEQ : OPC_BNE;
877 - }
878 -
879 - tcg_out_reloc(s, s->code_ptr, R_MIPS_PC16, l, 0);
880 - tcg_out_opc_br(s, b_opc, arg1, arg2);
881 - tcg_out_nop(s);
882 -}
883 -
884 -static const TCGOutOpBrcond outop_brcond = {
885 - .base.static_constraint = C_O0_I2(r, rz),
886 - .out_rr = tgen_brcond,
887 -};
888 -
889 -void tcg_out_br(TCGContext *s, TCGLabel *l)
890 -{
891 - tgen_brcond(s, TCG_TYPE_I32, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, l);
892 -}
893 -
894 -static void tgen_movcond(TCGContext *s, TCGType type, TCGCond cond,
895 - TCGReg ret, TCGReg c1, TCGArg c2, bool const_c2,
896 - TCGArg v1, bool const_v1, TCGArg v2, bool const_v2)
897 -{
898 - int tmpflags;
899 - bool eqz;
900 -
901 - /* If one of the values is zero, put it last to match SEL*Z instructions */
902 - if (use_mips32r6_instructions && v1 == 0) {
903 - v1 = v2;
904 - v2 = 0;
905 - cond = tcg_invert_cond(cond);
906 - }
907 -
908 - tmpflags = tcg_out_setcond_int(s, cond, TCG_TMP0, c1, c2);
909 - c1 = tmpflags & ~SETCOND_FLAGS;
910 - eqz = tmpflags & SETCOND_INV;
911 -
912 - if (use_mips32r6_instructions) {
913 - MIPSInsn m_opc_t = eqz ? OPC_SELEQZ : OPC_SELNEZ;
914 - MIPSInsn m_opc_f = eqz ? OPC_SELNEZ : OPC_SELEQZ;
915 -
916 - if (v2 != 0) {
917 - tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
918 - }
919 - tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
920 - if (v2 != 0) {
921 - tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
922 - }
923 - return;
924 - }
925 -
926 - /* This should be guaranteed via constraints */
927 - tcg_debug_assert(v2 == ret);
928 -
929 - if (use_movnz_instructions) {
930 - MIPSInsn m_opc = eqz ? OPC_MOVZ : OPC_MOVN;
931 - tcg_out_opc_reg(s, m_opc, ret, v1, c1);
932 - } else {
933 - /* Invert the condition in order to branch over the move. */
934 - MIPSInsn b_opc = eqz ? OPC_BNE : OPC_BEQ;
935 - tcg_out_opc_imm(s, b_opc, c1, TCG_REG_ZERO, 2);
936 - tcg_out_nop(s);
937 - /* Open-code tcg_out_mov, without the nop-move check. */
938 - tcg_out_opc_reg(s, OPC_OR, ret, v1, TCG_REG_ZERO);
939 - }
940 -}
941 -
942 -static const TCGOutOpMovcond outop_movcond = {
943 - .base.static_constraint = (use_mips32r6_instructions
944 - ? C_O1_I4(r, r, rz, rz, rz)
945 - : C_O1_I4(r, r, rz, rz, 0)),
946 - .out = tgen_movcond,
947 -};
948 -
949 -static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
950 -{
951 - /*
952 - * Note that __mips_abicalls requires the called function's address
953 - * to be loaded into $25 (t9), even if a direct branch is in range.
954 - *
955 - * We can re-use helper addresses often; always drop the pointer
956 - * into the constant pool.
957 - */
958 - tcg_out_movi_pool(s, TCG_REG_T9, (uintptr_t)arg, TCG_REG_TB);
959 -
960 - if (tail) {
961 - if (!tcg_out_opc_jmp(s, OPC_J, arg)) {
962 - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_T9, 0);
963 - }
964 - } else {
965 - if (!tcg_out_opc_jmp(s, OPC_JAL, arg)) {
966 - tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
967 - }
968 - }
969 -}
970 -
971 -static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg,
972 - const TCGHelperInfo *info)
973 -{
974 - tcg_out_call_int(s, arg, false);
975 - tcg_out_nop(s);
976 -}
977 -
978 -/* We have four temps, we might as well expose three of them. */
979 -static const TCGLdstHelperParam ldst_helper_param = {
980 - .ntmp = 3, .tmp = { TCG_TMP0, TCG_TMP1, TCG_TMP2 }
981 -};
982 -
983 -static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
984 -{
985 - const tcg_insn_unit *tgt_rx = tcg_splitwx_to_rx(s->code_ptr);
986 - MemOp opc = get_memop(l->oi);
987 -
988 - /* resolve label address */
989 - if (!reloc_pc16(l->label_ptr[0], tgt_rx)
990 - || (l->label_ptr[1] && !reloc_pc16(l->label_ptr[1], tgt_rx))) {
991 - return false;
992 - }
993 -
994 - tcg_out_ld_helper_args(s, l, &ldst_helper_param);
995 -
996 - tcg_out_call_int(s, qemu_ld_helpers[opc & MO_SSIZE], false);
997 - /* delay slot */
998 - tcg_out_nop(s);
999 -
1000 - tcg_out_ld_helper_ret(s, l, true, &ldst_helper_param);
1001 -
1002 - tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1003 - if (!reloc_pc16(s->code_ptr - 1, l->raddr)) {
1004 - return false;
1005 - }
1006 -
1007 - /* delay slot */
1008 - tcg_out_nop(s);
1009 - return true;
1010 -}
1011 -
1012 -static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1013 -{
1014 - const tcg_insn_unit *tgt_rx = tcg_splitwx_to_rx(s->code_ptr);
1015 - MemOp opc = get_memop(l->oi);
1016 -
1017 - /* resolve label address */
1018 - if (!reloc_pc16(l->label_ptr[0], tgt_rx)
1019 - || (l->label_ptr[1] && !reloc_pc16(l->label_ptr[1], tgt_rx))) {
1020 - return false;
1021 - }
1022 -
1023 - tcg_out_st_helper_args(s, l, &ldst_helper_param);
1024 -
1025 - tcg_out_call_int(s, qemu_st_helpers[opc & MO_SIZE], false);
1026 - /* delay slot */
1027 - tcg_out_nop(s);
1028 -
1029 - tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1030 - if (!reloc_pc16(s->code_ptr - 1, l->raddr)) {
1031 - return false;
1032 - }
1033 -
1034 - /* delay slot */
1035 - tcg_out_nop(s);
1036 - return true;
1037 -}
1038 -
1039 -typedef struct {
1040 - TCGReg base;
1041 - TCGAtomAlign aa;
1042 -} HostAddress;
1043 -
1044 -bool tcg_target_has_memory_bswap(MemOp memop)
1045 -{
1046 - return false;
1047 -}
1048 -
1049 -/* We expect to use a 16-bit negative offset from ENV. */
1050 -#define MIN_TLB_MASK_TABLE_OFS -32768
1051 -
1052 -/*
1053 - * For system-mode, perform the TLB load and compare.
1054 - * For user-mode, perform any required alignment tests.
1055 - * In both cases, return a TCGLabelQemuLdst structure if the slow path
1056 - * is required and fill in @h with the host address for the fast path.
1057 - */
1058 -static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
1059 - TCGReg addr, MemOpIdx oi, bool is_ld)
1060 -{
1061 - TCGType addr_type = s->addr_type;
1062 - TCGLabelQemuLdst *ldst = NULL;
1063 - MemOp opc = get_memop(oi);
1064 - MemOp a_bits;
1065 - unsigned s_bits = opc & MO_SIZE;
1066 - unsigned a_mask;
1067 - TCGReg base;
1068 -
1069 - h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_IFALIGN, false);
1070 - a_bits = h->aa.align;
1071 - a_mask = (1 << a_bits) - 1;
1072 -
1073 - if (tcg_use_softmmu) {
1074 - unsigned s_mask = (1 << s_bits) - 1;
1075 - int mem_index = get_mmuidx(oi);
1076 - int fast_off = tlb_mask_table_ofs(s, mem_index);
1077 - int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1078 - int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1079 - int add_off = offsetof(CPUTLBEntry, addend);
1080 - int cmp_off = is_ld ? offsetof(CPUTLBEntry, addr_read)
1081 - : offsetof(CPUTLBEntry, addr_write);
1082 -
1083 - ldst = new_ldst_label(s);
1084 - ldst->is_ld = is_ld;
1085 - ldst->oi = oi;
1086 - ldst->addr_reg = addr;
1087 -
1088 - /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
1089 - tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
1090 - tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP1, TCG_AREG0, table_off);
1091 -
1092 - /* Extract the TLB index from the address into TMP3. */
1093 - if (addr_type == TCG_TYPE_I32) {
1094 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addr,
1095 - TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1096 - } else {
1097 - tcg_out_dsrl(s, TCG_TMP3, addr, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1098 - }
1099 - tcg_out_opc_reg(s, OPC_AND, TCG_TMP3, TCG_TMP3, TCG_TMP0);
1100 -
1101 - /* Add the tlb_table pointer, creating the CPUTLBEntry address. */
1102 - tcg_out_opc_reg(s, OPC_DADDU, TCG_TMP3, TCG_TMP3, TCG_TMP1);
1103 -
1104 - /* Load the tlb comparator. */
1105 - if (addr_type == TCG_TYPE_I32) {
1106 - tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
1107 - cmp_off + HOST_BIG_ENDIAN * 4);
1108 - } else {
1109 - tcg_out_ld(s, TCG_TYPE_REG, TCG_TMP0, TCG_TMP3, cmp_off);
1110 - }
1111 -
1112 - /* Load the tlb addend for the fast path. */
1113 - tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
1114 -
1115 - /*
1116 - * Mask the page bits, keeping the alignment bits to compare against.
1117 - * For unaligned accesses, compare against the end of the access to
1118 - * verify that it does not cross a page boundary.
1119 - */
1120 - tcg_out_movi(s, addr_type, TCG_TMP1, TARGET_PAGE_MASK | a_mask);
1121 - if (a_mask < s_mask) {
1122 - tcg_out_opc_imm(s, (addr_type == TCG_TYPE_I32
1123 - ? OPC_ADDIU : OPC_DADDIU),
1124 - TCG_TMP2, addr, s_mask - a_mask);
1125 - tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP2);
1126 - } else {
1127 - tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addr);
1128 - }
1129 -
1130 - /* Zero extend a 32-bit guest address for a 64-bit host. */
1131 - if (addr_type == TCG_TYPE_I32) {
1132 - tcg_out_ext32u(s, TCG_TMP2, addr);
1133 - addr = TCG_TMP2;
1134 - }
1135 -
1136 - ldst->label_ptr[0] = s->code_ptr;
1137 - tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
1138 -
1139 - /* delay slot */
1140 - base = TCG_TMP3;
1141 - tcg_out_opc_reg(s, OPC_DADDU, base, TCG_TMP3, addr);
1142 - } else {
1143 - if (a_mask && (use_mips32r6_instructions || a_bits != s_bits)) {
1144 - ldst = new_ldst_label(s);
1145 -
1146 - ldst->is_ld = is_ld;
1147 - ldst->oi = oi;
1148 - ldst->addr_reg = addr;
1149 -
1150 - /* We are expecting a_bits to max out at 7, much lower than ANDI. */
1151 - tcg_debug_assert(a_bits < 16);
1152 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addr, a_mask);
1153 -
1154 - ldst->label_ptr[0] = s->code_ptr;
1155 - if (use_mips32r6_instructions) {
1156 - tcg_out_opc_br(s, OPC_BNEZALC_R6, TCG_REG_ZERO, TCG_TMP0);
1157 - } else {
1158 - tcg_out_opc_br(s, OPC_BNEL, TCG_TMP0, TCG_REG_ZERO);
1159 - tcg_out_nop(s);
1160 - }
1161 - }
1162 -
1163 - base = addr;
1164 - if (addr_type == TCG_TYPE_I32) {
1165 - tcg_out_ext32u(s, TCG_REG_A0, base);
1166 - base = TCG_REG_A0;
1167 - }
1168 - if (guest_base) {
1169 - if (guest_base == (int16_t)guest_base) {
1170 - tcg_out_opc_imm(s, OPC_DADDIU, TCG_REG_A0, base, guest_base);
1171 - } else {
1172 - tcg_out_opc_reg(s, OPC_DADDU, TCG_REG_A0, base,
1173 - TCG_GUEST_BASE_REG);
1174 - }
1175 - base = TCG_REG_A0;
1176 - }
1177 - }
1178 -
1179 - h->base = base;
1180 - return ldst;
1181 -}
1182 -
1183 -static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1184 - TCGReg base, MemOp opc, TCGType type)
1185 -{
1186 - switch (opc & MO_SSIZE) {
1187 - case MO_UB:
1188 - tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
1189 - break;
1190 - case MO_SB:
1191 - tcg_out_opc_imm(s, OPC_LB, lo, base, 0);
1192 - break;
1193 - case MO_UW:
1194 - tcg_out_opc_imm(s, OPC_LHU, lo, base, 0);
1195 - break;
1196 - case MO_SW:
1197 - tcg_out_opc_imm(s, OPC_LH, lo, base, 0);
1198 - break;
1199 - case MO_UL:
1200 - if (type == TCG_TYPE_I64) {
1201 - tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
1202 - break;
1203 - }
1204 - /* FALLTHRU */
1205 - case MO_SL:
1206 - tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1207 - break;
1208 - case MO_UQ:
1209 - tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
1210 - break;
1211 - default:
1212 - g_assert_not_reached();
1213 - }
1214 -}
1215 -
1216 -static void tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
1217 - TCGReg base, MemOp opc, TCGType type)
1218 -{
1219 - const MIPSInsn lw1 = HOST_BIG_ENDIAN ? OPC_LWL : OPC_LWR;
1220 - const MIPSInsn lw2 = HOST_BIG_ENDIAN ? OPC_LWR : OPC_LWL;
1221 - const MIPSInsn ld1 = HOST_BIG_ENDIAN ? OPC_LDL : OPC_LDR;
1222 - const MIPSInsn ld2 = HOST_BIG_ENDIAN ? OPC_LDR : OPC_LDL;
1223 - bool sgn = opc & MO_SIGN;
1224 -
1225 - switch (opc & MO_SIZE) {
1226 - case MO_16:
1227 - if (HOST_BIG_ENDIAN) {
1228 - tcg_out_opc_imm(s, sgn ? OPC_LB : OPC_LBU, TCG_TMP0, base, 0);
1229 - tcg_out_opc_imm(s, OPC_LBU, lo, base, 1);
1230 - if (use_mips32r2_instructions) {
1231 - tcg_out_opc_bf(s, OPC_INS, lo, TCG_TMP0, 31, 8);
1232 - } else {
1233 - tcg_out_opc_sa(s, OPC_SLL, TCG_TMP0, TCG_TMP0, 8);
1234 - tcg_out_opc_reg(s, OPC_OR, lo, lo, TCG_TMP0);
1235 - }
1236 - } else if (use_mips32r2_instructions && lo != base) {
1237 - tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
1238 - tcg_out_opc_imm(s, sgn ? OPC_LB : OPC_LBU, TCG_TMP0, base, 1);
1239 - tcg_out_opc_bf(s, OPC_INS, lo, TCG_TMP0, 31, 8);
1240 - } else {
1241 - tcg_out_opc_imm(s, OPC_LBU, TCG_TMP0, base, 0);
1242 - tcg_out_opc_imm(s, sgn ? OPC_LB : OPC_LBU, TCG_TMP1, base, 1);
1243 - tcg_out_opc_sa(s, OPC_SLL, TCG_TMP1, TCG_TMP1, 8);
1244 - tcg_out_opc_reg(s, OPC_OR, lo, TCG_TMP0, TCG_TMP1);
1245 - }
1246 - break;
1247 -
1248 - case MO_32:
1249 - tcg_out_opc_imm(s, lw1, lo, base, 0);
1250 - tcg_out_opc_imm(s, lw2, lo, base, 3);
1251 - if (type == TCG_TYPE_I64 && !sgn) {
1252 - tcg_out_ext32u(s, lo, lo);
1253 - }
1254 - break;
1255 -
1256 - case MO_64:
1257 - tcg_out_opc_imm(s, ld1, lo, base, 0);
1258 - tcg_out_opc_imm(s, ld2, lo, base, 7);
1259 - break;
1260 -
1261 - default:
1262 - g_assert_not_reached();
1263 - }
1264 -}
1265 -
1266 -static void tgen_qemu_ld(TCGContext *s, TCGType type, TCGReg data,
1267 - TCGReg addr, MemOpIdx oi)
1268 -{
1269 - MemOp opc = get_memop(oi);
1270 - TCGLabelQemuLdst *ldst;
1271 - HostAddress h;
1272 -
1273 - ldst = prepare_host_addr(s, &h, addr, oi, true);
1274 -
1275 - if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
1276 - tcg_out_qemu_ld_direct(s, data, 0, h.base, opc, type);
1277 - } else {
1278 - tcg_out_qemu_ld_unalign(s, data, 0, h.base, opc, type);
1279 - }
1280 -
1281 - if (ldst) {
1282 - ldst->type = type;
1283 - ldst->datalo_reg = data;
1284 - ldst->datahi_reg = 0;
1285 - ldst->raddr = tcg_splitwx_to_rx(s->code_ptr);
1286 - }
1287 -}
1288 -
1289 -static const TCGOutOpQemuLdSt outop_qemu_ld = {
1290 - .base.static_constraint = C_O1_I1(r, r),
1291 - .out = tgen_qemu_ld,
1292 -};
1293 -
1294 -static const TCGOutOpQemuLdSt2 outop_qemu_ld2 = {
1295 - .base.static_constraint = C_NotImplemented,
1296 -};
1297 -
1298 -static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1299 - TCGReg base, MemOp opc)
1300 -{
1301 - switch (opc & MO_SIZE) {
1302 - case MO_8:
1303 - tcg_out_opc_imm(s, OPC_SB, lo, base, 0);
1304 - break;
1305 - case MO_16:
1306 - tcg_out_opc_imm(s, OPC_SH, lo, base, 0);
1307 - break;
1308 - case MO_32:
1309 - tcg_out_opc_imm(s, OPC_SW, lo, base, 0);
1310 - break;
1311 - case MO_64:
1312 - tcg_out_opc_imm(s, OPC_SD, lo, base, 0);
1313 - break;
1314 - default:
1315 - g_assert_not_reached();
1316 - }
1317 -}
1318 -
1319 -static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
1320 - TCGReg base, MemOp opc)
1321 -{
1322 - const MIPSInsn sw1 = HOST_BIG_ENDIAN ? OPC_SWL : OPC_SWR;
1323 - const MIPSInsn sw2 = HOST_BIG_ENDIAN ? OPC_SWR : OPC_SWL;
1324 - const MIPSInsn sd1 = HOST_BIG_ENDIAN ? OPC_SDL : OPC_SDR;
1325 - const MIPSInsn sd2 = HOST_BIG_ENDIAN ? OPC_SDR : OPC_SDL;
1326 -
1327 - switch (opc & MO_SIZE) {
1328 - case MO_16:
1329 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, lo, 8);
1330 - tcg_out_opc_imm(s, OPC_SB, HOST_BIG_ENDIAN ? TCG_TMP0 : lo, base, 0);
1331 - tcg_out_opc_imm(s, OPC_SB, HOST_BIG_ENDIAN ? lo : TCG_TMP0, base, 1);
1332 - break;
1333 -
1334 - case MO_32:
1335 - tcg_out_opc_imm(s, sw1, lo, base, 0);
1336 - tcg_out_opc_imm(s, sw2, lo, base, 3);
1337 - break;
1338 -
1339 - case MO_64:
1340 - tcg_out_opc_imm(s, sd1, lo, base, 0);
1341 - tcg_out_opc_imm(s, sd2, lo, base, 7);
1342 - break;
1343 -
1344 - default:
1345 - g_assert_not_reached();
1346 - }
1347 -}
1348 -
1349 -static void tgen_qemu_st(TCGContext *s, TCGType type, TCGReg data,
1350 - TCGReg addr, MemOpIdx oi)
1351 -{
1352 - MemOp opc = get_memop(oi);
1353 - TCGLabelQemuLdst *ldst;
1354 - HostAddress h;
1355 -
1356 - ldst = prepare_host_addr(s, &h, addr, oi, false);
1357 -
1358 - if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
1359 - tcg_out_qemu_st_direct(s, data, 0, h.base, opc);
1360 - } else {
1361 - tcg_out_qemu_st_unalign(s, data, 0, h.base, opc);
1362 - }
1363 -
1364 - if (ldst) {
1365 - ldst->type = type;
1366 - ldst->datalo_reg = data;
1367 - ldst->datahi_reg = 0;
1368 - ldst->raddr = tcg_splitwx_to_rx(s->code_ptr);
1369 - }
1370 -}
1371 -
1372 -static const TCGOutOpQemuLdSt outop_qemu_st = {
1373 - .base.static_constraint = C_O0_I2(rz, r),
1374 - .out = tgen_qemu_st,
1375 -};
1376 -
1377 -static const TCGOutOpQemuLdSt2 outop_qemu_st2 = {
1378 - .base.static_constraint = C_NotImplemented,
1379 -};
1380 -
1381 -static void tcg_out_mb(TCGContext *s, unsigned a0)
1382 -{
1383 - static const MIPSInsn sync[] = {
1384 - /* Note that SYNC_MB is a slightly weaker than SYNC 0,
1385 - as the former is an ordering barrier and the latter
1386 - is a completion barrier. */
1387 - [0 ... TCG_MO_ALL] = OPC_SYNC_MB,
1388 - [TCG_MO_LD_LD] = OPC_SYNC_RMB,
1389 - [TCG_MO_ST_ST] = OPC_SYNC_WMB,
1390 - [TCG_MO_LD_ST] = OPC_SYNC_RELEASE,
1391 - [TCG_MO_LD_ST | TCG_MO_ST_ST] = OPC_SYNC_RELEASE,
1392 - [TCG_MO_LD_ST | TCG_MO_LD_LD] = OPC_SYNC_ACQUIRE,
1393 - };
1394 - tcg_out32(s, sync[a0 & TCG_MO_ALL]);
1395 -}
1396 -
1397 -static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
1398 -{
1399 - TCGReg base = TCG_REG_ZERO;
1400 - int16_t lo = 0;
1401 -
1402 - if (a0) {
1403 - intptr_t ofs = tcg_tbrel_diff(s, (void *)a0);
1404 - lo = ofs;
1405 - if (ofs == lo) {
1406 - base = TCG_REG_TB;
1407 - } else {
1408 - base = TCG_REG_V0;
1409 - tcg_out_movi(s, TCG_TYPE_PTR, base, ofs - lo);
1410 - tcg_out_opc_reg(s, OPC_DADDU, base, base, TCG_REG_TB);
1411 - }
1412 - }
1413 - if (!tcg_out_opc_jmp(s, OPC_J, tb_ret_addr)) {
1414 - tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, (uintptr_t)tb_ret_addr);
1415 - tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1416 - }
1417 - /* delay slot */
1418 - tcg_out_opc_imm(s, OPC_DADDIU, TCG_REG_V0, base, lo);
1419 -}
1420 -
1421 -static void tcg_out_goto_tb(TCGContext *s, int which)
1422 -{
1423 - intptr_t ofs = get_jmp_target_addr(s, which);
1424 - TCGReg base, dest;
1425 -
1426 - /* indirect jump method */
1427 - dest = TCG_REG_TB;
1428 - base = TCG_REG_TB;
1429 - ofs = tcg_tbrel_diff(s, (void *)ofs);
1430 - tcg_out_ld(s, TCG_TYPE_PTR, dest, base, ofs);
1431 - tcg_out_opc_reg(s, OPC_JR, 0, dest, 0);
1432 - /* delay slot */
1433 - tcg_out_nop(s);
1434 -
1435 - set_jmp_reset_offset(s, which);
1436 - /* For the unlinked case, need to reset TCG_REG_TB. */
1437 - tcg_out_ldst(s, OPC_DADDIU, TCG_REG_TB, TCG_REG_TB,
1438 - -tcg_current_code_size(s));
1439 -}
1440 -
1441 -static void tcg_out_goto_ptr(TCGContext *s, TCGReg a0)
1442 -{
1443 - tcg_out_opc_reg(s, OPC_JR, 0, a0, 0);
1444 - tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, a0);
1445 -}
1446 -
1447 -void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
1448 - uintptr_t jmp_rx, uintptr_t jmp_rw)
1449 -{
1450 - /* Always indirect, nothing to do */
1451 -}
1452 -
1453 -
1454 -static void tgen_add(TCGContext *s, TCGType type,
1455 - TCGReg a0, TCGReg a1, TCGReg a2)
1456 -{
1457 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_ADDU : OPC_DADDU;
1458 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1459 -}
1460 -
1461 -static void tgen_addi(TCGContext *s, TCGType type,
1462 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1463 -{
1464 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_ADDIU : OPC_DADDIU;
1465 - tcg_out_opc_imm(s, insn, a0, a1, a2);
1466 -}
1467 -
1468 -static const TCGOutOpBinary outop_add = {
1469 - .base.static_constraint = C_O1_I2(r, r, rJ),
1470 - .out_rrr = tgen_add,
1471 - .out_rri = tgen_addi,
1472 -};
1473 -
1474 -static const TCGOutOpBinary outop_addco = {
1475 - .base.static_constraint = C_NotImplemented,
1476 -};
1477 -
1478 -static const TCGOutOpAddSubCarry outop_addci = {
1479 - .base.static_constraint = C_NotImplemented,
1480 -};
1481 -
1482 -static const TCGOutOpBinary outop_addcio = {
1483 - .base.static_constraint = C_NotImplemented,
1484 -};
1485 -
1486 -static void tcg_out_set_carry(TCGContext *s)
1487 -{
1488 - g_assert_not_reached();
1489 -}
1490 -
1491 -static void tgen_and(TCGContext *s, TCGType type,
1492 - TCGReg a0, TCGReg a1, TCGReg a2)
1493 -{
1494 - tcg_out_opc_reg(s, OPC_AND, a0, a1, a2);
1495 -}
1496 -
1497 -static void tgen_andi(TCGContext *s, TCGType type,
1498 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1499 -{
1500 - int msb;
1501 -
1502 - if (a2 == (uint16_t)a2) {
1503 - tcg_out_opc_imm(s, OPC_ANDI, a0, a1, a2);
1504 - return;
1505 - }
1506 -
1507 - tcg_debug_assert(use_mips32r2_instructions);
1508 - tcg_debug_assert(is_p2m1(a2));
1509 - msb = ctz64(~a2) - 1;
1510 - if (type == TCG_TYPE_I32) {
1511 - tcg_out_opc_bf(s, OPC_EXT, a0, a1, msb, 0);
1512 - } else {
1513 - tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU, a0, a1, msb, 0);
1514 - }
1515 -}
1516 -
1517 -static const TCGOutOpBinary outop_and = {
1518 - .base.static_constraint = C_O1_I2(r, r, rIK),
1519 - .out_rrr = tgen_and,
1520 - .out_rri = tgen_andi,
1521 -};
1522 -
1523 -static const TCGOutOpBinary outop_andc = {
1524 - .base.static_constraint = C_NotImplemented,
1525 -};
1526 -
1527 -static void tgen_clz(TCGContext *s, TCGType type,
1528 - TCGReg a0, TCGReg a1, TCGReg a2)
1529 -{
1530 - if (use_mips32r6_instructions) {
1531 - MIPSInsn opcv6 = type == TCG_TYPE_I32 ? OPC_CLZ_R6 : OPC_DCLZ_R6;
1532 - tcg_out_opc_reg(s, opcv6, TCG_TMP0, a1, 0);
1533 - tgen_movcond(s, TCG_TYPE_REG, TCG_COND_EQ, a0, a1, a2, false,
1534 - TCG_TMP0, false, TCG_REG_ZERO, false);
1535 - } else {
1536 - MIPSInsn opcv2 = type == TCG_TYPE_I32 ? OPC_CLZ : OPC_DCLZ;
1537 - if (a0 == a2) {
1538 - tcg_out_opc_reg(s, opcv2, TCG_TMP0, a1, a1);
1539 - tcg_out_opc_reg(s, OPC_MOVN, a0, TCG_TMP0, a1);
1540 - } else if (a0 != a1) {
1541 - tcg_out_opc_reg(s, opcv2, a0, a1, a1);
1542 - tcg_out_opc_reg(s, OPC_MOVZ, a0, a2, a1);
1543 - } else {
1544 - tcg_out_opc_reg(s, opcv2, TCG_TMP0, a1, a1);
1545 - tcg_out_opc_reg(s, OPC_MOVZ, TCG_TMP0, a2, a1);
1546 - tcg_out_mov(s, type, a0, TCG_TMP0);
1547 - }
1548 - }
1549 -}
1550 -
1551 -static void tgen_clzi(TCGContext *s, TCGType type,
1552 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1553 -{
1554 - if (a2 == 0) {
1555 - tgen_clz(s, type, a0, a1, TCG_REG_ZERO);
1556 - } else if (use_mips32r6_instructions) {
1557 - MIPSInsn opcv6 = type == TCG_TYPE_I32 ? OPC_CLZ_R6 : OPC_DCLZ_R6;
1558 - tcg_out_opc_reg(s, opcv6, a0, a1, 0);
1559 - } else {
1560 - MIPSInsn opcv2 = type == TCG_TYPE_I32 ? OPC_CLZ : OPC_DCLZ;
1561 - tcg_out_opc_reg(s, opcv2, a0, a1, a1);
1562 - }
1563 -}
1564 -
1565 -static TCGConstraintSetIndex cset_clz(TCGType type, unsigned flags)
1566 -{
1567 - return use_mips32r2_instructions ? C_O1_I2(r, r, rzW) : C_NotImplemented;
1568 -}
1569 -
1570 -static const TCGOutOpBinary outop_clz = {
1571 - .base.static_constraint = C_Dynamic,
1572 - .base.dynamic_constraint = cset_clz,
1573 - .out_rrr = tgen_clz,
1574 - .out_rri = tgen_clzi,
1575 -};
1576 -
1577 -static const TCGOutOpUnary outop_ctpop = {
1578 - .base.static_constraint = C_NotImplemented,
1579 -};
1580 -
1581 -static const TCGOutOpBinary outop_ctz = {
1582 - .base.static_constraint = C_NotImplemented,
1583 -};
1584 -
1585 -static void tgen_divs(TCGContext *s, TCGType type,
1586 - TCGReg a0, TCGReg a1, TCGReg a2)
1587 -{
1588 - if (use_mips32r6_instructions) {
1589 - if (type == TCG_TYPE_I32) {
1590 - tcg_out_opc_reg(s, OPC_DIV_R6, a0, a1, a2);
1591 - } else {
1592 - tcg_out_opc_reg(s, OPC_DDIV_R6, a0, a1, a2);
1593 - }
1594 - } else {
1595 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_DIV : OPC_DDIV;
1596 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1597 - tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1598 - }
1599 -}
1600 -
1601 -static const TCGOutOpBinary outop_divs = {
1602 - .base.static_constraint = C_O1_I2(r, r, r),
1603 - .out_rrr = tgen_divs,
1604 -};
1605 -
1606 -static const TCGOutOpDivRem outop_divs2 = {
1607 - .base.static_constraint = C_NotImplemented,
1608 -};
1609 -
1610 -static void tgen_divu(TCGContext *s, TCGType type,
1611 - TCGReg a0, TCGReg a1, TCGReg a2)
1612 -{
1613 - if (use_mips32r6_instructions) {
1614 - if (type == TCG_TYPE_I32) {
1615 - tcg_out_opc_reg(s, OPC_DIVU_R6, a0, a1, a2);
1616 - } else {
1617 - tcg_out_opc_reg(s, OPC_DDIVU_R6, a0, a1, a2);
1618 - }
1619 - } else {
1620 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_DIVU : OPC_DDIVU;
1621 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1622 - tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1623 - }
1624 -}
1625 -
1626 -static const TCGOutOpBinary outop_divu = {
1627 - .base.static_constraint = C_O1_I2(r, r, r),
1628 - .out_rrr = tgen_divu,
1629 -};
1630 -
1631 -static const TCGOutOpDivRem outop_divu2 = {
1632 - .base.static_constraint = C_NotImplemented,
1633 -};
1634 -
1635 -static const TCGOutOpBinary outop_eqv = {
1636 - .base.static_constraint = C_NotImplemented,
1637 -};
1638 -
1639 -static void tgen_extrh_i64_i32(TCGContext *s, TCGType t, TCGReg a0, TCGReg a1)
1640 -{
1641 - tcg_out_dsra(s, a0, a1, 32);
1642 -}
1643 -
1644 -static const TCGOutOpUnary outop_extrh_i64_i32 = {
1645 - .base.static_constraint = C_O1_I1(r, r),
1646 - .out_rr = tgen_extrh_i64_i32,
1647 -};
1648 -
1649 -static void tgen_mul(TCGContext *s, TCGType type,
1650 - TCGReg a0, TCGReg a1, TCGReg a2)
1651 -{
1652 - MIPSInsn insn;
1653 -
1654 - if (type == TCG_TYPE_I32) {
1655 - if (use_mips32_instructions) {
1656 - tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2);
1657 - return;
1658 - }
1659 - insn = OPC_MULT;
1660 - } else {
1661 - if (use_mips32r6_instructions) {
1662 - tcg_out_opc_reg(s, OPC_DMUL, a0, a1, a2);
1663 - return;
1664 - }
1665 - insn = OPC_DMULT;
1666 - }
1667 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1668 - tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1669 -}
1670 -
1671 -static const TCGOutOpBinary outop_mul = {
1672 - .base.static_constraint = C_O1_I2(r, r, r),
1673 - .out_rrr = tgen_mul,
1674 -};
1675 -
1676 -static void tgen_muls2(TCGContext *s, TCGType type,
1677 - TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3)
1678 -{
1679 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_MULT : OPC_DMULT;
1680 - tcg_out_opc_reg(s, insn, 0, a2, a3);
1681 - tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1682 - tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1683 -}
1684 -
1685 -static TCGConstraintSetIndex cset_mul2(TCGType type, unsigned flags)
1686 -{
1687 - return use_mips32r6_instructions ? C_NotImplemented : C_O2_I2(r, r, r, r);
1688 -}
1689 -
1690 -static const TCGOutOpMul2 outop_muls2 = {
1691 - .base.static_constraint = C_Dynamic,
1692 - .base.dynamic_constraint = cset_mul2,
1693 - .out_rrrr = tgen_muls2,
1694 -};
1695 -
1696 -static void tgen_mulsh(TCGContext *s, TCGType type,
1697 - TCGReg a0, TCGReg a1, TCGReg a2)
1698 -{
1699 - if (use_mips32r6_instructions) {
1700 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_MUH : OPC_DMUH;
1701 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1702 - } else {
1703 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_MULT : OPC_DMULT;
1704 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1705 - tcg_out_opc_reg(s, OPC_MFHI, a0, 0, 0);
1706 - }
1707 -}
1708 -
1709 -static const TCGOutOpBinary outop_mulsh = {
1710 - .base.static_constraint = C_O1_I2(r, r, r),
1711 - .out_rrr = tgen_mulsh,
1712 -};
1713 -
1714 -static void tgen_mulu2(TCGContext *s, TCGType type,
1715 - TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3)
1716 -{
1717 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_MULTU : OPC_DMULTU;
1718 - tcg_out_opc_reg(s, insn, 0, a2, a3);
1719 - tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1720 - tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1721 -}
1722 -
1723 -static const TCGOutOpMul2 outop_mulu2 = {
1724 - .base.static_constraint = C_Dynamic,
1725 - .base.dynamic_constraint = cset_mul2,
1726 - .out_rrrr = tgen_mulu2,
1727 -};
1728 -
1729 -static void tgen_muluh(TCGContext *s, TCGType type,
1730 - TCGReg a0, TCGReg a1, TCGReg a2)
1731 -{
1732 - if (use_mips32r6_instructions) {
1733 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_MUHU : OPC_DMUHU;
1734 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1735 - } else {
1736 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_MULTU : OPC_DMULTU;
1737 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1738 - tcg_out_opc_reg(s, OPC_MFHI, a0, 0, 0);
1739 - }
1740 -}
1741 -
1742 -static const TCGOutOpBinary outop_muluh = {
1743 - .base.static_constraint = C_O1_I2(r, r, r),
1744 - .out_rrr = tgen_muluh,
1745 -};
1746 -
1747 -static const TCGOutOpBinary outop_nand = {
1748 - .base.static_constraint = C_NotImplemented,
1749 -};
1750 -
1751 -static void tgen_nor(TCGContext *s, TCGType type,
1752 - TCGReg a0, TCGReg a1, TCGReg a2)
1753 -{
1754 - tcg_out_opc_reg(s, OPC_NOR, a0, a1, a2);
1755 -}
1756 -
1757 -static const TCGOutOpBinary outop_nor = {
1758 - .base.static_constraint = C_O1_I2(r, r, r),
1759 - .out_rrr = tgen_nor,
1760 -};
1761 -
1762 -static void tgen_or(TCGContext *s, TCGType type,
1763 - TCGReg a0, TCGReg a1, TCGReg a2)
1764 -{
1765 - tcg_out_opc_reg(s, OPC_OR, a0, a1, a2);
1766 -}
1767 -
1768 -static void tgen_ori(TCGContext *s, TCGType type,
1769 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1770 -{
1771 - tcg_out_opc_imm(s, OPC_ORI, a0, a1, a2);
1772 -}
1773 -
1774 -static const TCGOutOpBinary outop_or = {
1775 - .base.static_constraint = C_O1_I2(r, r, rI),
1776 - .out_rrr = tgen_or,
1777 - .out_rri = tgen_ori,
1778 -};
1779 -
1780 -static const TCGOutOpBinary outop_orc = {
1781 - .base.static_constraint = C_NotImplemented,
1782 -};
1783 -
1784 -static void tgen_rems(TCGContext *s, TCGType type,
1785 - TCGReg a0, TCGReg a1, TCGReg a2)
1786 -{
1787 - if (use_mips32r6_instructions) {
1788 - if (type == TCG_TYPE_I32) {
1789 - tcg_out_opc_reg(s, OPC_MOD, a0, a1, a2);
1790 - } else {
1791 - tcg_out_opc_reg(s, OPC_DMOD, a0, a1, a2);
1792 - }
1793 - } else {
1794 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_DIV : OPC_DDIV;
1795 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1796 - tcg_out_opc_reg(s, OPC_MFHI, a0, 0, 0);
1797 - }
1798 -}
1799 -
1800 -static const TCGOutOpBinary outop_rems = {
1801 - .base.static_constraint = C_O1_I2(r, r, r),
1802 - .out_rrr = tgen_rems,
1803 -};
1804 -
1805 -static void tgen_remu(TCGContext *s, TCGType type,
1806 - TCGReg a0, TCGReg a1, TCGReg a2)
1807 -{
1808 - if (use_mips32r6_instructions) {
1809 - if (type == TCG_TYPE_I32) {
1810 - tcg_out_opc_reg(s, OPC_MODU, a0, a1, a2);
1811 - } else {
1812 - tcg_out_opc_reg(s, OPC_DMODU, a0, a1, a2);
1813 - }
1814 - } else {
1815 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_DIVU : OPC_DDIVU;
1816 - tcg_out_opc_reg(s, insn, 0, a1, a2);
1817 - tcg_out_opc_reg(s, OPC_MFHI, a0, 0, 0);
1818 - }
1819 -}
1820 -
1821 -static const TCGOutOpBinary outop_remu = {
1822 - .base.static_constraint = C_O1_I2(r, r, r),
1823 - .out_rrr = tgen_remu,
1824 -};
1825 -
1826 -static const TCGOutOpBinary outop_rotl = {
1827 - .base.static_constraint = C_NotImplemented,
1828 -};
1829 -
1830 -static TCGConstraintSetIndex cset_rotr(TCGType type, unsigned flags)
1831 -{
1832 - return use_mips32r2_instructions ? C_O1_I2(r, r, ri) : C_NotImplemented;
1833 -}
1834 -
1835 -static void tgen_rotr(TCGContext *s, TCGType type,
1836 - TCGReg a0, TCGReg a1, TCGReg a2)
1837 -{
1838 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_ROTRV : OPC_DROTRV;
1839 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1840 -}
1841 -
1842 -static void tgen_rotri(TCGContext *s, TCGType type,
1843 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1844 -{
1845 - if (type == TCG_TYPE_I32) {
1846 - tcg_out_opc_sa(s, OPC_ROTR, a0, a1, a2);
1847 - } else {
1848 - tcg_out_opc_sa64(s, OPC_DROTR, OPC_DROTR32, a0, a1, a2);
1849 - }
1850 -}
1851 -
1852 -static const TCGOutOpBinary outop_rotr = {
1853 - .base.static_constraint = C_Dynamic,
1854 - .base.dynamic_constraint = cset_rotr,
1855 - .out_rrr = tgen_rotr,
1856 - .out_rri = tgen_rotri,
1857 -};
1858 -
1859 -static void tgen_sar(TCGContext *s, TCGType type,
1860 - TCGReg a0, TCGReg a1, TCGReg a2)
1861 -{
1862 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SRAV : OPC_DSRAV;
1863 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1864 -}
1865 -
1866 -static void tgen_sari(TCGContext *s, TCGType type,
1867 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1868 -{
1869 - if (type == TCG_TYPE_I32) {
1870 - tcg_out_opc_sa(s, OPC_SRA, a0, a1, a2);
1871 - } else {
1872 - tcg_out_dsra(s, a0, a1, a2);
1873 - }
1874 -}
1875 -
1876 -static const TCGOutOpBinary outop_sar = {
1877 - .base.static_constraint = C_O1_I2(r, r, ri),
1878 - .out_rrr = tgen_sar,
1879 - .out_rri = tgen_sari,
1880 -};
1881 -
1882 -static void tgen_shl(TCGContext *s, TCGType type,
1883 - TCGReg a0, TCGReg a1, TCGReg a2)
1884 -{
1885 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SLLV : OPC_DSLLV;
1886 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1887 -}
1888 -
1889 -static void tgen_shli(TCGContext *s, TCGType type,
1890 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1891 -{
1892 - if (type == TCG_TYPE_I32) {
1893 - tcg_out_opc_sa(s, OPC_SLL, a0, a1, a2);
1894 - } else {
1895 - tcg_out_dsll(s, a0, a1, a2);
1896 - }
1897 -}
1898 -
1899 -static const TCGOutOpBinary outop_shl = {
1900 - .base.static_constraint = C_O1_I2(r, r, ri),
1901 - .out_rrr = tgen_shl,
1902 - .out_rri = tgen_shli,
1903 -};
1904 -
1905 -static void tgen_shr(TCGContext *s, TCGType type,
1906 - TCGReg a0, TCGReg a1, TCGReg a2)
1907 -{
1908 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SRLV : OPC_DSRLV;
1909 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1910 -}
1911 -
1912 -static void tgen_shri(TCGContext *s, TCGType type,
1913 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1914 -{
1915 - if (type == TCG_TYPE_I32) {
1916 - tcg_out_opc_sa(s, OPC_SRL, a0, a1, a2);
1917 - } else {
1918 - tcg_out_dsrl(s, a0, a1, a2);
1919 - }
1920 -}
1921 -
1922 -static const TCGOutOpBinary outop_shr = {
1923 - .base.static_constraint = C_O1_I2(r, r, ri),
1924 - .out_rrr = tgen_shr,
1925 - .out_rri = tgen_shri,
1926 -};
1927 -
1928 -static void tgen_sub(TCGContext *s, TCGType type,
1929 - TCGReg a0, TCGReg a1, TCGReg a2)
1930 -{
1931 - MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SUBU : OPC_DSUBU;
1932 - tcg_out_opc_reg(s, insn, a0, a1, a2);
1933 -}
1934 -
1935 -static const TCGOutOpSubtract outop_sub = {
1936 - .base.static_constraint = C_O1_I2(r, r, r),
1937 - .out_rrr = tgen_sub,
1938 -};
1939 -
1940 -static const TCGOutOpAddSubCarry outop_subbo = {
1941 - .base.static_constraint = C_NotImplemented,
1942 -};
1943 -
1944 -static const TCGOutOpAddSubCarry outop_subbi = {
1945 - .base.static_constraint = C_NotImplemented,
1946 -};
1947 -
1948 -static const TCGOutOpAddSubCarry outop_subbio = {
1949 - .base.static_constraint = C_NotImplemented,
1950 -};
1951 -
1952 -static void tcg_out_set_borrow(TCGContext *s)
1953 -{
1954 - g_assert_not_reached();
1955 -}
1956 -
1957 -static void tgen_xor(TCGContext *s, TCGType type,
1958 - TCGReg a0, TCGReg a1, TCGReg a2)
1959 -{
1960 - tcg_out_opc_reg(s, OPC_XOR, a0, a1, a2);
1961 -}
1962 -
1963 -static void tgen_xori(TCGContext *s, TCGType type,
1964 - TCGReg a0, TCGReg a1, tcg_target_long a2)
1965 -{
1966 - tcg_out_opc_imm(s, OPC_XORI, a0, a1, a2);
1967 -}
1968 -
1969 -static const TCGOutOpBinary outop_xor = {
1970 - .base.static_constraint = C_O1_I2(r, r, rI),
1971 - .out_rrr = tgen_xor,
1972 - .out_rri = tgen_xori,
1973 -};
1974 -
1975 -static void tgen_bswap16(TCGContext *s, TCGType type,
1976 - TCGReg ret, TCGReg arg, unsigned flags)
1977 -{
1978 - /* With arg = abcd: */
1979 - if (use_mips32r2_instructions) {
1980 - tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); /* badc */
1981 - if (flags & TCG_BSWAP_OS) {
1982 - tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); /* ssdc */
1983 - } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
1984 - tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xffff); /* 00dc */
1985 - }
1986 - return;
1987 - }
1988 -
1989 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); /* 0abc */
1990 - if (!(flags & TCG_BSWAP_IZ)) {
1991 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0x00ff); /* 000c */
1992 - }
1993 - if (flags & TCG_BSWAP_OS) {
1994 - tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24); /* d000 */
1995 - tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16); /* ssd0 */
1996 - } else {
1997 - tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); /* bcd0 */
1998 - if (flags & TCG_BSWAP_OZ) {
1999 - tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); /* 00d0 */
2000 - }
2001 - }
2002 - tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); /* ssdc */
2003 -}
2004 -
2005 -static const TCGOutOpBswap outop_bswap16 = {
2006 - .base.static_constraint = C_O1_I1(r, r),
2007 - .out_rr = tgen_bswap16,
2008 -};
2009 -
2010 -static void tgen_bswap32(TCGContext *s, TCGType type,
2011 - TCGReg ret, TCGReg arg, unsigned flags)
2012 -{
2013 - if (use_mips32r2_instructions) {
2014 - tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
2015 - tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
2016 - if (flags & TCG_BSWAP_OZ) {
2017 - tcg_out_opc_bf(s, OPC_DEXT, ret, ret, 31, 0);
2018 - }
2019 - } else {
2020 - if (flags & TCG_BSWAP_OZ) {
2021 - tcg_out_bswap_subr(s, bswap32u_addr);
2022 - } else {
2023 - tcg_out_bswap_subr(s, bswap32_addr);
2024 - }
2025 - /* delay slot -- never omit the insn, like tcg_out_mov might. */
2026 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
2027 - tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
2028 - }
2029 -}
2030 -
2031 -static const TCGOutOpBswap outop_bswap32 = {
2032 - .base.static_constraint = C_O1_I1(r, r),
2033 - .out_rr = tgen_bswap32,
2034 -};
2035 -
2036 -static void tgen_bswap64(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
2037 -{
2038 - if (use_mips32r2_instructions) {
2039 - tcg_out_opc_reg(s, OPC_DSBH, ret, 0, arg);
2040 - tcg_out_opc_reg(s, OPC_DSHD, ret, 0, ret);
2041 - } else {
2042 - tcg_out_bswap_subr(s, bswap64_addr);
2043 - /* delay slot -- never omit the insn, like tcg_out_mov might. */
2044 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
2045 - tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
2046 - }
2047 -}
2048 -
2049 -static const TCGOutOpUnary outop_bswap64 = {
2050 - .base.static_constraint = C_O1_I1(r, r),
2051 - .out_rr = tgen_bswap64,
2052 -};
2053 -
2054 -static void tgen_neg(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
2055 -{
2056 - tgen_sub(s, type, a0, TCG_REG_ZERO, a1);
2057 -}
2058 -
2059 -static const TCGOutOpUnary outop_neg = {
2060 - .base.static_constraint = C_O1_I1(r, r),
2061 - .out_rr = tgen_neg,
2062 -};
2063 -
2064 -static void tgen_not(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
2065 -{
2066 - tgen_nor(s, type, a0, TCG_REG_ZERO, a1);
2067 -}
2068 -
2069 -static const TCGOutOpUnary outop_not = {
2070 - .base.static_constraint = C_O1_I1(r, r),
2071 - .out_rr = tgen_not,
2072 -};
2073 -
2074 -static void tgen_deposit(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
2075 - TCGReg a2, unsigned ofs, unsigned len)
2076 -{
2077 - if (type == TCG_TYPE_I32) {
2078 - tcg_out_opc_bf(s, OPC_INS, a0, a2, ofs + len - 1, ofs);
2079 - } else {
2080 - tcg_out_opc_bf64(s, OPC_DINS, OPC_DINSM, OPC_DINSU, a0, a2,
2081 - ofs + len - 1, ofs);
2082 - }
2083 -}
2084 -
2085 -static const TCGOutOpDeposit outop_deposit = {
2086 - .base.static_constraint = C_O1_I2(r, 0, rz),
2087 - .out_rrr = tgen_deposit,
2088 -};
2089 -
2090 -static void tgen_extract(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
2091 - unsigned ofs, unsigned len)
2092 -{
2093 - if (ofs == 0 && len <= 16) {
2094 - tcg_out_opc_imm(s, OPC_ANDI, a0, a1, (1 << len) - 1);
2095 - } else if (type == TCG_TYPE_I32) {
2096 - tcg_out_opc_bf(s, OPC_EXT, a0, a1, len - 1, ofs);
2097 - } else {
2098 - tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU,
2099 - a0, a1, len - 1, ofs);
2100 - }
2101 -}
2102 -
2103 -static const TCGOutOpExtract outop_extract = {
2104 - .base.static_constraint = C_O1_I1(r, r),
2105 - .out_rr = tgen_extract,
2106 -};
2107 -
2108 -static void tgen_sextract(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
2109 - unsigned ofs, unsigned len)
2110 -{
2111 - if (ofs == 0) {
2112 - switch (len) {
2113 - case 8:
2114 - tcg_out_ext8s(s, type, a0, a1);
2115 - return;
2116 - case 16:
2117 - tcg_out_ext16s(s, type, a0, a1);
2118 - return;
2119 - case 32:
2120 - tcg_out_ext32s(s, a0, a1);
2121 - return;
2122 - }
2123 - }
2124 - g_assert_not_reached();
2125 -}
2126 -
2127 -static const TCGOutOpExtract outop_sextract = {
2128 - .base.static_constraint = C_O1_I1(r, r),
2129 - .out_rr = tgen_sextract,
2130 -};
2131 -
2132 -static const TCGOutOpExtract2 outop_extract2 = {
2133 - .base.static_constraint = C_NotImplemented,
2134 -};
2135 -
2136 -static void tgen_ld8u(TCGContext *s, TCGType type, TCGReg dest,
2137 - TCGReg base, ptrdiff_t offset)
2138 -{
2139 - tcg_out_ldst(s, OPC_LBU, dest, base, offset);
2140 -}
2141 -
2142 -static const TCGOutOpLoad outop_ld8u = {
2143 - .base.static_constraint = C_O1_I1(r, r),
2144 - .out = tgen_ld8u,
2145 -};
2146 -
2147 -static void tgen_ld8s(TCGContext *s, TCGType type, TCGReg dest,
2148 - TCGReg base, ptrdiff_t offset)
2149 -{
2150 - tcg_out_ldst(s, OPC_LB, dest, base, offset);
2151 -}
2152 -
2153 -static const TCGOutOpLoad outop_ld8s = {
2154 - .base.static_constraint = C_O1_I1(r, r),
2155 - .out = tgen_ld8s,
2156 -};
2157 -
2158 -static void tgen_ld16u(TCGContext *s, TCGType type, TCGReg dest,
2159 - TCGReg base, ptrdiff_t offset)
2160 -{
2161 - tcg_out_ldst(s, OPC_LHU, dest, base, offset);
2162 -}
2163 -
2164 -static const TCGOutOpLoad outop_ld16u = {
2165 - .base.static_constraint = C_O1_I1(r, r),
2166 - .out = tgen_ld16u,
2167 -};
2168 -
2169 -static void tgen_ld16s(TCGContext *s, TCGType type, TCGReg dest,
2170 - TCGReg base, ptrdiff_t offset)
2171 -{
2172 - tcg_out_ldst(s, OPC_LH, dest, base, offset);
2173 -}
2174 -
2175 -static const TCGOutOpLoad outop_ld16s = {
2176 - .base.static_constraint = C_O1_I1(r, r),
2177 - .out = tgen_ld16s,
2178 -};
2179 -
2180 -static void tgen_ld32u(TCGContext *s, TCGType type, TCGReg dest,
2181 - TCGReg base, ptrdiff_t offset)
2182 -{
2183 - tcg_out_ldst(s, OPC_LWU, dest, base, offset);
2184 -}
2185 -
2186 -static const TCGOutOpLoad outop_ld32u = {
2187 - .base.static_constraint = C_O1_I1(r, r),
2188 - .out = tgen_ld32u,
2189 -};
2190 -
2191 -static void tgen_ld32s(TCGContext *s, TCGType type, TCGReg dest,
2192 - TCGReg base, ptrdiff_t offset)
2193 -{
2194 - tcg_out_ldst(s, OPC_LW, dest, base, offset);
2195 -}
2196 -
2197 -static const TCGOutOpLoad outop_ld32s = {
2198 - .base.static_constraint = C_O1_I1(r, r),
2199 - .out = tgen_ld32s,
2200 -};
2201 -
2202 -static void tgen_st8_r(TCGContext *s, TCGType type, TCGReg data,
2203 - TCGReg base, ptrdiff_t offset)
2204 -{
2205 - tcg_out_ldst(s, OPC_SB, data, base, offset);
2206 -}
2207 -
2208 -static const TCGOutOpStore outop_st8 = {
2209 - .base.static_constraint = C_O0_I2(rz, r),
2210 - .out_r = tgen_st8_r,
2211 -};
2212 -
2213 -static void tgen_st16_r(TCGContext *s, TCGType type, TCGReg data,
2214 - TCGReg base, ptrdiff_t offset)
2215 -{
2216 - tcg_out_ldst(s, OPC_SH, data, base, offset);
2217 -}
2218 -
2219 -static const TCGOutOpStore outop_st16 = {
2220 - .base.static_constraint = C_O0_I2(rz, r),
2221 - .out_r = tgen_st16_r,
2222 -};
2223 -
2224 -static const TCGOutOpStore outop_st = {
2225 - .base.static_constraint = C_O0_I2(rz, r),
2226 - .out_r = tcg_out_st,
2227 -};
2228 -
2229 -
2230 -static TCGConstraintSetIndex
2231 -tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
2232 -{
2233 - return C_NotImplemented;
2234 -}
2235 -
2236 -static const int tcg_target_callee_save_regs[] = {
2237 - TCG_REG_S0,
2238 - TCG_REG_S1,
2239 - TCG_REG_S2,
2240 - TCG_REG_S3,
2241 - TCG_REG_S4,
2242 - TCG_REG_S5,
2243 - TCG_REG_S6, /* used for the tb base (TCG_REG_TB) */
2244 - TCG_REG_S7, /* used for guest_base */
2245 - TCG_REG_S8, /* used for the global env (TCG_AREG0) */
2246 - TCG_REG_RA, /* should be last for ABI compliance */
2247 -};
2248 -
2249 -/* The Linux kernel doesn't provide any information about the available
2250 - instruction set. Probe it using a signal handler. */
2251 -
2252 -
2253 -#ifndef use_movnz_instructions
2254 -bool use_movnz_instructions = false;
2255 -#endif
2256 -
2257 -#ifndef use_mips32_instructions
2258 -bool use_mips32_instructions = false;
2259 -#endif
2260 -
2261 -#ifndef use_mips32r2_instructions
2262 -bool use_mips32r2_instructions = false;
2263 -#endif
2264 -
2265 -static volatile sig_atomic_t got_sigill;
2266 -
2267 -static void sigill_handler(int signo, siginfo_t *si, void *data)
2268 -{
2269 - /* Skip the faulty instruction */
2270 - ucontext_t *uc = (ucontext_t *)data;
2271 - uc->uc_mcontext.pc += 4;
2272 -
2273 - got_sigill = 1;
2274 -}
2275 -
2276 -static void tcg_target_detect_isa(void)
2277 -{
2278 - struct sigaction sa_old, sa_new;
2279 -
2280 - memset(&sa_new, 0, sizeof(sa_new));
2281 - sa_new.sa_flags = SA_SIGINFO;
2282 - sa_new.sa_sigaction = sigill_handler;
2283 - sigaction(SIGILL, &sa_new, &sa_old);
2284 -
2285 - /* Probe for movn/movz, necessary to implement movcond. */
2286 -#ifndef use_movnz_instructions
2287 - got_sigill = 0;
2288 - asm volatile(".set push\n"
2289 - ".set mips32\n"
2290 - "movn $zero, $zero, $zero\n"
2291 - "movz $zero, $zero, $zero\n"
2292 - ".set pop\n"
2293 - : : : );
2294 - use_movnz_instructions = !got_sigill;
2295 -#endif
2296 -
2297 - /* Probe for MIPS32 instructions. As no subsetting is allowed
2298 - by the specification, it is only necessary to probe for one
2299 - of the instructions. */
2300 -#ifndef use_mips32_instructions
2301 - got_sigill = 0;
2302 - asm volatile(".set push\n"
2303 - ".set mips32\n"
2304 - "mul $zero, $zero\n"
2305 - ".set pop\n"
2306 - : : : );
2307 - use_mips32_instructions = !got_sigill;
2308 -#endif
2309 -
2310 - /* Probe for MIPS32r2 instructions if MIPS32 instructions are
2311 - available. As no subsetting is allowed by the specification,
2312 - it is only necessary to probe for one of the instructions. */
2313 -#ifndef use_mips32r2_instructions
2314 - if (use_mips32_instructions) {
2315 - got_sigill = 0;
2316 - asm volatile(".set push\n"
2317 - ".set mips32r2\n"
2318 - "seb $zero, $zero\n"
2319 - ".set pop\n"
2320 - : : : );
2321 - use_mips32r2_instructions = !got_sigill;
2322 - }
2323 -#endif
2324 -
2325 - sigaction(SIGILL, &sa_old, NULL);
2326 -}
2327 -
2328 -static tcg_insn_unit *align_code_ptr(TCGContext *s)
2329 -{
2330 - uintptr_t p = (uintptr_t)s->code_ptr;
2331 - if (p & 15) {
2332 - p = (p + 15) & -16;
2333 - s->code_ptr = (void *)p;
2334 - }
2335 - return s->code_ptr;
2336 -}
2337 -
2338 -/* Stack frame parameters. */
2339 -#define REG_SIZE 8
2340 -#define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
2341 -#define TEMP_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
2342 -
2343 -#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
2344 - + TCG_TARGET_STACK_ALIGN - 1) \
2345 - & -TCG_TARGET_STACK_ALIGN)
2346 -#define SAVE_OFS (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
2347 -
2348 -/* We're expecting to be able to use an immediate for frame allocation. */
2349 -QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7fff);
2350 -
2351 -/* Generate global QEMU prologue and epilogue code */
2352 -static void tcg_target_qemu_prologue(TCGContext *s)
2353 -{
2354 - int i;
2355 -
2356 - tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
2357 -
2358 - /* TB prologue */
2359 - tcg_out_opc_imm(s, OPC_DADDIU, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
2360 - for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2361 - tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2362 - TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
2363 - }
2364 -
2365 - if (!tcg_use_softmmu && guest_base != (int16_t)guest_base) {
2366 - /*
2367 - * The function call abi for n32 and n64 will have loaded $25 (t9)
2368 - * with the address of the prologue, so we can use that instead
2369 - * of TCG_REG_TB.
2370 - */
2371 -#if !defined(__mips_abicalls)
2372 -# error "Unknown mips abi"
2373 -#endif
2374 - tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base,
2375 - TCG_REG_T9);
2376 - tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2377 - }
2378 -
2379 - tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, tcg_target_call_iarg_regs[1]);
2380 -
2381 - /* Call generated code */
2382 - tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
2383 - /* delay slot */
2384 - tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2385 -
2386 - /*
2387 - * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2388 - * and fall through to the rest of the epilogue.
2389 - */
2390 - tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2391 - tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_V0, TCG_REG_ZERO);
2392 -
2393 - /* TB epilogue */
2394 - tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
2395 - for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2396 - tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2397 - TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
2398 - }
2399 -
2400 - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2401 - /* delay slot */
2402 - tcg_out_opc_imm(s, OPC_DADDIU, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
2403 -
2404 - if (use_mips32r2_instructions) {
2405 - return;
2406 - }
2407 -
2408 - /* Bswap subroutines: Input in TCG_TMP0, output in TCG_TMP3;
2409 - clobbers TCG_TMP1, TCG_TMP2. */
2410 -
2411 - /*
2412 - * bswap32 -- 32-bit swap (signed result for mips64). a0 = abcd.
2413 - */
2414 - bswap32_addr = tcg_splitwx_to_rx(align_code_ptr(s));
2415 - /* t3 = (ssss)d000 */
2416 - tcg_out_opc_sa(s, OPC_SLL, TCG_TMP3, TCG_TMP0, 24);
2417 - /* t1 = 000a */
2418 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 24);
2419 - /* t2 = 00c0 */
2420 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2421 - /* t3 = d00a */
2422 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2423 - /* t1 = 0abc */
2424 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
2425 - /* t2 = 0c00 */
2426 - tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
2427 - /* t1 = 00b0 */
2428 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2429 - /* t3 = dc0a */
2430 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2431 - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2432 - /* t3 = dcba -- delay slot */
2433 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2434 -
2435 - /*
2436 - * bswap32u -- unsigned 32-bit swap. a0 = ....abcd.
2437 - */
2438 - bswap32u_addr = tcg_splitwx_to_rx(align_code_ptr(s));
2439 - /* t1 = (0000)000d */
2440 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP0, 0xff);
2441 - /* t3 = 000a */
2442 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, TCG_TMP0, 24);
2443 - /* t1 = (0000)d000 */
2444 - tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 24);
2445 - /* t2 = 00c0 */
2446 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2447 - /* t3 = d00a */
2448 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2449 - /* t1 = 0abc */
2450 - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
2451 - /* t2 = 0c00 */
2452 - tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
2453 - /* t1 = 00b0 */
2454 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2455 - /* t3 = dc0a */
2456 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2457 - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2458 - /* t3 = dcba -- delay slot */
2459 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2460 -
2461 - /*
2462 - * bswap64 -- 64-bit swap. a0 = abcdefgh
2463 - */
2464 - bswap64_addr = tcg_splitwx_to_rx(align_code_ptr(s));
2465 - /* t3 = h0000000 */
2466 - tcg_out_dsll(s, TCG_TMP3, TCG_TMP0, 56);
2467 - /* t1 = 0000000a */
2468 - tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 56);
2469 -
2470 - /* t2 = 000000g0 */
2471 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2472 - /* t3 = h000000a */
2473 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2474 - /* t1 = 00000abc */
2475 - tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 40);
2476 - /* t2 = 0g000000 */
2477 - tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 40);
2478 - /* t1 = 000000b0 */
2479 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2480 -
2481 - /* t3 = hg00000a */
2482 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2483 - /* t2 = 0000abcd */
2484 - tcg_out_dsrl(s, TCG_TMP2, TCG_TMP0, 32);
2485 - /* t3 = hg0000ba */
2486 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2487 -
2488 - /* t1 = 000000c0 */
2489 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP2, 0xff00);
2490 - /* t2 = 0000000d */
2491 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP2, 0x00ff);
2492 - /* t1 = 00000c00 */
2493 - tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 8);
2494 - /* t2 = 0000d000 */
2495 - tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 24);
2496 -
2497 - /* t3 = hg000cba */
2498 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2499 - /* t1 = 00abcdef */
2500 - tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 16);
2501 - /* t3 = hg00dcba */
2502 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2503 -
2504 - /* t2 = 0000000f */
2505 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP1, 0x00ff);
2506 - /* t1 = 000000e0 */
2507 - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2508 - /* t2 = 00f00000 */
2509 - tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 40);
2510 - /* t1 = 000e0000 */
2511 - tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 24);
2512 -
2513 - /* t3 = hgf0dcba */
2514 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2515 - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2516 - /* t3 = hgfedcba -- delay slot */
2517 - tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2518 -}
2519 -
2520 -static void tcg_out_tb_start(TCGContext *s)
2521 -{
2522 - /* nothing to do */
2523 -}
2524 -
2525 -static void tcg_target_init(TCGContext *s)
2526 -{
2527 - tcg_target_detect_isa();
2528 - tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
2529 - tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
2530 -
2531 - tcg_target_call_clobber_regs = 0;
2532 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0);
2533 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1);
2534 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A0);
2535 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A1);
2536 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A2);
2537 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A3);
2538 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T0);
2539 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T1);
2540 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T2);
2541 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T3);
2542 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T4);
2543 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T5);
2544 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T6);
2545 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T7);
2546 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T8);
2547 - tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T9);
2548 -
2549 - s->reserved_regs = 0;
2550 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
2551 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0); /* kernel use only */
2552 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */
2553 - tcg_regset_set_reg(s->reserved_regs, TCG_TMP0); /* internal use */
2554 - tcg_regset_set_reg(s->reserved_regs, TCG_TMP1); /* internal use */
2555 - tcg_regset_set_reg(s->reserved_regs, TCG_TMP2); /* internal use */
2556 - tcg_regset_set_reg(s->reserved_regs, TCG_TMP3); /* internal use */
2557 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return address */
2558 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
2559 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
2560 - tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB); /* tc->tc_ptr */
2561 -}
2562 -
2563 -typedef struct {
2564 - DebugFrameHeader h;
2565 - uint8_t fde_def_cfa[4];
2566 - uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
2567 -} DebugFrame;
2568 -
2569 -#define ELF_HOST_MACHINE EM_MIPS
2570 -/* GDB doesn't appear to require proper setting of ELF_HOST_FLAGS,
2571 - which is good because they're really quite complicated for MIPS. */
2572 -
2573 -static const DebugFrame debug_frame = {
2574 - .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
2575 - .h.cie.id = -1,
2576 - .h.cie.version = 1,
2577 - .h.cie.code_align = 1,
2578 - .h.cie.data_align = -REG_SIZE & 0x7f, /* sleb128 */
2579 - .h.cie.return_column = TCG_REG_RA,
2580 -
2581 - /* Total FDE size does not include the "len" member. */
2582 - .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2583 -
2584 - .fde_def_cfa = {
2585 - 12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */
2586 - (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2587 - (FRAME_SIZE >> 7)
2588 - },
2589 - .fde_reg_ofs = {
2590 - 0x80 + 16, 9, /* DW_CFA_offset, s0, -72 */
2591 - 0x80 + 17, 8, /* DW_CFA_offset, s2, -64 */
2592 - 0x80 + 18, 7, /* DW_CFA_offset, s3, -56 */
2593 - 0x80 + 19, 6, /* DW_CFA_offset, s4, -48 */
2594 - 0x80 + 20, 5, /* DW_CFA_offset, s5, -40 */
2595 - 0x80 + 21, 4, /* DW_CFA_offset, s6, -32 */
2596 - 0x80 + 22, 3, /* DW_CFA_offset, s7, -24 */
2597 - 0x80 + 30, 2, /* DW_CFA_offset, s8, -16 */
2598 - 0x80 + 31, 1, /* DW_CFA_offset, ra, -8 */
2599 - }
2600 -};
2601 -
2602 -void tcg_register_jit(const void *buf, size_t buf_size)
2603 -{
2604 - tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2605 -}
tcg/mips64/tcg-target.h deleted
-75
@@ -1,75 +0,0 @@
1 -/*
2 - * Tiny Code Generator for QEMU
3 - *
4 - * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5 - * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6 - * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
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 -#ifndef MIPS_TCG_TARGET_H
28 -#define MIPS_TCG_TARGET_H
29 -
30 -#define TCG_TARGET_INSN_UNIT_SIZE 4
31 -#define TCG_TARGET_NB_REGS 32
32 -
33 -#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
34 -
35 -typedef enum {
36 - TCG_REG_ZERO = 0,
37 - TCG_REG_AT,
38 - TCG_REG_V0,
39 - TCG_REG_V1,
40 - TCG_REG_A0,
41 - TCG_REG_A1,
42 - TCG_REG_A2,
43 - TCG_REG_A3,
44 - TCG_REG_T0,
45 - TCG_REG_T1,
46 - TCG_REG_T2,
47 - TCG_REG_T3,
48 - TCG_REG_T4,
49 - TCG_REG_T5,
50 - TCG_REG_T6,
51 - TCG_REG_T7,
52 - TCG_REG_S0,
53 - TCG_REG_S1,
54 - TCG_REG_S2,
55 - TCG_REG_S3,
56 - TCG_REG_S4,
57 - TCG_REG_S5,
58 - TCG_REG_S6,
59 - TCG_REG_S7,
60 - TCG_REG_T8,
61 - TCG_REG_T9,
62 - TCG_REG_K0,
63 - TCG_REG_K1,
64 - TCG_REG_GP,
65 - TCG_REG_SP,
66 - TCG_REG_S8,
67 - TCG_REG_RA,
68 -
69 - TCG_REG_CALL_STACK = TCG_REG_SP,
70 - TCG_AREG0 = TCG_REG_S8,
71 -} TCGReg;
72 -
73 -#define TCG_REG_ZERO TCG_REG_ZERO
74 -
75 -#endif