Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 2ace7e55

History | View | Annotate | Download (102.6 kB)

1 4c9649a9 j_mayer
/*
2 4c9649a9 j_mayer
 *  Alpha emulation cpu translation for qemu.
3 5fafdf24 ths
 *
4 4c9649a9 j_mayer
 *  Copyright (c) 2007 Jocelyn Mayer
5 4c9649a9 j_mayer
 *
6 4c9649a9 j_mayer
 * This library is free software; you can redistribute it and/or
7 4c9649a9 j_mayer
 * modify it under the terms of the GNU Lesser General Public
8 4c9649a9 j_mayer
 * License as published by the Free Software Foundation; either
9 4c9649a9 j_mayer
 * version 2 of the License, or (at your option) any later version.
10 4c9649a9 j_mayer
 *
11 4c9649a9 j_mayer
 * This library is distributed in the hope that it will be useful,
12 4c9649a9 j_mayer
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 4c9649a9 j_mayer
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 4c9649a9 j_mayer
 * Lesser General Public License for more details.
15 4c9649a9 j_mayer
 *
16 4c9649a9 j_mayer
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 4c9649a9 j_mayer
 */
19 4c9649a9 j_mayer
20 4c9649a9 j_mayer
#include <stdint.h>
21 4c9649a9 j_mayer
#include <stdlib.h>
22 4c9649a9 j_mayer
#include <stdio.h>
23 4c9649a9 j_mayer
24 4c9649a9 j_mayer
#include "cpu.h"
25 4c9649a9 j_mayer
#include "exec-all.h"
26 4c9649a9 j_mayer
#include "disas.h"
27 ae8ecd42 aurel32
#include "host-utils.h"
28 57fec1fe bellard
#include "tcg-op.h"
29 ca10f867 aurel32
#include "qemu-common.h"
30 4c9649a9 j_mayer
31 a7812ae4 pbrook
#include "helper.h"
32 a7812ae4 pbrook
#define GEN_HELPER 1
33 a7812ae4 pbrook
#include "helper.h"
34 a7812ae4 pbrook
35 19188121 Richard Henderson
#undef ALPHA_DEBUG_DISAS
36 f24518b5 Richard Henderson
#define CONFIG_SOFTFLOAT_INLINE
37 d12d51d5 aliguori
38 d12d51d5 aliguori
#ifdef ALPHA_DEBUG_DISAS
39 806991da Richard Henderson
#  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
40 d12d51d5 aliguori
#else
41 d12d51d5 aliguori
#  define LOG_DISAS(...) do { } while (0)
42 d12d51d5 aliguori
#endif
43 d12d51d5 aliguori
44 4c9649a9 j_mayer
typedef struct DisasContext DisasContext;
45 4c9649a9 j_mayer
struct DisasContext {
46 4af70374 Richard Henderson
    struct TranslationBlock *tb;
47 4af70374 Richard Henderson
    CPUAlphaState *env;
48 4c9649a9 j_mayer
    uint64_t pc;
49 4c9649a9 j_mayer
    int mem_idx;
50 f24518b5 Richard Henderson
51 f24518b5 Richard Henderson
    /* Current rounding mode for this TB.  */
52 f24518b5 Richard Henderson
    int tb_rm;
53 f24518b5 Richard Henderson
    /* Current flush-to-zero setting for this TB.  */
54 f24518b5 Richard Henderson
    int tb_ftz;
55 4c9649a9 j_mayer
};
56 4c9649a9 j_mayer
57 4af70374 Richard Henderson
/* Return values from translate_one, indicating the state of the TB.
58 4af70374 Richard Henderson
   Note that zero indicates that we are not exiting the TB.  */
59 4af70374 Richard Henderson
60 4af70374 Richard Henderson
typedef enum {
61 4af70374 Richard Henderson
    NO_EXIT,
62 4af70374 Richard Henderson
63 4af70374 Richard Henderson
    /* We have emitted one or more goto_tb.  No fixup required.  */
64 4af70374 Richard Henderson
    EXIT_GOTO_TB,
65 4af70374 Richard Henderson
66 4af70374 Richard Henderson
    /* We are not using a goto_tb (for whatever reason), but have updated
67 4af70374 Richard Henderson
       the PC (for whatever reason), so there's no need to do it again on
68 4af70374 Richard Henderson
       exiting the TB.  */
69 4af70374 Richard Henderson
    EXIT_PC_UPDATED,
70 4af70374 Richard Henderson
71 4af70374 Richard Henderson
    /* We are exiting the TB, but have neither emitted a goto_tb, nor
72 4af70374 Richard Henderson
       updated the PC for the next instruction to be executed.  */
73 8aa3fa20 Richard Henderson
    EXIT_PC_STALE,
74 8aa3fa20 Richard Henderson
75 8aa3fa20 Richard Henderson
    /* We are ending the TB with a noreturn function call, e.g. longjmp.
76 8aa3fa20 Richard Henderson
       No following code will be executed.  */
77 8aa3fa20 Richard Henderson
    EXIT_NORETURN,
78 4af70374 Richard Henderson
} ExitStatus;
79 4af70374 Richard Henderson
80 3761035f aurel32
/* global register indexes */
81 a7812ae4 pbrook
static TCGv_ptr cpu_env;
82 496cb5b9 aurel32
static TCGv cpu_ir[31];
83 f18cd223 aurel32
static TCGv cpu_fir[31];
84 496cb5b9 aurel32
static TCGv cpu_pc;
85 6910b8f6 Richard Henderson
static TCGv cpu_lock_addr;
86 6910b8f6 Richard Henderson
static TCGv cpu_lock_st_addr;
87 6910b8f6 Richard Henderson
static TCGv cpu_lock_value;
88 2ace7e55 Richard Henderson
static TCGv cpu_unique;
89 2ace7e55 Richard Henderson
#ifndef CONFIG_USER_ONLY
90 2ace7e55 Richard Henderson
static TCGv cpu_sysval;
91 2ace7e55 Richard Henderson
static TCGv cpu_usp;
92 ab471ade Richard Henderson
#endif
93 496cb5b9 aurel32
94 3761035f aurel32
/* register names */
95 f18cd223 aurel32
static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
96 2e70f6ef pbrook
97 2e70f6ef pbrook
#include "gen-icount.h"
98 2e70f6ef pbrook
99 a5f1b965 blueswir1
static void alpha_translate_init(void)
100 2e70f6ef pbrook
{
101 496cb5b9 aurel32
    int i;
102 496cb5b9 aurel32
    char *p;
103 2e70f6ef pbrook
    static int done_init = 0;
104 496cb5b9 aurel32
105 2e70f6ef pbrook
    if (done_init)
106 2e70f6ef pbrook
        return;
107 496cb5b9 aurel32
108 a7812ae4 pbrook
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
109 496cb5b9 aurel32
110 496cb5b9 aurel32
    p = cpu_reg_names;
111 496cb5b9 aurel32
    for (i = 0; i < 31; i++) {
112 496cb5b9 aurel32
        sprintf(p, "ir%d", i);
113 a7812ae4 pbrook
        cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
114 a7812ae4 pbrook
                                           offsetof(CPUState, ir[i]), p);
115 6ba8dcd7 aurel32
        p += (i < 10) ? 4 : 5;
116 f18cd223 aurel32
117 f18cd223 aurel32
        sprintf(p, "fir%d", i);
118 a7812ae4 pbrook
        cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
119 a7812ae4 pbrook
                                            offsetof(CPUState, fir[i]), p);
120 f18cd223 aurel32
        p += (i < 10) ? 5 : 6;
121 496cb5b9 aurel32
    }
122 496cb5b9 aurel32
123 a7812ae4 pbrook
    cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
124 a7812ae4 pbrook
                                    offsetof(CPUState, pc), "pc");
125 496cb5b9 aurel32
126 6910b8f6 Richard Henderson
    cpu_lock_addr = tcg_global_mem_new_i64(TCG_AREG0,
127 6910b8f6 Richard Henderson
                                           offsetof(CPUState, lock_addr),
128 6910b8f6 Richard Henderson
                                           "lock_addr");
129 6910b8f6 Richard Henderson
    cpu_lock_st_addr = tcg_global_mem_new_i64(TCG_AREG0,
130 6910b8f6 Richard Henderson
                                              offsetof(CPUState, lock_st_addr),
131 6910b8f6 Richard Henderson
                                              "lock_st_addr");
132 6910b8f6 Richard Henderson
    cpu_lock_value = tcg_global_mem_new_i64(TCG_AREG0,
133 6910b8f6 Richard Henderson
                                            offsetof(CPUState, lock_value),
134 6910b8f6 Richard Henderson
                                            "lock_value");
135 f4ed8679 aurel32
136 2ace7e55 Richard Henderson
    cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
137 2ace7e55 Richard Henderson
                                        offsetof(CPUState, unique), "unique");
138 2ace7e55 Richard Henderson
#ifndef CONFIG_USER_ONLY
139 2ace7e55 Richard Henderson
    cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
140 2ace7e55 Richard Henderson
                                        offsetof(CPUState, sysval), "sysval");
141 2ace7e55 Richard Henderson
    cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
142 2ace7e55 Richard Henderson
                                     offsetof(CPUState, usp), "usp");
143 ab471ade Richard Henderson
#endif
144 ab471ade Richard Henderson
145 496cb5b9 aurel32
    /* register helpers */
146 a7812ae4 pbrook
#define GEN_HELPER 2
147 496cb5b9 aurel32
#include "helper.h"
148 496cb5b9 aurel32
149 2e70f6ef pbrook
    done_init = 1;
150 2e70f6ef pbrook
}
151 2e70f6ef pbrook
152 bf1b03fe Richard Henderson
static void gen_excp_1(int exception, int error_code)
153 4c9649a9 j_mayer
{
154 a7812ae4 pbrook
    TCGv_i32 tmp1, tmp2;
155 6ad02592 aurel32
156 6ad02592 aurel32
    tmp1 = tcg_const_i32(exception);
157 6ad02592 aurel32
    tmp2 = tcg_const_i32(error_code);
158 a7812ae4 pbrook
    gen_helper_excp(tmp1, tmp2);
159 a7812ae4 pbrook
    tcg_temp_free_i32(tmp2);
160 a7812ae4 pbrook
    tcg_temp_free_i32(tmp1);
161 bf1b03fe Richard Henderson
}
162 8aa3fa20 Richard Henderson
163 bf1b03fe Richard Henderson
static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
164 bf1b03fe Richard Henderson
{
165 bf1b03fe Richard Henderson
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
166 bf1b03fe Richard Henderson
    gen_excp_1(exception, error_code);
167 8aa3fa20 Richard Henderson
    return EXIT_NORETURN;
168 4c9649a9 j_mayer
}
169 4c9649a9 j_mayer
170 8aa3fa20 Richard Henderson
static inline ExitStatus gen_invalid(DisasContext *ctx)
171 4c9649a9 j_mayer
{
172 8aa3fa20 Richard Henderson
    return gen_excp(ctx, EXCP_OPCDEC, 0);
173 4c9649a9 j_mayer
}
174 4c9649a9 j_mayer
175 636aa200 Blue Swirl
static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
176 f18cd223 aurel32
{
177 a7812ae4 pbrook
    TCGv tmp = tcg_temp_new();
178 a7812ae4 pbrook
    TCGv_i32 tmp32 = tcg_temp_new_i32();
179 f18cd223 aurel32
    tcg_gen_qemu_ld32u(tmp, t1, flags);
180 a7812ae4 pbrook
    tcg_gen_trunc_i64_i32(tmp32, tmp);
181 a7812ae4 pbrook
    gen_helper_memory_to_f(t0, tmp32);
182 a7812ae4 pbrook
    tcg_temp_free_i32(tmp32);
183 f18cd223 aurel32
    tcg_temp_free(tmp);
184 f18cd223 aurel32
}
185 f18cd223 aurel32
186 636aa200 Blue Swirl
static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
187 f18cd223 aurel32
{
188 a7812ae4 pbrook
    TCGv tmp = tcg_temp_new();
189 f18cd223 aurel32
    tcg_gen_qemu_ld64(tmp, t1, flags);
190 a7812ae4 pbrook
    gen_helper_memory_to_g(t0, tmp);
191 f18cd223 aurel32
    tcg_temp_free(tmp);
192 f18cd223 aurel32
}
193 f18cd223 aurel32
194 636aa200 Blue Swirl
static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
195 f18cd223 aurel32
{
196 a7812ae4 pbrook
    TCGv tmp = tcg_temp_new();
197 a7812ae4 pbrook
    TCGv_i32 tmp32 = tcg_temp_new_i32();
198 f18cd223 aurel32
    tcg_gen_qemu_ld32u(tmp, t1, flags);
199 a7812ae4 pbrook
    tcg_gen_trunc_i64_i32(tmp32, tmp);
200 a7812ae4 pbrook
    gen_helper_memory_to_s(t0, tmp32);
201 a7812ae4 pbrook
    tcg_temp_free_i32(tmp32);
202 f18cd223 aurel32
    tcg_temp_free(tmp);
203 f18cd223 aurel32
}
204 f18cd223 aurel32
205 636aa200 Blue Swirl
static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
206 f4ed8679 aurel32
{
207 f4ed8679 aurel32
    tcg_gen_qemu_ld32s(t0, t1, flags);
208 6910b8f6 Richard Henderson
    tcg_gen_mov_i64(cpu_lock_addr, t1);
209 6910b8f6 Richard Henderson
    tcg_gen_mov_i64(cpu_lock_value, t0);
210 f4ed8679 aurel32
}
211 f4ed8679 aurel32
212 636aa200 Blue Swirl
static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
213 f4ed8679 aurel32
{
214 f4ed8679 aurel32
    tcg_gen_qemu_ld64(t0, t1, flags);
215 6910b8f6 Richard Henderson
    tcg_gen_mov_i64(cpu_lock_addr, t1);
216 6910b8f6 Richard Henderson
    tcg_gen_mov_i64(cpu_lock_value, t0);
217 f4ed8679 aurel32
}
218 f4ed8679 aurel32
219 636aa200 Blue Swirl
static inline void gen_load_mem(DisasContext *ctx,
220 636aa200 Blue Swirl
                                void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
221 636aa200 Blue Swirl
                                                          int flags),
222 636aa200 Blue Swirl
                                int ra, int rb, int32_t disp16, int fp,
223 636aa200 Blue Swirl
                                int clear)
224 023d8ca2 aurel32
{
225 6910b8f6 Richard Henderson
    TCGv addr, va;
226 023d8ca2 aurel32
227 6910b8f6 Richard Henderson
    /* LDQ_U with ra $31 is UNOP.  Other various loads are forms of
228 6910b8f6 Richard Henderson
       prefetches, which we can treat as nops.  No worries about
229 6910b8f6 Richard Henderson
       missed exceptions here.  */
230 6910b8f6 Richard Henderson
    if (unlikely(ra == 31)) {
231 023d8ca2 aurel32
        return;
232 6910b8f6 Richard Henderson
    }
233 023d8ca2 aurel32
234 a7812ae4 pbrook
    addr = tcg_temp_new();
235 023d8ca2 aurel32
    if (rb != 31) {
236 023d8ca2 aurel32
        tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
237 6910b8f6 Richard Henderson
        if (clear) {
238 023d8ca2 aurel32
            tcg_gen_andi_i64(addr, addr, ~0x7);
239 6910b8f6 Richard Henderson
        }
240 023d8ca2 aurel32
    } else {
241 6910b8f6 Richard Henderson
        if (clear) {
242 023d8ca2 aurel32
            disp16 &= ~0x7;
243 6910b8f6 Richard Henderson
        }
244 023d8ca2 aurel32
        tcg_gen_movi_i64(addr, disp16);
245 023d8ca2 aurel32
    }
246 6910b8f6 Richard Henderson
247 6910b8f6 Richard Henderson
    va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
248 6910b8f6 Richard Henderson
    tcg_gen_qemu_load(va, addr, ctx->mem_idx);
249 6910b8f6 Richard Henderson
250 023d8ca2 aurel32
    tcg_temp_free(addr);
251 023d8ca2 aurel32
}
252 023d8ca2 aurel32
253 636aa200 Blue Swirl
static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
254 f18cd223 aurel32
{
255 a7812ae4 pbrook
    TCGv_i32 tmp32 = tcg_temp_new_i32();
256 a7812ae4 pbrook
    TCGv tmp = tcg_temp_new();
257 a7812ae4 pbrook
    gen_helper_f_to_memory(tmp32, t0);
258 a7812ae4 pbrook
    tcg_gen_extu_i32_i64(tmp, tmp32);
259 f18cd223 aurel32
    tcg_gen_qemu_st32(tmp, t1, flags);
260 f18cd223 aurel32
    tcg_temp_free(tmp);
261 a7812ae4 pbrook
    tcg_temp_free_i32(tmp32);
262 f18cd223 aurel32
}
263 f18cd223 aurel32
264 636aa200 Blue Swirl
static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
265 f18cd223 aurel32
{
266 a7812ae4 pbrook
    TCGv tmp = tcg_temp_new();
267 a7812ae4 pbrook
    gen_helper_g_to_memory(tmp, t0);
268 f18cd223 aurel32
    tcg_gen_qemu_st64(tmp, t1, flags);
269 f18cd223 aurel32
    tcg_temp_free(tmp);
270 f18cd223 aurel32
}
271 f18cd223 aurel32
272 636aa200 Blue Swirl
static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
273 f18cd223 aurel32
{
274 a7812ae4 pbrook
    TCGv_i32 tmp32 = tcg_temp_new_i32();
275 a7812ae4 pbrook
    TCGv tmp = tcg_temp_new();
276 a7812ae4 pbrook
    gen_helper_s_to_memory(tmp32, t0);
277 a7812ae4 pbrook
    tcg_gen_extu_i32_i64(tmp, tmp32);
278 f18cd223 aurel32
    tcg_gen_qemu_st32(tmp, t1, flags);
279 f18cd223 aurel32
    tcg_temp_free(tmp);
280 a7812ae4 pbrook
    tcg_temp_free_i32(tmp32);
281 f18cd223 aurel32
}
282 f18cd223 aurel32
283 636aa200 Blue Swirl
static inline void gen_store_mem(DisasContext *ctx,
284 636aa200 Blue Swirl
                                 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
285 636aa200 Blue Swirl
                                                            int flags),
286 636aa200 Blue Swirl
                                 int ra, int rb, int32_t disp16, int fp,
287 6910b8f6 Richard Henderson
                                 int clear)
288 023d8ca2 aurel32
{
289 6910b8f6 Richard Henderson
    TCGv addr, va;
290 6910b8f6 Richard Henderson
291 6910b8f6 Richard Henderson
    addr = tcg_temp_new();
292 023d8ca2 aurel32
    if (rb != 31) {
293 023d8ca2 aurel32
        tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
294 6910b8f6 Richard Henderson
        if (clear) {
295 023d8ca2 aurel32
            tcg_gen_andi_i64(addr, addr, ~0x7);
296 6910b8f6 Richard Henderson
        }
297 023d8ca2 aurel32
    } else {
298 6910b8f6 Richard Henderson
        if (clear) {
299 023d8ca2 aurel32
            disp16 &= ~0x7;
300 6910b8f6 Richard Henderson
        }
301 023d8ca2 aurel32
        tcg_gen_movi_i64(addr, disp16);
302 023d8ca2 aurel32
    }
303 6910b8f6 Richard Henderson
304 6910b8f6 Richard Henderson
    if (ra == 31) {
305 6910b8f6 Richard Henderson
        va = tcg_const_i64(0);
306 f18cd223 aurel32
    } else {
307 6910b8f6 Richard Henderson
        va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
308 023d8ca2 aurel32
    }
309 6910b8f6 Richard Henderson
    tcg_gen_qemu_store(va, addr, ctx->mem_idx);
310 6910b8f6 Richard Henderson
311 023d8ca2 aurel32
    tcg_temp_free(addr);
312 6910b8f6 Richard Henderson
    if (ra == 31) {
313 6910b8f6 Richard Henderson
        tcg_temp_free(va);
314 6910b8f6 Richard Henderson
    }
315 6910b8f6 Richard Henderson
}
316 6910b8f6 Richard Henderson
317 6910b8f6 Richard Henderson
static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
318 6910b8f6 Richard Henderson
                                        int32_t disp16, int quad)
319 6910b8f6 Richard Henderson
{
320 6910b8f6 Richard Henderson
    TCGv addr;
321 6910b8f6 Richard Henderson
322 6910b8f6 Richard Henderson
    if (ra == 31) {
323 6910b8f6 Richard Henderson
        /* ??? Don't bother storing anything.  The user can't tell
324 6910b8f6 Richard Henderson
           the difference, since the zero register always reads zero.  */
325 6910b8f6 Richard Henderson
        return NO_EXIT;
326 6910b8f6 Richard Henderson
    }
327 6910b8f6 Richard Henderson
328 6910b8f6 Richard Henderson
#if defined(CONFIG_USER_ONLY)
329 6910b8f6 Richard Henderson
    addr = cpu_lock_st_addr;
330 6910b8f6 Richard Henderson
#else
331 e52458fe Richard Henderson
    addr = tcg_temp_local_new();
332 6910b8f6 Richard Henderson
#endif
333 6910b8f6 Richard Henderson
334 6910b8f6 Richard Henderson
    if (rb != 31) {
335 6910b8f6 Richard Henderson
        tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
336 6910b8f6 Richard Henderson
    } else {
337 6910b8f6 Richard Henderson
        tcg_gen_movi_i64(addr, disp16);
338 6910b8f6 Richard Henderson
    }
339 6910b8f6 Richard Henderson
340 6910b8f6 Richard Henderson
#if defined(CONFIG_USER_ONLY)
341 6910b8f6 Richard Henderson
    /* ??? This is handled via a complicated version of compare-and-swap
342 6910b8f6 Richard Henderson
       in the cpu_loop.  Hopefully one day we'll have a real CAS opcode
343 6910b8f6 Richard Henderson
       in TCG so that this isn't necessary.  */
344 6910b8f6 Richard Henderson
    return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra);
345 6910b8f6 Richard Henderson
#else
346 6910b8f6 Richard Henderson
    /* ??? In system mode we are never multi-threaded, so CAS can be
347 6910b8f6 Richard Henderson
       implemented via a non-atomic load-compare-store sequence.  */
348 6910b8f6 Richard Henderson
    {
349 6910b8f6 Richard Henderson
        int lab_fail, lab_done;
350 6910b8f6 Richard Henderson
        TCGv val;
351 6910b8f6 Richard Henderson
352 6910b8f6 Richard Henderson
        lab_fail = gen_new_label();
353 6910b8f6 Richard Henderson
        lab_done = gen_new_label();
354 e52458fe Richard Henderson
        tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
355 6910b8f6 Richard Henderson
356 6910b8f6 Richard Henderson
        val = tcg_temp_new();
357 6910b8f6 Richard Henderson
        if (quad) {
358 6910b8f6 Richard Henderson
            tcg_gen_qemu_ld64(val, addr, ctx->mem_idx);
359 6910b8f6 Richard Henderson
        } else {
360 6910b8f6 Richard Henderson
            tcg_gen_qemu_ld32s(val, addr, ctx->mem_idx);
361 6910b8f6 Richard Henderson
        }
362 e52458fe Richard Henderson
        tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
363 6910b8f6 Richard Henderson
364 6910b8f6 Richard Henderson
        if (quad) {
365 6910b8f6 Richard Henderson
            tcg_gen_qemu_st64(cpu_ir[ra], addr, ctx->mem_idx);
366 6910b8f6 Richard Henderson
        } else {
367 6910b8f6 Richard Henderson
            tcg_gen_qemu_st32(cpu_ir[ra], addr, ctx->mem_idx);
368 6910b8f6 Richard Henderson
        }
369 6910b8f6 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[ra], 1);
370 6910b8f6 Richard Henderson
        tcg_gen_br(lab_done);
371 6910b8f6 Richard Henderson
372 6910b8f6 Richard Henderson
        gen_set_label(lab_fail);
373 6910b8f6 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[ra], 0);
374 6910b8f6 Richard Henderson
375 6910b8f6 Richard Henderson
        gen_set_label(lab_done);
376 6910b8f6 Richard Henderson
        tcg_gen_movi_i64(cpu_lock_addr, -1);
377 6910b8f6 Richard Henderson
378 6910b8f6 Richard Henderson
        tcg_temp_free(addr);
379 6910b8f6 Richard Henderson
        return NO_EXIT;
380 6910b8f6 Richard Henderson
    }
381 6910b8f6 Richard Henderson
#endif
382 023d8ca2 aurel32
}
383 023d8ca2 aurel32
384 4af70374 Richard Henderson
static int use_goto_tb(DisasContext *ctx, uint64_t dest)
385 4c9649a9 j_mayer
{
386 4af70374 Richard Henderson
    /* Check for the dest on the same page as the start of the TB.  We
387 4af70374 Richard Henderson
       also want to suppress goto_tb in the case of single-steping and IO.  */
388 4af70374 Richard Henderson
    return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
389 4af70374 Richard Henderson
            && !ctx->env->singlestep_enabled
390 4af70374 Richard Henderson
            && !(ctx->tb->cflags & CF_LAST_IO));
391 4af70374 Richard Henderson
}
392 dbb30fe6 Richard Henderson
393 4af70374 Richard Henderson
static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
394 4af70374 Richard Henderson
{
395 4af70374 Richard Henderson
    uint64_t dest = ctx->pc + (disp << 2);
396 4af70374 Richard Henderson
397 4af70374 Richard Henderson
    if (ra != 31) {
398 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
399 4af70374 Richard Henderson
    }
400 4af70374 Richard Henderson
401 4af70374 Richard Henderson
    /* Notice branch-to-next; used to initialize RA with the PC.  */
402 4af70374 Richard Henderson
    if (disp == 0) {
403 4af70374 Richard Henderson
        return 0;
404 4af70374 Richard Henderson
    } else if (use_goto_tb(ctx, dest)) {
405 4af70374 Richard Henderson
        tcg_gen_goto_tb(0);
406 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_pc, dest);
407 4b4a72e5 Stefan Weil
        tcg_gen_exit_tb((tcg_target_long)ctx->tb);
408 4af70374 Richard Henderson
        return EXIT_GOTO_TB;
409 4af70374 Richard Henderson
    } else {
410 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_pc, dest);
411 4af70374 Richard Henderson
        return EXIT_PC_UPDATED;
412 4af70374 Richard Henderson
    }
413 dbb30fe6 Richard Henderson
}
414 dbb30fe6 Richard Henderson
415 4af70374 Richard Henderson
static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
416 4af70374 Richard Henderson
                                     TCGv cmp, int32_t disp)
417 dbb30fe6 Richard Henderson
{
418 4af70374 Richard Henderson
    uint64_t dest = ctx->pc + (disp << 2);
419 dbb30fe6 Richard Henderson
    int lab_true = gen_new_label();
420 9c29504e aurel32
421 4af70374 Richard Henderson
    if (use_goto_tb(ctx, dest)) {
422 4af70374 Richard Henderson
        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
423 4af70374 Richard Henderson
424 4af70374 Richard Henderson
        tcg_gen_goto_tb(0);
425 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_pc, ctx->pc);
426 4b4a72e5 Stefan Weil
        tcg_gen_exit_tb((tcg_target_long)ctx->tb);
427 4af70374 Richard Henderson
428 4af70374 Richard Henderson
        gen_set_label(lab_true);
429 4af70374 Richard Henderson
        tcg_gen_goto_tb(1);
430 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_pc, dest);
431 4b4a72e5 Stefan Weil
        tcg_gen_exit_tb((tcg_target_long)ctx->tb + 1);
432 4af70374 Richard Henderson
433 4af70374 Richard Henderson
        return EXIT_GOTO_TB;
434 4af70374 Richard Henderson
    } else {
435 4af70374 Richard Henderson
        int lab_over = gen_new_label();
436 4af70374 Richard Henderson
437 4af70374 Richard Henderson
        /* ??? Consider using either
438 4af70374 Richard Henderson
             movi pc, next
439 4af70374 Richard Henderson
             addi tmp, pc, disp
440 4af70374 Richard Henderson
             movcond pc, cond, 0, tmp, pc
441 4af70374 Richard Henderson
           or
442 4af70374 Richard Henderson
             setcond tmp, cond, 0
443 4af70374 Richard Henderson
             movi pc, next
444 4af70374 Richard Henderson
             neg tmp, tmp
445 4af70374 Richard Henderson
             andi tmp, tmp, disp
446 4af70374 Richard Henderson
             add pc, pc, tmp
447 4af70374 Richard Henderson
           The current diamond subgraph surely isn't efficient.  */
448 4af70374 Richard Henderson
449 4af70374 Richard Henderson
        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
450 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_pc, ctx->pc);
451 4af70374 Richard Henderson
        tcg_gen_br(lab_over);
452 4af70374 Richard Henderson
        gen_set_label(lab_true);
453 4af70374 Richard Henderson
        tcg_gen_movi_i64(cpu_pc, dest);
454 4af70374 Richard Henderson
        gen_set_label(lab_over);
455 4af70374 Richard Henderson
456 4af70374 Richard Henderson
        return EXIT_PC_UPDATED;
457 4af70374 Richard Henderson
    }
458 4af70374 Richard Henderson
}
459 4af70374 Richard Henderson
460 4af70374 Richard Henderson
static ExitStatus gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
461 4af70374 Richard Henderson
                            int32_t disp, int mask)
462 4af70374 Richard Henderson
{
463 4af70374 Richard Henderson
    TCGv cmp_tmp;
464 4af70374 Richard Henderson
465 4af70374 Richard Henderson
    if (unlikely(ra == 31)) {
466 4af70374 Richard Henderson
        cmp_tmp = tcg_const_i64(0);
467 4af70374 Richard Henderson
    } else {
468 4af70374 Richard Henderson
        cmp_tmp = tcg_temp_new();
469 9c29504e aurel32
        if (mask) {
470 4af70374 Richard Henderson
            tcg_gen_andi_i64(cmp_tmp, cpu_ir[ra], 1);
471 dbb30fe6 Richard Henderson
        } else {
472 4af70374 Richard Henderson
            tcg_gen_mov_i64(cmp_tmp, cpu_ir[ra]);
473 dbb30fe6 Richard Henderson
        }
474 9c29504e aurel32
    }
475 4af70374 Richard Henderson
476 4af70374 Richard Henderson
    return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
477 4c9649a9 j_mayer
}
478 4c9649a9 j_mayer
479 4af70374 Richard Henderson
/* Fold -0.0 for comparison with COND.  */
480 dbb30fe6 Richard Henderson
481 4af70374 Richard Henderson
static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
482 4c9649a9 j_mayer
{
483 dbb30fe6 Richard Henderson
    uint64_t mzero = 1ull << 63;
484 f18cd223 aurel32
485 dbb30fe6 Richard Henderson
    switch (cond) {
486 dbb30fe6 Richard Henderson
    case TCG_COND_LE:
487 dbb30fe6 Richard Henderson
    case TCG_COND_GT:
488 dbb30fe6 Richard Henderson
        /* For <= or >, the -0.0 value directly compares the way we want.  */
489 4af70374 Richard Henderson
        tcg_gen_mov_i64(dest, src);
490 a7812ae4 pbrook
        break;
491 dbb30fe6 Richard Henderson
492 dbb30fe6 Richard Henderson
    case TCG_COND_EQ:
493 dbb30fe6 Richard Henderson
    case TCG_COND_NE:
494 dbb30fe6 Richard Henderson
        /* For == or !=, we can simply mask off the sign bit and compare.  */
495 4af70374 Richard Henderson
        tcg_gen_andi_i64(dest, src, mzero - 1);
496 a7812ae4 pbrook
        break;
497 dbb30fe6 Richard Henderson
498 dbb30fe6 Richard Henderson
    case TCG_COND_GE:
499 dbb30fe6 Richard Henderson
    case TCG_COND_LT:
500 4af70374 Richard Henderson
        /* For >= or <, map -0.0 to +0.0 via comparison and mask.  */
501 4af70374 Richard Henderson
        tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
502 4af70374 Richard Henderson
        tcg_gen_neg_i64(dest, dest);
503 4af70374 Richard Henderson
        tcg_gen_and_i64(dest, dest, src);
504 a7812ae4 pbrook
        break;
505 dbb30fe6 Richard Henderson
506 a7812ae4 pbrook
    default:
507 a7812ae4 pbrook
        abort();
508 f18cd223 aurel32
    }
509 dbb30fe6 Richard Henderson
}
510 dbb30fe6 Richard Henderson
511 4af70374 Richard Henderson
static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
512 4af70374 Richard Henderson
                             int32_t disp)
513 dbb30fe6 Richard Henderson
{
514 4af70374 Richard Henderson
    TCGv cmp_tmp;
515 dbb30fe6 Richard Henderson
516 dbb30fe6 Richard Henderson
    if (unlikely(ra == 31)) {
517 dbb30fe6 Richard Henderson
        /* Very uncommon case, but easier to optimize it to an integer
518 dbb30fe6 Richard Henderson
           comparison than continuing with the floating point comparison.  */
519 4af70374 Richard Henderson
        return gen_bcond(ctx, cond, ra, disp, 0);
520 dbb30fe6 Richard Henderson
    }
521 dbb30fe6 Richard Henderson
522 4af70374 Richard Henderson
    cmp_tmp = tcg_temp_new();
523 4af70374 Richard Henderson
    gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
524 4af70374 Richard Henderson
    return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
525 4c9649a9 j_mayer
}
526 4c9649a9 j_mayer
527 bbe1dab4 Richard Henderson
static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
528 4af70374 Richard Henderson
                     int islit, uint8_t lit, int mask)
529 4c9649a9 j_mayer
{
530 bbe1dab4 Richard Henderson
    TCGCond inv_cond = tcg_invert_cond(cond);
531 9c29504e aurel32
    int l1;
532 9c29504e aurel32
533 9c29504e aurel32
    if (unlikely(rc == 31))
534 9c29504e aurel32
        return;
535 9c29504e aurel32
536 9c29504e aurel32
    l1 = gen_new_label();
537 9c29504e aurel32
538 9c29504e aurel32
    if (ra != 31) {
539 9c29504e aurel32
        if (mask) {
540 a7812ae4 pbrook
            TCGv tmp = tcg_temp_new();
541 9c29504e aurel32
            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
542 9c29504e aurel32
            tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
543 9c29504e aurel32
            tcg_temp_free(tmp);
544 9c29504e aurel32
        } else
545 9c29504e aurel32
            tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
546 9c29504e aurel32
    } else {
547 9c29504e aurel32
        /* Very uncommon case - Do not bother to optimize.  */
548 9c29504e aurel32
        TCGv tmp = tcg_const_i64(0);
549 9c29504e aurel32
        tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
550 9c29504e aurel32
        tcg_temp_free(tmp);
551 9c29504e aurel32
    }
552 9c29504e aurel32
553 4c9649a9 j_mayer
    if (islit)
554 9c29504e aurel32
        tcg_gen_movi_i64(cpu_ir[rc], lit);
555 4c9649a9 j_mayer
    else
556 dfaa8583 aurel32
        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
557 9c29504e aurel32
    gen_set_label(l1);
558 4c9649a9 j_mayer
}
559 4c9649a9 j_mayer
560 bbe1dab4 Richard Henderson
static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
561 dbb30fe6 Richard Henderson
{
562 4af70374 Richard Henderson
    TCGv cmp_tmp;
563 dbb30fe6 Richard Henderson
    int l1;
564 dbb30fe6 Richard Henderson
565 4af70374 Richard Henderson
    if (unlikely(rc == 31)) {
566 dbb30fe6 Richard Henderson
        return;
567 4af70374 Richard Henderson
    }
568 4af70374 Richard Henderson
569 4af70374 Richard Henderson
    cmp_tmp = tcg_temp_new();
570 dbb30fe6 Richard Henderson
    if (unlikely(ra == 31)) {
571 4af70374 Richard Henderson
        tcg_gen_movi_i64(cmp_tmp, 0);
572 4af70374 Richard Henderson
    } else {
573 4af70374 Richard Henderson
        gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
574 dbb30fe6 Richard Henderson
    }
575 dbb30fe6 Richard Henderson
576 dbb30fe6 Richard Henderson
    l1 = gen_new_label();
577 4af70374 Richard Henderson
    tcg_gen_brcondi_i64(tcg_invert_cond(cond), cmp_tmp, 0, l1);
578 4af70374 Richard Henderson
    tcg_temp_free(cmp_tmp);
579 dbb30fe6 Richard Henderson
580 dbb30fe6 Richard Henderson
    if (rb != 31)
581 dbb30fe6 Richard Henderson
        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
582 dbb30fe6 Richard Henderson
    else
583 dbb30fe6 Richard Henderson
        tcg_gen_movi_i64(cpu_fir[rc], 0);
584 dbb30fe6 Richard Henderson
    gen_set_label(l1);
585 dbb30fe6 Richard Henderson
}
586 dbb30fe6 Richard Henderson
587 f24518b5 Richard Henderson
#define QUAL_RM_N       0x080   /* Round mode nearest even */
588 f24518b5 Richard Henderson
#define QUAL_RM_C       0x000   /* Round mode chopped */
589 f24518b5 Richard Henderson
#define QUAL_RM_M       0x040   /* Round mode minus infinity */
590 f24518b5 Richard Henderson
#define QUAL_RM_D       0x0c0   /* Round mode dynamic */
591 f24518b5 Richard Henderson
#define QUAL_RM_MASK    0x0c0
592 f24518b5 Richard Henderson
593 f24518b5 Richard Henderson
#define QUAL_U          0x100   /* Underflow enable (fp output) */
594 f24518b5 Richard Henderson
#define QUAL_V          0x100   /* Overflow enable (int output) */
595 f24518b5 Richard Henderson
#define QUAL_S          0x400   /* Software completion enable */
596 f24518b5 Richard Henderson
#define QUAL_I          0x200   /* Inexact detection enable */
597 f24518b5 Richard Henderson
598 f24518b5 Richard Henderson
static void gen_qual_roundmode(DisasContext *ctx, int fn11)
599 f24518b5 Richard Henderson
{
600 f24518b5 Richard Henderson
    TCGv_i32 tmp;
601 f24518b5 Richard Henderson
602 f24518b5 Richard Henderson
    fn11 &= QUAL_RM_MASK;
603 f24518b5 Richard Henderson
    if (fn11 == ctx->tb_rm) {
604 f24518b5 Richard Henderson
        return;
605 f24518b5 Richard Henderson
    }
606 f24518b5 Richard Henderson
    ctx->tb_rm = fn11;
607 f24518b5 Richard Henderson
608 f24518b5 Richard Henderson
    tmp = tcg_temp_new_i32();
609 f24518b5 Richard Henderson
    switch (fn11) {
610 f24518b5 Richard Henderson
    case QUAL_RM_N:
611 f24518b5 Richard Henderson
        tcg_gen_movi_i32(tmp, float_round_nearest_even);
612 f24518b5 Richard Henderson
        break;
613 f24518b5 Richard Henderson
    case QUAL_RM_C:
614 f24518b5 Richard Henderson
        tcg_gen_movi_i32(tmp, float_round_to_zero);
615 f24518b5 Richard Henderson
        break;
616 f24518b5 Richard Henderson
    case QUAL_RM_M:
617 f24518b5 Richard Henderson
        tcg_gen_movi_i32(tmp, float_round_down);
618 f24518b5 Richard Henderson
        break;
619 f24518b5 Richard Henderson
    case QUAL_RM_D:
620 f24518b5 Richard Henderson
        tcg_gen_ld8u_i32(tmp, cpu_env, offsetof(CPUState, fpcr_dyn_round));
621 f24518b5 Richard Henderson
        break;
622 f24518b5 Richard Henderson
    }
623 f24518b5 Richard Henderson
624 f24518b5 Richard Henderson
#if defined(CONFIG_SOFTFLOAT_INLINE)
625 f24518b5 Richard Henderson
    /* ??? The "softfloat.h" interface is to call set_float_rounding_mode.
626 f24518b5 Richard Henderson
       With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
627 f24518b5 Richard Henderson
       sets the one field.  */
628 f24518b5 Richard Henderson
    tcg_gen_st8_i32(tmp, cpu_env,
629 f24518b5 Richard Henderson
                    offsetof(CPUState, fp_status.float_rounding_mode));
630 f24518b5 Richard Henderson
#else
631 f24518b5 Richard Henderson
    gen_helper_setroundmode(tmp);
632 f24518b5 Richard Henderson
#endif
633 f24518b5 Richard Henderson
634 f24518b5 Richard Henderson
    tcg_temp_free_i32(tmp);
635 f24518b5 Richard Henderson
}
636 f24518b5 Richard Henderson
637 f24518b5 Richard Henderson
static void gen_qual_flushzero(DisasContext *ctx, int fn11)
638 f24518b5 Richard Henderson
{
639 f24518b5 Richard Henderson
    TCGv_i32 tmp;
640 f24518b5 Richard Henderson
641 f24518b5 Richard Henderson
    fn11 &= QUAL_U;
642 f24518b5 Richard Henderson
    if (fn11 == ctx->tb_ftz) {
643 f24518b5 Richard Henderson
        return;
644 f24518b5 Richard Henderson
    }
645 f24518b5 Richard Henderson
    ctx->tb_ftz = fn11;
646 f24518b5 Richard Henderson
647 f24518b5 Richard Henderson
    tmp = tcg_temp_new_i32();
648 f24518b5 Richard Henderson
    if (fn11) {
649 f24518b5 Richard Henderson
        /* Underflow is enabled, use the FPCR setting.  */
650 f24518b5 Richard Henderson
        tcg_gen_ld8u_i32(tmp, cpu_env, offsetof(CPUState, fpcr_flush_to_zero));
651 f24518b5 Richard Henderson
    } else {
652 f24518b5 Richard Henderson
        /* Underflow is disabled, force flush-to-zero.  */
653 f24518b5 Richard Henderson
        tcg_gen_movi_i32(tmp, 1);
654 f24518b5 Richard Henderson
    }
655 f24518b5 Richard Henderson
656 f24518b5 Richard Henderson
#if defined(CONFIG_SOFTFLOAT_INLINE)
657 f24518b5 Richard Henderson
    tcg_gen_st8_i32(tmp, cpu_env,
658 f24518b5 Richard Henderson
                    offsetof(CPUState, fp_status.flush_to_zero));
659 f24518b5 Richard Henderson
#else
660 f24518b5 Richard Henderson
    gen_helper_setflushzero(tmp);
661 f24518b5 Richard Henderson
#endif
662 f24518b5 Richard Henderson
663 f24518b5 Richard Henderson
    tcg_temp_free_i32(tmp);
664 f24518b5 Richard Henderson
}
665 f24518b5 Richard Henderson
666 f24518b5 Richard Henderson
static TCGv gen_ieee_input(int reg, int fn11, int is_cmp)
667 f24518b5 Richard Henderson
{
668 f24518b5 Richard Henderson
    TCGv val = tcg_temp_new();
669 f24518b5 Richard Henderson
    if (reg == 31) {
670 f24518b5 Richard Henderson
        tcg_gen_movi_i64(val, 0);
671 f24518b5 Richard Henderson
    } else if (fn11 & QUAL_S) {
672 f24518b5 Richard Henderson
        gen_helper_ieee_input_s(val, cpu_fir[reg]);
673 f24518b5 Richard Henderson
    } else if (is_cmp) {
674 f24518b5 Richard Henderson
        gen_helper_ieee_input_cmp(val, cpu_fir[reg]);
675 f24518b5 Richard Henderson
    } else {
676 f24518b5 Richard Henderson
        gen_helper_ieee_input(val, cpu_fir[reg]);
677 f24518b5 Richard Henderson
    }
678 f24518b5 Richard Henderson
    return val;
679 f24518b5 Richard Henderson
}
680 f24518b5 Richard Henderson
681 f24518b5 Richard Henderson
static void gen_fp_exc_clear(void)
682 f24518b5 Richard Henderson
{
683 f24518b5 Richard Henderson
#if defined(CONFIG_SOFTFLOAT_INLINE)
684 f24518b5 Richard Henderson
    TCGv_i32 zero = tcg_const_i32(0);
685 f24518b5 Richard Henderson
    tcg_gen_st8_i32(zero, cpu_env,
686 f24518b5 Richard Henderson
                    offsetof(CPUState, fp_status.float_exception_flags));
687 f24518b5 Richard Henderson
    tcg_temp_free_i32(zero);
688 f24518b5 Richard Henderson
#else
689 f24518b5 Richard Henderson
    gen_helper_fp_exc_clear();
690 f24518b5 Richard Henderson
#endif
691 f24518b5 Richard Henderson
}
692 f24518b5 Richard Henderson
693 f24518b5 Richard Henderson
static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
694 f24518b5 Richard Henderson
{
695 f24518b5 Richard Henderson
    /* ??? We ought to be able to do something with imprecise exceptions.
696 f24518b5 Richard Henderson
       E.g. notice we're still in the trap shadow of something within the
697 f24518b5 Richard Henderson
       TB and do not generate the code to signal the exception; end the TB
698 f24518b5 Richard Henderson
       when an exception is forced to arrive, either by consumption of a
699 f24518b5 Richard Henderson
       register value or TRAPB or EXCB.  */
700 f24518b5 Richard Henderson
    TCGv_i32 exc = tcg_temp_new_i32();
701 f24518b5 Richard Henderson
    TCGv_i32 reg;
702 f24518b5 Richard Henderson
703 f24518b5 Richard Henderson
#if defined(CONFIG_SOFTFLOAT_INLINE)
704 f24518b5 Richard Henderson
    tcg_gen_ld8u_i32(exc, cpu_env,
705 f24518b5 Richard Henderson
                     offsetof(CPUState, fp_status.float_exception_flags));
706 f24518b5 Richard Henderson
#else
707 f24518b5 Richard Henderson
    gen_helper_fp_exc_get(exc);
708 f24518b5 Richard Henderson
#endif
709 f24518b5 Richard Henderson
710 f24518b5 Richard Henderson
    if (ignore) {
711 f24518b5 Richard Henderson
        tcg_gen_andi_i32(exc, exc, ~ignore);
712 f24518b5 Richard Henderson
    }
713 f24518b5 Richard Henderson
714 f24518b5 Richard Henderson
    /* ??? Pass in the regno of the destination so that the helper can
715 f24518b5 Richard Henderson
       set EXC_MASK, which contains a bitmask of destination registers
716 f24518b5 Richard Henderson
       that have caused arithmetic traps.  A simple userspace emulation
717 f24518b5 Richard Henderson
       does not require this.  We do need it for a guest kernel's entArith,
718 f24518b5 Richard Henderson
       or if we were to do something clever with imprecise exceptions.  */
719 f24518b5 Richard Henderson
    reg = tcg_const_i32(rc + 32);
720 f24518b5 Richard Henderson
721 f24518b5 Richard Henderson
    if (fn11 & QUAL_S) {
722 f24518b5 Richard Henderson
        gen_helper_fp_exc_raise_s(exc, reg);
723 f24518b5 Richard Henderson
    } else {
724 f24518b5 Richard Henderson
        gen_helper_fp_exc_raise(exc, reg);
725 f24518b5 Richard Henderson
    }
726 f24518b5 Richard Henderson
727 f24518b5 Richard Henderson
    tcg_temp_free_i32(reg);
728 f24518b5 Richard Henderson
    tcg_temp_free_i32(exc);
729 f24518b5 Richard Henderson
}
730 f24518b5 Richard Henderson
731 f24518b5 Richard Henderson
static inline void gen_fp_exc_raise(int rc, int fn11)
732 f24518b5 Richard Henderson
{
733 f24518b5 Richard Henderson
    gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
734 4c9649a9 j_mayer
}
735 f24518b5 Richard Henderson
736 593f17e5 Richard Henderson
static void gen_fcvtlq(int rb, int rc)
737 593f17e5 Richard Henderson
{
738 593f17e5 Richard Henderson
    if (unlikely(rc == 31)) {
739 593f17e5 Richard Henderson
        return;
740 593f17e5 Richard Henderson
    }
741 593f17e5 Richard Henderson
    if (unlikely(rb == 31)) {
742 593f17e5 Richard Henderson
        tcg_gen_movi_i64(cpu_fir[rc], 0);
743 593f17e5 Richard Henderson
    } else {
744 593f17e5 Richard Henderson
        TCGv tmp = tcg_temp_new();
745 593f17e5 Richard Henderson
746 593f17e5 Richard Henderson
        /* The arithmetic right shift here, plus the sign-extended mask below
747 593f17e5 Richard Henderson
           yields a sign-extended result without an explicit ext32s_i64.  */
748 593f17e5 Richard Henderson
        tcg_gen_sari_i64(tmp, cpu_fir[rb], 32);
749 593f17e5 Richard Henderson
        tcg_gen_shri_i64(cpu_fir[rc], cpu_fir[rb], 29);
750 593f17e5 Richard Henderson
        tcg_gen_andi_i64(tmp, tmp, (int32_t)0xc0000000);
751 593f17e5 Richard Henderson
        tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rc], 0x3fffffff);
752 593f17e5 Richard Henderson
        tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
753 593f17e5 Richard Henderson
754 593f17e5 Richard Henderson
        tcg_temp_free(tmp);
755 593f17e5 Richard Henderson
    }
756 593f17e5 Richard Henderson
}
757 593f17e5 Richard Henderson
758 735cf45f Richard Henderson
static void gen_fcvtql(int rb, int rc)
759 735cf45f Richard Henderson
{
760 735cf45f Richard Henderson
    if (unlikely(rc == 31)) {
761 735cf45f Richard Henderson
        return;
762 735cf45f Richard Henderson
    }
763 735cf45f Richard Henderson
    if (unlikely(rb == 31)) {
764 735cf45f Richard Henderson
        tcg_gen_movi_i64(cpu_fir[rc], 0);
765 735cf45f Richard Henderson
    } else {
766 735cf45f Richard Henderson
        TCGv tmp = tcg_temp_new();
767 735cf45f Richard Henderson
768 735cf45f Richard Henderson
        tcg_gen_andi_i64(tmp, cpu_fir[rb], 0xC0000000);
769 735cf45f Richard Henderson
        tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rb], 0x3FFFFFFF);
770 735cf45f Richard Henderson
        tcg_gen_shli_i64(tmp, tmp, 32);
771 735cf45f Richard Henderson
        tcg_gen_shli_i64(cpu_fir[rc], cpu_fir[rc], 29);
772 735cf45f Richard Henderson
        tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
773 735cf45f Richard Henderson
774 735cf45f Richard Henderson
        tcg_temp_free(tmp);
775 735cf45f Richard Henderson
    }
776 735cf45f Richard Henderson
}
777 735cf45f Richard Henderson
778 735cf45f Richard Henderson
static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
779 735cf45f Richard Henderson
{
780 735cf45f Richard Henderson
    if (rb != 31) {
781 735cf45f Richard Henderson
        int lab = gen_new_label();
782 735cf45f Richard Henderson
        TCGv tmp = tcg_temp_new();
783 735cf45f Richard Henderson
784 735cf45f Richard Henderson
        tcg_gen_ext32s_i64(tmp, cpu_fir[rb]);
785 735cf45f Richard Henderson
        tcg_gen_brcond_i64(TCG_COND_EQ, tmp, cpu_fir[rb], lab);
786 735cf45f Richard Henderson
        gen_excp(ctx, EXCP_ARITH, EXC_M_IOV);
787 735cf45f Richard Henderson
788 735cf45f Richard Henderson
        gen_set_label(lab);
789 735cf45f Richard Henderson
    }
790 735cf45f Richard Henderson
    gen_fcvtql(rb, rc);
791 735cf45f Richard Henderson
}
792 735cf45f Richard Henderson
793 f24518b5 Richard Henderson
#define FARITH2(name)                                   \
794 f24518b5 Richard Henderson
static inline void glue(gen_f, name)(int rb, int rc)    \
795 f24518b5 Richard Henderson
{                                                       \
796 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {                           \
797 f24518b5 Richard Henderson
        return;                                         \
798 f24518b5 Richard Henderson
    }                                                   \
799 f24518b5 Richard Henderson
    if (rb != 31) {                                     \
800 f24518b5 Richard Henderson
        gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]); \
801 f24518b5 Richard Henderson
    } else {                                                \
802 f24518b5 Richard Henderson
        TCGv tmp = tcg_const_i64(0);                    \
803 f24518b5 Richard Henderson
        gen_helper_ ## name (cpu_fir[rc], tmp);         \
804 f24518b5 Richard Henderson
        tcg_temp_free(tmp);                             \
805 f24518b5 Richard Henderson
    }                                                   \
806 f24518b5 Richard Henderson
}
807 f24518b5 Richard Henderson
808 f24518b5 Richard Henderson
/* ??? VAX instruction qualifiers ignored.  */
809 a7812ae4 pbrook
FARITH2(sqrtf)
810 a7812ae4 pbrook
FARITH2(sqrtg)
811 a7812ae4 pbrook
FARITH2(cvtgf)
812 a7812ae4 pbrook
FARITH2(cvtgq)
813 a7812ae4 pbrook
FARITH2(cvtqf)
814 a7812ae4 pbrook
FARITH2(cvtqg)
815 f24518b5 Richard Henderson
816 f24518b5 Richard Henderson
static void gen_ieee_arith2(DisasContext *ctx, void (*helper)(TCGv, TCGv),
817 f24518b5 Richard Henderson
                            int rb, int rc, int fn11)
818 f24518b5 Richard Henderson
{
819 f24518b5 Richard Henderson
    TCGv vb;
820 f24518b5 Richard Henderson
821 f24518b5 Richard Henderson
    /* ??? This is wrong: the instruction is not a nop, it still may
822 f24518b5 Richard Henderson
       raise exceptions.  */
823 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {
824 f24518b5 Richard Henderson
        return;
825 f24518b5 Richard Henderson
    }
826 f24518b5 Richard Henderson
827 f24518b5 Richard Henderson
    gen_qual_roundmode(ctx, fn11);
828 f24518b5 Richard Henderson
    gen_qual_flushzero(ctx, fn11);
829 f24518b5 Richard Henderson
    gen_fp_exc_clear();
830 f24518b5 Richard Henderson
831 f24518b5 Richard Henderson
    vb = gen_ieee_input(rb, fn11, 0);
832 f24518b5 Richard Henderson
    helper(cpu_fir[rc], vb);
833 f24518b5 Richard Henderson
    tcg_temp_free(vb);
834 f24518b5 Richard Henderson
835 f24518b5 Richard Henderson
    gen_fp_exc_raise(rc, fn11);
836 f24518b5 Richard Henderson
}
837 f24518b5 Richard Henderson
838 f24518b5 Richard Henderson
#define IEEE_ARITH2(name)                                       \
839 f24518b5 Richard Henderson
static inline void glue(gen_f, name)(DisasContext *ctx,         \
840 f24518b5 Richard Henderson
                                     int rb, int rc, int fn11)  \
841 f24518b5 Richard Henderson
{                                                               \
842 f24518b5 Richard Henderson
    gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11);      \
843 f24518b5 Richard Henderson
}
844 f24518b5 Richard Henderson
IEEE_ARITH2(sqrts)
845 f24518b5 Richard Henderson
IEEE_ARITH2(sqrtt)
846 f24518b5 Richard Henderson
IEEE_ARITH2(cvtst)
847 f24518b5 Richard Henderson
IEEE_ARITH2(cvtts)
848 f24518b5 Richard Henderson
849 f24518b5 Richard Henderson
static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
850 f24518b5 Richard Henderson
{
851 f24518b5 Richard Henderson
    TCGv vb;
852 f24518b5 Richard Henderson
    int ignore = 0;
853 f24518b5 Richard Henderson
854 f24518b5 Richard Henderson
    /* ??? This is wrong: the instruction is not a nop, it still may
855 f24518b5 Richard Henderson
       raise exceptions.  */
856 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {
857 f24518b5 Richard Henderson
        return;
858 f24518b5 Richard Henderson
    }
859 f24518b5 Richard Henderson
860 f24518b5 Richard Henderson
    /* No need to set flushzero, since we have an integer output.  */
861 f24518b5 Richard Henderson
    gen_fp_exc_clear();
862 f24518b5 Richard Henderson
    vb = gen_ieee_input(rb, fn11, 0);
863 f24518b5 Richard Henderson
864 f24518b5 Richard Henderson
    /* Almost all integer conversions use cropped rounding, and most
865 f24518b5 Richard Henderson
       also do not have integer overflow enabled.  Special case that.  */
866 f24518b5 Richard Henderson
    switch (fn11) {
867 f24518b5 Richard Henderson
    case QUAL_RM_C:
868 f24518b5 Richard Henderson
        gen_helper_cvttq_c(cpu_fir[rc], vb);
869 f24518b5 Richard Henderson
        break;
870 f24518b5 Richard Henderson
    case QUAL_V | QUAL_RM_C:
871 f24518b5 Richard Henderson
    case QUAL_S | QUAL_V | QUAL_RM_C:
872 f24518b5 Richard Henderson
        ignore = float_flag_inexact;
873 f24518b5 Richard Henderson
        /* FALLTHRU */
874 f24518b5 Richard Henderson
    case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
875 f24518b5 Richard Henderson
        gen_helper_cvttq_svic(cpu_fir[rc], vb);
876 f24518b5 Richard Henderson
        break;
877 f24518b5 Richard Henderson
    default:
878 f24518b5 Richard Henderson
        gen_qual_roundmode(ctx, fn11);
879 f24518b5 Richard Henderson
        gen_helper_cvttq(cpu_fir[rc], vb);
880 f24518b5 Richard Henderson
        ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow);
881 f24518b5 Richard Henderson
        ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
882 f24518b5 Richard Henderson
        break;
883 f24518b5 Richard Henderson
    }
884 f24518b5 Richard Henderson
    tcg_temp_free(vb);
885 f24518b5 Richard Henderson
886 f24518b5 Richard Henderson
    gen_fp_exc_raise_ignore(rc, fn11, ignore);
887 4c9649a9 j_mayer
}
888 4c9649a9 j_mayer
889 f24518b5 Richard Henderson
static void gen_ieee_intcvt(DisasContext *ctx, void (*helper)(TCGv, TCGv),
890 f24518b5 Richard Henderson
                            int rb, int rc, int fn11)
891 f24518b5 Richard Henderson
{
892 f24518b5 Richard Henderson
    TCGv vb;
893 f24518b5 Richard Henderson
894 f24518b5 Richard Henderson
    /* ??? This is wrong: the instruction is not a nop, it still may
895 f24518b5 Richard Henderson
       raise exceptions.  */
896 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {
897 f24518b5 Richard Henderson
        return;
898 f24518b5 Richard Henderson
    }
899 f24518b5 Richard Henderson
900 f24518b5 Richard Henderson
    gen_qual_roundmode(ctx, fn11);
901 f24518b5 Richard Henderson
902 f24518b5 Richard Henderson
    if (rb == 31) {
903 f24518b5 Richard Henderson
        vb = tcg_const_i64(0);
904 f24518b5 Richard Henderson
    } else {
905 f24518b5 Richard Henderson
        vb = cpu_fir[rb];
906 f24518b5 Richard Henderson
    }
907 f24518b5 Richard Henderson
908 f24518b5 Richard Henderson
    /* The only exception that can be raised by integer conversion
909 f24518b5 Richard Henderson
       is inexact.  Thus we only need to worry about exceptions when
910 f24518b5 Richard Henderson
       inexact handling is requested.  */
911 f24518b5 Richard Henderson
    if (fn11 & QUAL_I) {
912 f24518b5 Richard Henderson
        gen_fp_exc_clear();
913 f24518b5 Richard Henderson
        helper(cpu_fir[rc], vb);
914 f24518b5 Richard Henderson
        gen_fp_exc_raise(rc, fn11);
915 f24518b5 Richard Henderson
    } else {
916 f24518b5 Richard Henderson
        helper(cpu_fir[rc], vb);
917 f24518b5 Richard Henderson
    }
918 f24518b5 Richard Henderson
919 f24518b5 Richard Henderson
    if (rb == 31) {
920 f24518b5 Richard Henderson
        tcg_temp_free(vb);
921 f24518b5 Richard Henderson
    }
922 f24518b5 Richard Henderson
}
923 f24518b5 Richard Henderson
924 f24518b5 Richard Henderson
#define IEEE_INTCVT(name)                                       \
925 f24518b5 Richard Henderson
static inline void glue(gen_f, name)(DisasContext *ctx,         \
926 f24518b5 Richard Henderson
                                     int rb, int rc, int fn11)  \
927 f24518b5 Richard Henderson
{                                                               \
928 f24518b5 Richard Henderson
    gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11);      \
929 f24518b5 Richard Henderson
}
930 f24518b5 Richard Henderson
IEEE_INTCVT(cvtqs)
931 f24518b5 Richard Henderson
IEEE_INTCVT(cvtqt)
932 f24518b5 Richard Henderson
933 dc96be4b Richard Henderson
static void gen_cpys_internal(int ra, int rb, int rc, int inv_a, uint64_t mask)
934 dc96be4b Richard Henderson
{
935 dc96be4b Richard Henderson
    TCGv va, vb, vmask;
936 dc96be4b Richard Henderson
    int za = 0, zb = 0;
937 dc96be4b Richard Henderson
938 dc96be4b Richard Henderson
    if (unlikely(rc == 31)) {
939 dc96be4b Richard Henderson
        return;
940 dc96be4b Richard Henderson
    }
941 dc96be4b Richard Henderson
942 dc96be4b Richard Henderson
    vmask = tcg_const_i64(mask);
943 dc96be4b Richard Henderson
944 dc96be4b Richard Henderson
    TCGV_UNUSED_I64(va);
945 dc96be4b Richard Henderson
    if (ra == 31) {
946 dc96be4b Richard Henderson
        if (inv_a) {
947 dc96be4b Richard Henderson
            va = vmask;
948 dc96be4b Richard Henderson
        } else {
949 dc96be4b Richard Henderson
            za = 1;
950 dc96be4b Richard Henderson
        }
951 dc96be4b Richard Henderson
    } else {
952 dc96be4b Richard Henderson
        va = tcg_temp_new_i64();
953 dc96be4b Richard Henderson
        tcg_gen_mov_i64(va, cpu_fir[ra]);
954 dc96be4b Richard Henderson
        if (inv_a) {
955 dc96be4b Richard Henderson
            tcg_gen_andc_i64(va, vmask, va);
956 dc96be4b Richard Henderson
        } else {
957 dc96be4b Richard Henderson
            tcg_gen_and_i64(va, va, vmask);
958 dc96be4b Richard Henderson
        }
959 dc96be4b Richard Henderson
    }
960 dc96be4b Richard Henderson
961 dc96be4b Richard Henderson
    TCGV_UNUSED_I64(vb);
962 dc96be4b Richard Henderson
    if (rb == 31) {
963 dc96be4b Richard Henderson
        zb = 1;
964 dc96be4b Richard Henderson
    } else {
965 dc96be4b Richard Henderson
        vb = tcg_temp_new_i64();
966 dc96be4b Richard Henderson
        tcg_gen_andc_i64(vb, cpu_fir[rb], vmask);
967 dc96be4b Richard Henderson
    }
968 dc96be4b Richard Henderson
969 dc96be4b Richard Henderson
    switch (za << 1 | zb) {
970 dc96be4b Richard Henderson
    case 0 | 0:
971 dc96be4b Richard Henderson
        tcg_gen_or_i64(cpu_fir[rc], va, vb);
972 dc96be4b Richard Henderson
        break;
973 dc96be4b Richard Henderson
    case 0 | 1:
974 dc96be4b Richard Henderson
        tcg_gen_mov_i64(cpu_fir[rc], va);
975 dc96be4b Richard Henderson
        break;
976 dc96be4b Richard Henderson
    case 2 | 0:
977 dc96be4b Richard Henderson
        tcg_gen_mov_i64(cpu_fir[rc], vb);
978 dc96be4b Richard Henderson
        break;
979 dc96be4b Richard Henderson
    case 2 | 1:
980 dc96be4b Richard Henderson
        tcg_gen_movi_i64(cpu_fir[rc], 0);
981 dc96be4b Richard Henderson
        break;
982 dc96be4b Richard Henderson
    }
983 dc96be4b Richard Henderson
984 dc96be4b Richard Henderson
    tcg_temp_free(vmask);
985 dc96be4b Richard Henderson
    if (ra != 31) {
986 dc96be4b Richard Henderson
        tcg_temp_free(va);
987 dc96be4b Richard Henderson
    }
988 dc96be4b Richard Henderson
    if (rb != 31) {
989 dc96be4b Richard Henderson
        tcg_temp_free(vb);
990 dc96be4b Richard Henderson
    }
991 dc96be4b Richard Henderson
}
992 dc96be4b Richard Henderson
993 dc96be4b Richard Henderson
static inline void gen_fcpys(int ra, int rb, int rc)
994 dc96be4b Richard Henderson
{
995 dc96be4b Richard Henderson
    gen_cpys_internal(ra, rb, rc, 0, 0x8000000000000000ULL);
996 dc96be4b Richard Henderson
}
997 dc96be4b Richard Henderson
998 dc96be4b Richard Henderson
static inline void gen_fcpysn(int ra, int rb, int rc)
999 dc96be4b Richard Henderson
{
1000 dc96be4b Richard Henderson
    gen_cpys_internal(ra, rb, rc, 1, 0x8000000000000000ULL);
1001 dc96be4b Richard Henderson
}
1002 dc96be4b Richard Henderson
1003 dc96be4b Richard Henderson
static inline void gen_fcpyse(int ra, int rb, int rc)
1004 dc96be4b Richard Henderson
{
1005 dc96be4b Richard Henderson
    gen_cpys_internal(ra, rb, rc, 0, 0xFFF0000000000000ULL);
1006 dc96be4b Richard Henderson
}
1007 dc96be4b Richard Henderson
1008 f24518b5 Richard Henderson
#define FARITH3(name)                                           \
1009 f24518b5 Richard Henderson
static inline void glue(gen_f, name)(int ra, int rb, int rc)    \
1010 f24518b5 Richard Henderson
{                                                               \
1011 f24518b5 Richard Henderson
    TCGv va, vb;                                                \
1012 f24518b5 Richard Henderson
                                                                \
1013 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {                                   \
1014 f24518b5 Richard Henderson
        return;                                                 \
1015 f24518b5 Richard Henderson
    }                                                           \
1016 f24518b5 Richard Henderson
    if (ra == 31) {                                             \
1017 f24518b5 Richard Henderson
        va = tcg_const_i64(0);                                  \
1018 f24518b5 Richard Henderson
    } else {                                                    \
1019 f24518b5 Richard Henderson
        va = cpu_fir[ra];                                       \
1020 f24518b5 Richard Henderson
    }                                                           \
1021 f24518b5 Richard Henderson
    if (rb == 31) {                                             \
1022 f24518b5 Richard Henderson
        vb = tcg_const_i64(0);                                  \
1023 f24518b5 Richard Henderson
    } else {                                                    \
1024 f24518b5 Richard Henderson
        vb = cpu_fir[rb];                                       \
1025 f24518b5 Richard Henderson
    }                                                           \
1026 f24518b5 Richard Henderson
                                                                \
1027 f24518b5 Richard Henderson
    gen_helper_ ## name (cpu_fir[rc], va, vb);                  \
1028 f24518b5 Richard Henderson
                                                                \
1029 f24518b5 Richard Henderson
    if (ra == 31) {                                             \
1030 f24518b5 Richard Henderson
        tcg_temp_free(va);                                      \
1031 f24518b5 Richard Henderson
    }                                                           \
1032 f24518b5 Richard Henderson
    if (rb == 31) {                                             \
1033 f24518b5 Richard Henderson
        tcg_temp_free(vb);                                      \
1034 f24518b5 Richard Henderson
    }                                                           \
1035 f24518b5 Richard Henderson
}
1036 f24518b5 Richard Henderson
1037 f24518b5 Richard Henderson
/* ??? VAX instruction qualifiers ignored.  */
1038 a7812ae4 pbrook
FARITH3(addf)
1039 a7812ae4 pbrook
FARITH3(subf)
1040 a7812ae4 pbrook
FARITH3(mulf)
1041 a7812ae4 pbrook
FARITH3(divf)
1042 a7812ae4 pbrook
FARITH3(addg)
1043 a7812ae4 pbrook
FARITH3(subg)
1044 a7812ae4 pbrook
FARITH3(mulg)
1045 a7812ae4 pbrook
FARITH3(divg)
1046 a7812ae4 pbrook
FARITH3(cmpgeq)
1047 a7812ae4 pbrook
FARITH3(cmpglt)
1048 a7812ae4 pbrook
FARITH3(cmpgle)
1049 f24518b5 Richard Henderson
1050 f24518b5 Richard Henderson
static void gen_ieee_arith3(DisasContext *ctx,
1051 f24518b5 Richard Henderson
                            void (*helper)(TCGv, TCGv, TCGv),
1052 f24518b5 Richard Henderson
                            int ra, int rb, int rc, int fn11)
1053 f24518b5 Richard Henderson
{
1054 f24518b5 Richard Henderson
    TCGv va, vb;
1055 f24518b5 Richard Henderson
1056 f24518b5 Richard Henderson
    /* ??? This is wrong: the instruction is not a nop, it still may
1057 f24518b5 Richard Henderson
       raise exceptions.  */
1058 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {
1059 f24518b5 Richard Henderson
        return;
1060 f24518b5 Richard Henderson
    }
1061 f24518b5 Richard Henderson
1062 f24518b5 Richard Henderson
    gen_qual_roundmode(ctx, fn11);
1063 f24518b5 Richard Henderson
    gen_qual_flushzero(ctx, fn11);
1064 f24518b5 Richard Henderson
    gen_fp_exc_clear();
1065 f24518b5 Richard Henderson
1066 f24518b5 Richard Henderson
    va = gen_ieee_input(ra, fn11, 0);
1067 f24518b5 Richard Henderson
    vb = gen_ieee_input(rb, fn11, 0);
1068 f24518b5 Richard Henderson
    helper(cpu_fir[rc], va, vb);
1069 f24518b5 Richard Henderson
    tcg_temp_free(va);
1070 f24518b5 Richard Henderson
    tcg_temp_free(vb);
1071 f24518b5 Richard Henderson
1072 f24518b5 Richard Henderson
    gen_fp_exc_raise(rc, fn11);
1073 f24518b5 Richard Henderson
}
1074 f24518b5 Richard Henderson
1075 f24518b5 Richard Henderson
#define IEEE_ARITH3(name)                                               \
1076 f24518b5 Richard Henderson
static inline void glue(gen_f, name)(DisasContext *ctx,                 \
1077 f24518b5 Richard Henderson
                                     int ra, int rb, int rc, int fn11)  \
1078 f24518b5 Richard Henderson
{                                                                       \
1079 f24518b5 Richard Henderson
    gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11);          \
1080 f24518b5 Richard Henderson
}
1081 f24518b5 Richard Henderson
IEEE_ARITH3(adds)
1082 f24518b5 Richard Henderson
IEEE_ARITH3(subs)
1083 f24518b5 Richard Henderson
IEEE_ARITH3(muls)
1084 f24518b5 Richard Henderson
IEEE_ARITH3(divs)
1085 f24518b5 Richard Henderson
IEEE_ARITH3(addt)
1086 f24518b5 Richard Henderson
IEEE_ARITH3(subt)
1087 f24518b5 Richard Henderson
IEEE_ARITH3(mult)
1088 f24518b5 Richard Henderson
IEEE_ARITH3(divt)
1089 f24518b5 Richard Henderson
1090 f24518b5 Richard Henderson
static void gen_ieee_compare(DisasContext *ctx,
1091 f24518b5 Richard Henderson
                             void (*helper)(TCGv, TCGv, TCGv),
1092 f24518b5 Richard Henderson
                             int ra, int rb, int rc, int fn11)
1093 f24518b5 Richard Henderson
{
1094 f24518b5 Richard Henderson
    TCGv va, vb;
1095 f24518b5 Richard Henderson
1096 f24518b5 Richard Henderson
    /* ??? This is wrong: the instruction is not a nop, it still may
1097 f24518b5 Richard Henderson
       raise exceptions.  */
1098 f24518b5 Richard Henderson
    if (unlikely(rc == 31)) {
1099 f24518b5 Richard Henderson
        return;
1100 f24518b5 Richard Henderson
    }
1101 f24518b5 Richard Henderson
1102 f24518b5 Richard Henderson
    gen_fp_exc_clear();
1103 f24518b5 Richard Henderson
1104 f24518b5 Richard Henderson
    va = gen_ieee_input(ra, fn11, 1);
1105 f24518b5 Richard Henderson
    vb = gen_ieee_input(rb, fn11, 1);
1106 f24518b5 Richard Henderson
    helper(cpu_fir[rc], va, vb);
1107 f24518b5 Richard Henderson
    tcg_temp_free(va);
1108 f24518b5 Richard Henderson
    tcg_temp_free(vb);
1109 f24518b5 Richard Henderson
1110 f24518b5 Richard Henderson
    gen_fp_exc_raise(rc, fn11);
1111 f24518b5 Richard Henderson
}
1112 f24518b5 Richard Henderson
1113 f24518b5 Richard Henderson
#define IEEE_CMP3(name)                                                 \
1114 f24518b5 Richard Henderson
static inline void glue(gen_f, name)(DisasContext *ctx,                 \
1115 f24518b5 Richard Henderson
                                     int ra, int rb, int rc, int fn11)  \
1116 f24518b5 Richard Henderson
{                                                                       \
1117 f24518b5 Richard Henderson
    gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11);         \
1118 f24518b5 Richard Henderson
}
1119 f24518b5 Richard Henderson
IEEE_CMP3(cmptun)
1120 f24518b5 Richard Henderson
IEEE_CMP3(cmpteq)
1121 f24518b5 Richard Henderson
IEEE_CMP3(cmptlt)
1122 f24518b5 Richard Henderson
IEEE_CMP3(cmptle)
1123 a7812ae4 pbrook
1124 248c42f3 Richard Henderson
static inline uint64_t zapnot_mask(uint8_t lit)
1125 248c42f3 Richard Henderson
{
1126 248c42f3 Richard Henderson
    uint64_t mask = 0;
1127 248c42f3 Richard Henderson
    int i;
1128 248c42f3 Richard Henderson
1129 248c42f3 Richard Henderson
    for (i = 0; i < 8; ++i) {
1130 248c42f3 Richard Henderson
        if ((lit >> i) & 1)
1131 248c42f3 Richard Henderson
            mask |= 0xffull << (i * 8);
1132 248c42f3 Richard Henderson
    }
1133 248c42f3 Richard Henderson
    return mask;
1134 248c42f3 Richard Henderson
}
1135 248c42f3 Richard Henderson
1136 87d98f95 Richard Henderson
/* Implement zapnot with an immediate operand, which expands to some
1137 87d98f95 Richard Henderson
   form of immediate AND.  This is a basic building block in the
1138 87d98f95 Richard Henderson
   definition of many of the other byte manipulation instructions.  */
1139 248c42f3 Richard Henderson
static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
1140 87d98f95 Richard Henderson
{
1141 87d98f95 Richard Henderson
    switch (lit) {
1142 87d98f95 Richard Henderson
    case 0x00:
1143 248c42f3 Richard Henderson
        tcg_gen_movi_i64(dest, 0);
1144 87d98f95 Richard Henderson
        break;
1145 87d98f95 Richard Henderson
    case 0x01:
1146 248c42f3 Richard Henderson
        tcg_gen_ext8u_i64(dest, src);
1147 87d98f95 Richard Henderson
        break;
1148 87d98f95 Richard Henderson
    case 0x03:
1149 248c42f3 Richard Henderson
        tcg_gen_ext16u_i64(dest, src);
1150 87d98f95 Richard Henderson
        break;
1151 87d98f95 Richard Henderson
    case 0x0f:
1152 248c42f3 Richard Henderson
        tcg_gen_ext32u_i64(dest, src);
1153 87d98f95 Richard Henderson
        break;
1154 87d98f95 Richard Henderson
    case 0xff:
1155 248c42f3 Richard Henderson
        tcg_gen_mov_i64(dest, src);
1156 87d98f95 Richard Henderson
        break;
1157 87d98f95 Richard Henderson
    default:
1158 248c42f3 Richard Henderson
        tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
1159 87d98f95 Richard Henderson
        break;
1160 87d98f95 Richard Henderson
    }
1161 87d98f95 Richard Henderson
}
1162 87d98f95 Richard Henderson
1163 87d98f95 Richard Henderson
static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
1164 87d98f95 Richard Henderson
{
1165 87d98f95 Richard Henderson
    if (unlikely(rc == 31))
1166 87d98f95 Richard Henderson
        return;
1167 87d98f95 Richard Henderson
    else if (unlikely(ra == 31))
1168 87d98f95 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1169 87d98f95 Richard Henderson
    else if (islit)
1170 248c42f3 Richard Henderson
        gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
1171 87d98f95 Richard Henderson
    else
1172 87d98f95 Richard Henderson
        gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1173 87d98f95 Richard Henderson
}
1174 87d98f95 Richard Henderson
1175 87d98f95 Richard Henderson
static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
1176 87d98f95 Richard Henderson
{
1177 87d98f95 Richard Henderson
    if (unlikely(rc == 31))
1178 87d98f95 Richard Henderson
        return;
1179 87d98f95 Richard Henderson
    else if (unlikely(ra == 31))
1180 87d98f95 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1181 87d98f95 Richard Henderson
    else if (islit)
1182 248c42f3 Richard Henderson
        gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
1183 87d98f95 Richard Henderson
    else
1184 87d98f95 Richard Henderson
        gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1185 87d98f95 Richard Henderson
}
1186 87d98f95 Richard Henderson
1187 87d98f95 Richard Henderson
1188 248c42f3 Richard Henderson
/* EXTWH, EXTLH, EXTQH */
1189 ffec44f1 Richard Henderson
static void gen_ext_h(int ra, int rb, int rc, int islit,
1190 ffec44f1 Richard Henderson
                      uint8_t lit, uint8_t byte_mask)
1191 b3249f63 aurel32
{
1192 b3249f63 aurel32
    if (unlikely(rc == 31))
1193 b3249f63 aurel32
        return;
1194 377a43b6 Richard Henderson
    else if (unlikely(ra == 31))
1195 377a43b6 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1196 377a43b6 Richard Henderson
    else {
1197 dfaa8583 aurel32
        if (islit) {
1198 377a43b6 Richard Henderson
            lit = (64 - (lit & 7) * 8) & 0x3f;
1199 377a43b6 Richard Henderson
            tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1200 fe2b269a aurel32
        } else {
1201 377a43b6 Richard Henderson
            TCGv tmp1 = tcg_temp_new();
1202 b3249f63 aurel32
            tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
1203 b3249f63 aurel32
            tcg_gen_shli_i64(tmp1, tmp1, 3);
1204 dbf95805 Vince Weaver
            tcg_gen_neg_i64(tmp1, tmp1);
1205 dbf95805 Vince Weaver
            tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
1206 dfaa8583 aurel32
            tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
1207 b3249f63 aurel32
            tcg_temp_free(tmp1);
1208 dfaa8583 aurel32
        }
1209 248c42f3 Richard Henderson
        gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1210 377a43b6 Richard Henderson
    }
1211 b3249f63 aurel32
}
1212 b3249f63 aurel32
1213 248c42f3 Richard Henderson
/* EXTBL, EXTWL, EXTLL, EXTQL */
1214 ffec44f1 Richard Henderson
static void gen_ext_l(int ra, int rb, int rc, int islit,
1215 ffec44f1 Richard Henderson
                      uint8_t lit, uint8_t byte_mask)
1216 b3249f63 aurel32
{
1217 b3249f63 aurel32
    if (unlikely(rc == 31))
1218 b3249f63 aurel32
        return;
1219 377a43b6 Richard Henderson
    else if (unlikely(ra == 31))
1220 377a43b6 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1221 377a43b6 Richard Henderson
    else {
1222 dfaa8583 aurel32
        if (islit) {
1223 377a43b6 Richard Henderson
            tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
1224 dfaa8583 aurel32
        } else {
1225 a7812ae4 pbrook
            TCGv tmp = tcg_temp_new();
1226 b3249f63 aurel32
            tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
1227 b3249f63 aurel32
            tcg_gen_shli_i64(tmp, tmp, 3);
1228 dfaa8583 aurel32
            tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
1229 b3249f63 aurel32
            tcg_temp_free(tmp);
1230 fe2b269a aurel32
        }
1231 248c42f3 Richard Henderson
        gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1232 248c42f3 Richard Henderson
    }
1233 248c42f3 Richard Henderson
}
1234 248c42f3 Richard Henderson
1235 50eb6e5c Richard Henderson
/* INSWH, INSLH, INSQH */
1236 50eb6e5c Richard Henderson
static void gen_ins_h(int ra, int rb, int rc, int islit,
1237 50eb6e5c Richard Henderson
                      uint8_t lit, uint8_t byte_mask)
1238 50eb6e5c Richard Henderson
{
1239 50eb6e5c Richard Henderson
    if (unlikely(rc == 31))
1240 50eb6e5c Richard Henderson
        return;
1241 50eb6e5c Richard Henderson
    else if (unlikely(ra == 31) || (islit && (lit & 7) == 0))
1242 50eb6e5c Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1243 50eb6e5c Richard Henderson
    else {
1244 50eb6e5c Richard Henderson
        TCGv tmp = tcg_temp_new();
1245 50eb6e5c Richard Henderson
1246 50eb6e5c Richard Henderson
        /* The instruction description has us left-shift the byte mask
1247 50eb6e5c Richard Henderson
           and extract bits <15:8> and apply that zap at the end.  This
1248 50eb6e5c Richard Henderson
           is equivalent to simply performing the zap first and shifting
1249 50eb6e5c Richard Henderson
           afterward.  */
1250 50eb6e5c Richard Henderson
        gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1251 50eb6e5c Richard Henderson
1252 50eb6e5c Richard Henderson
        if (islit) {
1253 50eb6e5c Richard Henderson
            /* Note that we have handled the lit==0 case above.  */
1254 50eb6e5c Richard Henderson
            tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
1255 50eb6e5c Richard Henderson
        } else {
1256 50eb6e5c Richard Henderson
            TCGv shift = tcg_temp_new();
1257 50eb6e5c Richard Henderson
1258 50eb6e5c Richard Henderson
            /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
1259 50eb6e5c Richard Henderson
               Do this portably by splitting the shift into two parts:
1260 50eb6e5c Richard Henderson
               shift_count-1 and 1.  Arrange for the -1 by using
1261 50eb6e5c Richard Henderson
               ones-complement instead of twos-complement in the negation:
1262 50eb6e5c Richard Henderson
               ~((B & 7) * 8) & 63.  */
1263 50eb6e5c Richard Henderson
1264 50eb6e5c Richard Henderson
            tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1265 50eb6e5c Richard Henderson
            tcg_gen_shli_i64(shift, shift, 3);
1266 50eb6e5c Richard Henderson
            tcg_gen_not_i64(shift, shift);
1267 50eb6e5c Richard Henderson
            tcg_gen_andi_i64(shift, shift, 0x3f);
1268 50eb6e5c Richard Henderson
1269 50eb6e5c Richard Henderson
            tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
1270 50eb6e5c Richard Henderson
            tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
1271 50eb6e5c Richard Henderson
            tcg_temp_free(shift);
1272 50eb6e5c Richard Henderson
        }
1273 50eb6e5c Richard Henderson
        tcg_temp_free(tmp);
1274 50eb6e5c Richard Henderson
    }
1275 50eb6e5c Richard Henderson
}
1276 50eb6e5c Richard Henderson
1277 248c42f3 Richard Henderson
/* INSBL, INSWL, INSLL, INSQL */
1278 ffec44f1 Richard Henderson
static void gen_ins_l(int ra, int rb, int rc, int islit,
1279 ffec44f1 Richard Henderson
                      uint8_t lit, uint8_t byte_mask)
1280 248c42f3 Richard Henderson
{
1281 248c42f3 Richard Henderson
    if (unlikely(rc == 31))
1282 248c42f3 Richard Henderson
        return;
1283 248c42f3 Richard Henderson
    else if (unlikely(ra == 31))
1284 248c42f3 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1285 248c42f3 Richard Henderson
    else {
1286 248c42f3 Richard Henderson
        TCGv tmp = tcg_temp_new();
1287 248c42f3 Richard Henderson
1288 248c42f3 Richard Henderson
        /* The instruction description has us left-shift the byte mask
1289 248c42f3 Richard Henderson
           the same number of byte slots as the data and apply the zap
1290 248c42f3 Richard Henderson
           at the end.  This is equivalent to simply performing the zap
1291 248c42f3 Richard Henderson
           first and shifting afterward.  */
1292 248c42f3 Richard Henderson
        gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1293 248c42f3 Richard Henderson
1294 248c42f3 Richard Henderson
        if (islit) {
1295 248c42f3 Richard Henderson
            tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
1296 248c42f3 Richard Henderson
        } else {
1297 248c42f3 Richard Henderson
            TCGv shift = tcg_temp_new();
1298 248c42f3 Richard Henderson
            tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1299 248c42f3 Richard Henderson
            tcg_gen_shli_i64(shift, shift, 3);
1300 248c42f3 Richard Henderson
            tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
1301 248c42f3 Richard Henderson
            tcg_temp_free(shift);
1302 248c42f3 Richard Henderson
        }
1303 248c42f3 Richard Henderson
        tcg_temp_free(tmp);
1304 377a43b6 Richard Henderson
    }
1305 b3249f63 aurel32
}
1306 b3249f63 aurel32
1307 ffec44f1 Richard Henderson
/* MSKWH, MSKLH, MSKQH */
1308 ffec44f1 Richard Henderson
static void gen_msk_h(int ra, int rb, int rc, int islit,
1309 ffec44f1 Richard Henderson
                      uint8_t lit, uint8_t byte_mask)
1310 ffec44f1 Richard Henderson
{
1311 ffec44f1 Richard Henderson
    if (unlikely(rc == 31))
1312 ffec44f1 Richard Henderson
        return;
1313 ffec44f1 Richard Henderson
    else if (unlikely(ra == 31))
1314 ffec44f1 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1315 ffec44f1 Richard Henderson
    else if (islit) {
1316 ffec44f1 Richard Henderson
        gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
1317 ffec44f1 Richard Henderson
    } else {
1318 ffec44f1 Richard Henderson
        TCGv shift = tcg_temp_new();
1319 ffec44f1 Richard Henderson
        TCGv mask = tcg_temp_new();
1320 ffec44f1 Richard Henderson
1321 ffec44f1 Richard Henderson
        /* The instruction description is as above, where the byte_mask
1322 ffec44f1 Richard Henderson
           is shifted left, and then we extract bits <15:8>.  This can be
1323 ffec44f1 Richard Henderson
           emulated with a right-shift on the expanded byte mask.  This
1324 ffec44f1 Richard Henderson
           requires extra care because for an input <2:0> == 0 we need a
1325 ffec44f1 Richard Henderson
           shift of 64 bits in order to generate a zero.  This is done by
1326 ffec44f1 Richard Henderson
           splitting the shift into two parts, the variable shift - 1
1327 ffec44f1 Richard Henderson
           followed by a constant 1 shift.  The code we expand below is
1328 ffec44f1 Richard Henderson
           equivalent to ~((B & 7) * 8) & 63.  */
1329 ffec44f1 Richard Henderson
1330 ffec44f1 Richard Henderson
        tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1331 ffec44f1 Richard Henderson
        tcg_gen_shli_i64(shift, shift, 3);
1332 ffec44f1 Richard Henderson
        tcg_gen_not_i64(shift, shift);
1333 ffec44f1 Richard Henderson
        tcg_gen_andi_i64(shift, shift, 0x3f);
1334 ffec44f1 Richard Henderson
        tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1335 ffec44f1 Richard Henderson
        tcg_gen_shr_i64(mask, mask, shift);
1336 ffec44f1 Richard Henderson
        tcg_gen_shri_i64(mask, mask, 1);
1337 ffec44f1 Richard Henderson
1338 ffec44f1 Richard Henderson
        tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1339 ffec44f1 Richard Henderson
1340 ffec44f1 Richard Henderson
        tcg_temp_free(mask);
1341 ffec44f1 Richard Henderson
        tcg_temp_free(shift);
1342 ffec44f1 Richard Henderson
    }
1343 ffec44f1 Richard Henderson
}
1344 ffec44f1 Richard Henderson
1345 14ab1634 Richard Henderson
/* MSKBL, MSKWL, MSKLL, MSKQL */
1346 ffec44f1 Richard Henderson
static void gen_msk_l(int ra, int rb, int rc, int islit,
1347 ffec44f1 Richard Henderson
                      uint8_t lit, uint8_t byte_mask)
1348 14ab1634 Richard Henderson
{
1349 14ab1634 Richard Henderson
    if (unlikely(rc == 31))
1350 14ab1634 Richard Henderson
        return;
1351 14ab1634 Richard Henderson
    else if (unlikely(ra == 31))
1352 14ab1634 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);
1353 14ab1634 Richard Henderson
    else if (islit) {
1354 14ab1634 Richard Henderson
        gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
1355 14ab1634 Richard Henderson
    } else {
1356 14ab1634 Richard Henderson
        TCGv shift = tcg_temp_new();
1357 14ab1634 Richard Henderson
        TCGv mask = tcg_temp_new();
1358 14ab1634 Richard Henderson
1359 14ab1634 Richard Henderson
        tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1360 14ab1634 Richard Henderson
        tcg_gen_shli_i64(shift, shift, 3);
1361 14ab1634 Richard Henderson
        tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1362 14ab1634 Richard Henderson
        tcg_gen_shl_i64(mask, mask, shift);
1363 14ab1634 Richard Henderson
1364 14ab1634 Richard Henderson
        tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1365 14ab1634 Richard Henderson
1366 14ab1634 Richard Henderson
        tcg_temp_free(mask);
1367 14ab1634 Richard Henderson
        tcg_temp_free(shift);
1368 14ab1634 Richard Henderson
    }
1369 14ab1634 Richard Henderson
}
1370 14ab1634 Richard Henderson
1371 04acd307 aurel32
/* Code to call arith3 helpers */
1372 a7812ae4 pbrook
#define ARITH3(name)                                                  \
1373 636aa200 Blue Swirl
static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
1374 636aa200 Blue Swirl
                                    uint8_t lit)                      \
1375 a7812ae4 pbrook
{                                                                     \
1376 a7812ae4 pbrook
    if (unlikely(rc == 31))                                           \
1377 a7812ae4 pbrook
        return;                                                       \
1378 a7812ae4 pbrook
                                                                      \
1379 a7812ae4 pbrook
    if (ra != 31) {                                                   \
1380 a7812ae4 pbrook
        if (islit) {                                                  \
1381 a7812ae4 pbrook
            TCGv tmp = tcg_const_i64(lit);                            \
1382 a7812ae4 pbrook
            gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp);         \
1383 a7812ae4 pbrook
            tcg_temp_free(tmp);                                       \
1384 a7812ae4 pbrook
        } else                                                        \
1385 a7812ae4 pbrook
            gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
1386 a7812ae4 pbrook
    } else {                                                          \
1387 a7812ae4 pbrook
        TCGv tmp1 = tcg_const_i64(0);                                 \
1388 a7812ae4 pbrook
        if (islit) {                                                  \
1389 a7812ae4 pbrook
            TCGv tmp2 = tcg_const_i64(lit);                           \
1390 a7812ae4 pbrook
            gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2);             \
1391 a7812ae4 pbrook
            tcg_temp_free(tmp2);                                      \
1392 a7812ae4 pbrook
        } else                                                        \
1393 a7812ae4 pbrook
            gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]);       \
1394 a7812ae4 pbrook
        tcg_temp_free(tmp1);                                          \
1395 a7812ae4 pbrook
    }                                                                 \
1396 b3249f63 aurel32
}
1397 a7812ae4 pbrook
ARITH3(cmpbge)
1398 a7812ae4 pbrook
ARITH3(addlv)
1399 a7812ae4 pbrook
ARITH3(sublv)
1400 a7812ae4 pbrook
ARITH3(addqv)
1401 a7812ae4 pbrook
ARITH3(subqv)
1402 a7812ae4 pbrook
ARITH3(umulh)
1403 a7812ae4 pbrook
ARITH3(mullv)
1404 a7812ae4 pbrook
ARITH3(mulqv)
1405 13e4df99 Richard Henderson
ARITH3(minub8)
1406 13e4df99 Richard Henderson
ARITH3(minsb8)
1407 13e4df99 Richard Henderson
ARITH3(minuw4)
1408 13e4df99 Richard Henderson
ARITH3(minsw4)
1409 13e4df99 Richard Henderson
ARITH3(maxub8)
1410 13e4df99 Richard Henderson
ARITH3(maxsb8)
1411 13e4df99 Richard Henderson
ARITH3(maxuw4)
1412 13e4df99 Richard Henderson
ARITH3(maxsw4)
1413 13e4df99 Richard Henderson
ARITH3(perr)
1414 13e4df99 Richard Henderson
1415 13e4df99 Richard Henderson
#define MVIOP2(name)                                    \
1416 13e4df99 Richard Henderson
static inline void glue(gen_, name)(int rb, int rc)     \
1417 13e4df99 Richard Henderson
{                                                       \
1418 13e4df99 Richard Henderson
    if (unlikely(rc == 31))                             \
1419 13e4df99 Richard Henderson
        return;                                         \
1420 13e4df99 Richard Henderson
    if (unlikely(rb == 31))                             \
1421 13e4df99 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[rc], 0);                \
1422 13e4df99 Richard Henderson
    else                                                \
1423 13e4df99 Richard Henderson
        gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]);   \
1424 13e4df99 Richard Henderson
}
1425 13e4df99 Richard Henderson
MVIOP2(pklb)
1426 13e4df99 Richard Henderson
MVIOP2(pkwb)
1427 13e4df99 Richard Henderson
MVIOP2(unpkbl)
1428 13e4df99 Richard Henderson
MVIOP2(unpkbw)
1429 b3249f63 aurel32
1430 9e05960f Richard Henderson
static void gen_cmp(TCGCond cond, int ra, int rb, int rc,
1431 9e05960f Richard Henderson
                    int islit, uint8_t lit)
1432 01ff9cc8 aurel32
{
1433 9e05960f Richard Henderson
    TCGv va, vb;
1434 01ff9cc8 aurel32
1435 9e05960f Richard Henderson
    if (unlikely(rc == 31)) {
1436 13e4df99 Richard Henderson
        return;
1437 9e05960f Richard Henderson
    }
1438 01ff9cc8 aurel32
1439 9e05960f Richard Henderson
    if (ra == 31) {
1440 9e05960f Richard Henderson
        va = tcg_const_i64(0);
1441 9e05960f Richard Henderson
    } else {
1442 9e05960f Richard Henderson
        va = cpu_ir[ra];
1443 9e05960f Richard Henderson
    }
1444 9e05960f Richard Henderson
    if (islit) {
1445 9e05960f Richard Henderson
        vb = tcg_const_i64(lit);
1446 9e05960f Richard Henderson
    } else {
1447 9e05960f Richard Henderson
        vb = cpu_ir[rb];
1448 9e05960f Richard Henderson
    }
1449 01ff9cc8 aurel32
1450 9e05960f Richard Henderson
    tcg_gen_setcond_i64(cond, cpu_ir[rc], va, vb);
1451 01ff9cc8 aurel32
1452 9e05960f Richard Henderson
    if (ra == 31) {
1453 9e05960f Richard Henderson
        tcg_temp_free(va);
1454 9e05960f Richard Henderson
    }
1455 9e05960f Richard Henderson
    if (islit) {
1456 9e05960f Richard Henderson
        tcg_temp_free(vb);
1457 9e05960f Richard Henderson
    }
1458 01ff9cc8 aurel32
}
1459 01ff9cc8 aurel32
1460 ac316ca4 Richard Henderson
static void gen_rx(int ra, int set)
1461 ac316ca4 Richard Henderson
{
1462 ac316ca4 Richard Henderson
    TCGv_i32 tmp;
1463 ac316ca4 Richard Henderson
1464 ac316ca4 Richard Henderson
    if (ra != 31) {
1465 ac316ca4 Richard Henderson
        tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, offsetof(CPUState, intr_flag));
1466 ac316ca4 Richard Henderson
    }
1467 ac316ca4 Richard Henderson
1468 ac316ca4 Richard Henderson
    tmp = tcg_const_i32(set);
1469 ac316ca4 Richard Henderson
    tcg_gen_st8_i32(tmp, cpu_env, offsetof(CPUState, intr_flag));
1470 ac316ca4 Richard Henderson
    tcg_temp_free_i32(tmp);
1471 ac316ca4 Richard Henderson
}
1472 ac316ca4 Richard Henderson
1473 2ace7e55 Richard Henderson
static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
1474 2ace7e55 Richard Henderson
{
1475 2ace7e55 Richard Henderson
    /* We're emulating OSF/1 PALcode.  Many of these are trivial access
1476 2ace7e55 Richard Henderson
       to internal cpu registers.  */
1477 2ace7e55 Richard Henderson
1478 2ace7e55 Richard Henderson
    /* Unprivileged PAL call */
1479 2ace7e55 Richard Henderson
    if (palcode >= 0x80 && palcode < 0xC0) {
1480 2ace7e55 Richard Henderson
        switch (palcode) {
1481 2ace7e55 Richard Henderson
        case 0x86:
1482 2ace7e55 Richard Henderson
            /* IMB */
1483 2ace7e55 Richard Henderson
            /* No-op inside QEMU.  */
1484 2ace7e55 Richard Henderson
            break;
1485 2ace7e55 Richard Henderson
        case 0x9E:
1486 2ace7e55 Richard Henderson
            /* RDUNIQUE */
1487 2ace7e55 Richard Henderson
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
1488 2ace7e55 Richard Henderson
            break;
1489 2ace7e55 Richard Henderson
        case 0x9F:
1490 2ace7e55 Richard Henderson
            /* WRUNIQUE */
1491 2ace7e55 Richard Henderson
            tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
1492 2ace7e55 Richard Henderson
            break;
1493 2ace7e55 Richard Henderson
        default:
1494 2ace7e55 Richard Henderson
            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf);
1495 2ace7e55 Richard Henderson
        }
1496 2ace7e55 Richard Henderson
        return NO_EXIT;
1497 2ace7e55 Richard Henderson
    }
1498 2ace7e55 Richard Henderson
1499 2ace7e55 Richard Henderson
#ifndef CONFIG_USER_ONLY
1500 2ace7e55 Richard Henderson
    /* Privileged PAL code */
1501 2ace7e55 Richard Henderson
    if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
1502 2ace7e55 Richard Henderson
        switch (palcode) {
1503 2ace7e55 Richard Henderson
        case 0x01:
1504 2ace7e55 Richard Henderson
            /* CFLUSH */
1505 2ace7e55 Richard Henderson
            /* No-op inside QEMU.  */
1506 2ace7e55 Richard Henderson
            break;
1507 2ace7e55 Richard Henderson
        case 0x02:
1508 2ace7e55 Richard Henderson
            /* DRAINA */
1509 2ace7e55 Richard Henderson
            /* No-op inside QEMU.  */
1510 2ace7e55 Richard Henderson
            break;
1511 2ace7e55 Richard Henderson
        case 0x2D:
1512 2ace7e55 Richard Henderson
            /* WRVPTPTR */
1513 2ace7e55 Richard Henderson
            tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUState, vptptr));
1514 2ace7e55 Richard Henderson
            break;
1515 2ace7e55 Richard Henderson
        case 0x31:
1516 2ace7e55 Richard Henderson
            /* WRVAL */
1517 2ace7e55 Richard Henderson
            tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
1518 2ace7e55 Richard Henderson
            break;
1519 2ace7e55 Richard Henderson
        case 0x32:
1520 2ace7e55 Richard Henderson
            /* RDVAL */
1521 2ace7e55 Richard Henderson
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
1522 2ace7e55 Richard Henderson
            break;
1523 2ace7e55 Richard Henderson
1524 2ace7e55 Richard Henderson
        case 0x35: {
1525 2ace7e55 Richard Henderson
            /* SWPIPL */
1526 2ace7e55 Richard Henderson
            TCGv tmp;
1527 2ace7e55 Richard Henderson
1528 2ace7e55 Richard Henderson
            /* Note that we already know we're in kernel mode, so we know
1529 2ace7e55 Richard Henderson
               that PS only contains the 3 IPL bits.  */
1530 2ace7e55 Richard Henderson
            tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
1531 2ace7e55 Richard Henderson
1532 2ace7e55 Richard Henderson
            /* But make sure and store only the 3 IPL bits from the user.  */
1533 2ace7e55 Richard Henderson
            tmp = tcg_temp_new();
1534 2ace7e55 Richard Henderson
            tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
1535 2ace7e55 Richard Henderson
            tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUState, ps));
1536 2ace7e55 Richard Henderson
            tcg_temp_free(tmp);
1537 2ace7e55 Richard Henderson
            break;
1538 2ace7e55 Richard Henderson
        }
1539 2ace7e55 Richard Henderson
1540 2ace7e55 Richard Henderson
        case 0x36:
1541 2ace7e55 Richard Henderson
            /* RDPS */
1542 2ace7e55 Richard Henderson
            tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
1543 2ace7e55 Richard Henderson
            break;
1544 2ace7e55 Richard Henderson
        case 0x38:
1545 2ace7e55 Richard Henderson
            /* WRUSP */
1546 2ace7e55 Richard Henderson
            tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
1547 2ace7e55 Richard Henderson
            break;
1548 2ace7e55 Richard Henderson
        case 0x3A:
1549 2ace7e55 Richard Henderson
            /* RDUSP */
1550 2ace7e55 Richard Henderson
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
1551 2ace7e55 Richard Henderson
            break;
1552 2ace7e55 Richard Henderson
        case 0x3C:
1553 2ace7e55 Richard Henderson
            /* WHAMI */
1554 2ace7e55 Richard Henderson
            tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
1555 2ace7e55 Richard Henderson
                              offsetof(CPUState, cpu_index));
1556 2ace7e55 Richard Henderson
            break;
1557 2ace7e55 Richard Henderson
1558 2ace7e55 Richard Henderson
        default:
1559 2ace7e55 Richard Henderson
            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f);
1560 2ace7e55 Richard Henderson
        }
1561 2ace7e55 Richard Henderson
        return NO_EXIT;
1562 2ace7e55 Richard Henderson
    }
1563 2ace7e55 Richard Henderson
#endif
1564 2ace7e55 Richard Henderson
1565 2ace7e55 Richard Henderson
    return gen_invalid(ctx);
1566 2ace7e55 Richard Henderson
}
1567 2ace7e55 Richard Henderson
1568 26b46094 Richard Henderson
#ifndef CONFIG_USER_ONLY
1569 26b46094 Richard Henderson
1570 26b46094 Richard Henderson
#define PR_BYTE         0x100000
1571 26b46094 Richard Henderson
#define PR_LONG         0x200000
1572 26b46094 Richard Henderson
1573 26b46094 Richard Henderson
static int cpu_pr_data(int pr)
1574 26b46094 Richard Henderson
{
1575 26b46094 Richard Henderson
    switch (pr) {
1576 26b46094 Richard Henderson
    case  0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
1577 26b46094 Richard Henderson
    case  1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
1578 26b46094 Richard Henderson
    case  2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1579 26b46094 Richard Henderson
    case  3: return offsetof(CPUAlphaState, trap_arg0);
1580 26b46094 Richard Henderson
    case  4: return offsetof(CPUAlphaState, trap_arg1);
1581 26b46094 Richard Henderson
    case  5: return offsetof(CPUAlphaState, trap_arg2);
1582 26b46094 Richard Henderson
    case  6: return offsetof(CPUAlphaState, exc_addr);
1583 26b46094 Richard Henderson
    case  7: return offsetof(CPUAlphaState, palbr);
1584 26b46094 Richard Henderson
    case  8: return offsetof(CPUAlphaState, ptbr);
1585 26b46094 Richard Henderson
    case  9: return offsetof(CPUAlphaState, vptptr);
1586 26b46094 Richard Henderson
    case 10: return offsetof(CPUAlphaState, unique);
1587 26b46094 Richard Henderson
    case 11: return offsetof(CPUAlphaState, sysval);
1588 26b46094 Richard Henderson
    case 12: return offsetof(CPUAlphaState, usp);
1589 26b46094 Richard Henderson
1590 26b46094 Richard Henderson
    case 32 ... 39:
1591 26b46094 Richard Henderson
        return offsetof(CPUAlphaState, shadow[pr - 32]);
1592 26b46094 Richard Henderson
    case 40 ... 63:
1593 26b46094 Richard Henderson
        return offsetof(CPUAlphaState, scratch[pr - 40]);
1594 26b46094 Richard Henderson
    }
1595 26b46094 Richard Henderson
    return 0;
1596 26b46094 Richard Henderson
}
1597 26b46094 Richard Henderson
1598 26b46094 Richard Henderson
static void gen_mfpr(int ra, int regno)
1599 26b46094 Richard Henderson
{
1600 26b46094 Richard Henderson
    int data = cpu_pr_data(regno);
1601 26b46094 Richard Henderson
1602 26b46094 Richard Henderson
    /* In our emulated PALcode, these processor registers have no
1603 26b46094 Richard Henderson
       side effects from reading.  */
1604 26b46094 Richard Henderson
    if (ra == 31) {
1605 26b46094 Richard Henderson
        return;
1606 26b46094 Richard Henderson
    }
1607 26b46094 Richard Henderson
1608 26b46094 Richard Henderson
    /* The basic registers are data only, and unknown registers
1609 26b46094 Richard Henderson
       are read-zero, write-ignore.  */
1610 26b46094 Richard Henderson
    if (data == 0) {
1611 26b46094 Richard Henderson
        tcg_gen_movi_i64(cpu_ir[ra], 0);
1612 26b46094 Richard Henderson
    } else if (data & PR_BYTE) {
1613 26b46094 Richard Henderson
        tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE);
1614 26b46094 Richard Henderson
    } else if (data & PR_LONG) {
1615 26b46094 Richard Henderson
        tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG);
1616 26b46094 Richard Henderson
    } else {
1617 26b46094 Richard Henderson
        tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data);
1618 26b46094 Richard Henderson
    }
1619 26b46094 Richard Henderson
}
1620 26b46094 Richard Henderson
1621 26b46094 Richard Henderson
static void gen_mtpr(int rb, int regno)
1622 26b46094 Richard Henderson
{
1623 26b46094 Richard Henderson
    TCGv tmp;
1624 26b46094 Richard Henderson
    int data;
1625 26b46094 Richard Henderson
1626 26b46094 Richard Henderson
    if (rb == 31) {
1627 26b46094 Richard Henderson
        tmp = tcg_const_i64(0);
1628 26b46094 Richard Henderson
    } else {
1629 26b46094 Richard Henderson
        tmp = cpu_ir[rb];
1630 26b46094 Richard Henderson
    }
1631 26b46094 Richard Henderson
1632 26b46094 Richard Henderson
    /* The basic registers are data only, and unknown registers
1633 26b46094 Richard Henderson
       are read-zero, write-ignore.  */
1634 26b46094 Richard Henderson
    data = cpu_pr_data(regno);
1635 26b46094 Richard Henderson
    if (data != 0) {
1636 26b46094 Richard Henderson
        if (data & PR_BYTE) {
1637 26b46094 Richard Henderson
            tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
1638 26b46094 Richard Henderson
        } else if (data & PR_LONG) {
1639 26b46094 Richard Henderson
            tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
1640 26b46094 Richard Henderson
        } else {
1641 26b46094 Richard Henderson
            tcg_gen_st_i64(tmp, cpu_env, data);
1642 26b46094 Richard Henderson
        }
1643 26b46094 Richard Henderson
    }
1644 26b46094 Richard Henderson
1645 26b46094 Richard Henderson
    if (rb == 31) {
1646 26b46094 Richard Henderson
        tcg_temp_free(tmp);
1647 26b46094 Richard Henderson
    }
1648 26b46094 Richard Henderson
}
1649 26b46094 Richard Henderson
#endif /* !USER_ONLY*/
1650 26b46094 Richard Henderson
1651 4af70374 Richard Henderson
static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
1652 4c9649a9 j_mayer
{
1653 4c9649a9 j_mayer
    uint32_t palcode;
1654 4c9649a9 j_mayer
    int32_t disp21, disp16, disp12;
1655 f88fe4e3 Blue Swirl
    uint16_t fn11;
1656 f88fe4e3 Blue Swirl
    uint8_t opc, ra, rb, rc, fpfn, fn7, fn2, islit, real_islit;
1657 adf3c8b6 aurel32
    uint8_t lit;
1658 4af70374 Richard Henderson
    ExitStatus ret;
1659 4c9649a9 j_mayer
1660 4c9649a9 j_mayer
    /* Decode all instruction fields */
1661 4c9649a9 j_mayer
    opc = insn >> 26;
1662 4c9649a9 j_mayer
    ra = (insn >> 21) & 0x1F;
1663 4c9649a9 j_mayer
    rb = (insn >> 16) & 0x1F;
1664 4c9649a9 j_mayer
    rc = insn & 0x1F;
1665 13e4df99 Richard Henderson
    real_islit = islit = (insn >> 12) & 1;
1666 dfaa8583 aurel32
    if (rb == 31 && !islit) {
1667 dfaa8583 aurel32
        islit = 1;
1668 dfaa8583 aurel32
        lit = 0;
1669 dfaa8583 aurel32
    } else
1670 dfaa8583 aurel32
        lit = (insn >> 13) & 0xFF;
1671 4c9649a9 j_mayer
    palcode = insn & 0x03FFFFFF;
1672 4c9649a9 j_mayer
    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
1673 4c9649a9 j_mayer
    disp16 = (int16_t)(insn & 0x0000FFFF);
1674 4c9649a9 j_mayer
    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
1675 4c9649a9 j_mayer
    fn11 = (insn >> 5) & 0x000007FF;
1676 4c9649a9 j_mayer
    fpfn = fn11 & 0x3F;
1677 4c9649a9 j_mayer
    fn7 = (insn >> 5) & 0x0000007F;
1678 4c9649a9 j_mayer
    fn2 = (insn >> 5) & 0x00000003;
1679 806991da Richard Henderson
    LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
1680 d12d51d5 aliguori
              opc, ra, rb, rc, disp16);
1681 806991da Richard Henderson
1682 4af70374 Richard Henderson
    ret = NO_EXIT;
1683 4c9649a9 j_mayer
    switch (opc) {
1684 4c9649a9 j_mayer
    case 0x00:
1685 4c9649a9 j_mayer
        /* CALL_PAL */
1686 2ace7e55 Richard Henderson
        ret = gen_call_pal(ctx, palcode);
1687 2ace7e55 Richard Henderson
        break;
1688 4c9649a9 j_mayer
    case 0x01:
1689 4c9649a9 j_mayer
        /* OPC01 */
1690 4c9649a9 j_mayer
        goto invalid_opc;
1691 4c9649a9 j_mayer
    case 0x02:
1692 4c9649a9 j_mayer
        /* OPC02 */
1693 4c9649a9 j_mayer
        goto invalid_opc;
1694 4c9649a9 j_mayer
    case 0x03:
1695 4c9649a9 j_mayer
        /* OPC03 */
1696 4c9649a9 j_mayer
        goto invalid_opc;
1697 4c9649a9 j_mayer
    case 0x04:
1698 4c9649a9 j_mayer
        /* OPC04 */
1699 4c9649a9 j_mayer
        goto invalid_opc;
1700 4c9649a9 j_mayer
    case 0x05:
1701 4c9649a9 j_mayer
        /* OPC05 */
1702 4c9649a9 j_mayer
        goto invalid_opc;
1703 4c9649a9 j_mayer
    case 0x06:
1704 4c9649a9 j_mayer
        /* OPC06 */
1705 4c9649a9 j_mayer
        goto invalid_opc;
1706 4c9649a9 j_mayer
    case 0x07:
1707 4c9649a9 j_mayer
        /* OPC07 */
1708 4c9649a9 j_mayer
        goto invalid_opc;
1709 4c9649a9 j_mayer
    case 0x08:
1710 4c9649a9 j_mayer
        /* LDA */
1711 1ef4ef4e aurel32
        if (likely(ra != 31)) {
1712 496cb5b9 aurel32
            if (rb != 31)
1713 3761035f aurel32
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
1714 3761035f aurel32
            else
1715 3761035f aurel32
                tcg_gen_movi_i64(cpu_ir[ra], disp16);
1716 496cb5b9 aurel32
        }
1717 4c9649a9 j_mayer
        break;
1718 4c9649a9 j_mayer
    case 0x09:
1719 4c9649a9 j_mayer
        /* LDAH */
1720 1ef4ef4e aurel32
        if (likely(ra != 31)) {
1721 496cb5b9 aurel32
            if (rb != 31)
1722 3761035f aurel32
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
1723 3761035f aurel32
            else
1724 3761035f aurel32
                tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
1725 496cb5b9 aurel32
        }
1726 4c9649a9 j_mayer
        break;
1727 4c9649a9 j_mayer
    case 0x0A:
1728 4c9649a9 j_mayer
        /* LDBU */
1729 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1730 a18ad893 Richard Henderson
            gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1731 a18ad893 Richard Henderson
            break;
1732 a18ad893 Richard Henderson
        }
1733 a18ad893 Richard Henderson
        goto invalid_opc;
1734 4c9649a9 j_mayer
    case 0x0B:
1735 4c9649a9 j_mayer
        /* LDQ_U */
1736 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1737 4c9649a9 j_mayer
        break;
1738 4c9649a9 j_mayer
    case 0x0C:
1739 4c9649a9 j_mayer
        /* LDWU */
1740 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1741 a18ad893 Richard Henderson
            gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1742 a18ad893 Richard Henderson
            break;
1743 a18ad893 Richard Henderson
        }
1744 a18ad893 Richard Henderson
        goto invalid_opc;
1745 4c9649a9 j_mayer
    case 0x0D:
1746 4c9649a9 j_mayer
        /* STW */
1747 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1748 4c9649a9 j_mayer
        break;
1749 4c9649a9 j_mayer
    case 0x0E:
1750 4c9649a9 j_mayer
        /* STB */
1751 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1752 4c9649a9 j_mayer
        break;
1753 4c9649a9 j_mayer
    case 0x0F:
1754 4c9649a9 j_mayer
        /* STQ_U */
1755 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1756 4c9649a9 j_mayer
        break;
1757 4c9649a9 j_mayer
    case 0x10:
1758 4c9649a9 j_mayer
        switch (fn7) {
1759 4c9649a9 j_mayer
        case 0x00:
1760 4c9649a9 j_mayer
            /* ADDL */
1761 30c7183b aurel32
            if (likely(rc != 31)) {
1762 30c7183b aurel32
                if (ra != 31) {
1763 30c7183b aurel32
                    if (islit) {
1764 30c7183b aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1765 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1766 dfaa8583 aurel32
                    } else {
1767 30c7183b aurel32
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1768 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1769 dfaa8583 aurel32
                    }
1770 30c7183b aurel32
                } else {
1771 30c7183b aurel32
                    if (islit)
1772 dfaa8583 aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1773 30c7183b aurel32
                    else
1774 dfaa8583 aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1775 30c7183b aurel32
                }
1776 30c7183b aurel32
            }
1777 4c9649a9 j_mayer
            break;
1778 4c9649a9 j_mayer
        case 0x02:
1779 4c9649a9 j_mayer
            /* S4ADDL */
1780 30c7183b aurel32
            if (likely(rc != 31)) {
1781 30c7183b aurel32
                if (ra != 31) {
1782 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1783 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1784 dfaa8583 aurel32
                    if (islit)
1785 dfaa8583 aurel32
                        tcg_gen_addi_i64(tmp, tmp, lit);
1786 dfaa8583 aurel32
                    else
1787 dfaa8583 aurel32
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1788 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1789 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1790 30c7183b aurel32
                } else {
1791 30c7183b aurel32
                    if (islit)
1792 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1793 30c7183b aurel32
                    else
1794 dfaa8583 aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1795 30c7183b aurel32
                }
1796 30c7183b aurel32
            }
1797 4c9649a9 j_mayer
            break;
1798 4c9649a9 j_mayer
        case 0x09:
1799 4c9649a9 j_mayer
            /* SUBL */
1800 30c7183b aurel32
            if (likely(rc != 31)) {
1801 30c7183b aurel32
                if (ra != 31) {
1802 dfaa8583 aurel32
                    if (islit)
1803 30c7183b aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1804 dfaa8583 aurel32
                    else
1805 30c7183b aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1806 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1807 30c7183b aurel32
                } else {
1808 30c7183b aurel32
                    if (islit)
1809 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1810 dfaa8583 aurel32
                    else {
1811 30c7183b aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1812 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1813 30c7183b aurel32
                }
1814 30c7183b aurel32
            }
1815 4c9649a9 j_mayer
            break;
1816 4c9649a9 j_mayer
        case 0x0B:
1817 4c9649a9 j_mayer
            /* S4SUBL */
1818 30c7183b aurel32
            if (likely(rc != 31)) {
1819 30c7183b aurel32
                if (ra != 31) {
1820 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1821 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1822 dfaa8583 aurel32
                    if (islit)
1823 dfaa8583 aurel32
                        tcg_gen_subi_i64(tmp, tmp, lit);
1824 dfaa8583 aurel32
                    else
1825 dfaa8583 aurel32
                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1826 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1827 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1828 30c7183b aurel32
                } else {
1829 30c7183b aurel32
                    if (islit)
1830 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1831 dfaa8583 aurel32
                    else {
1832 30c7183b aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1833 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1834 dfaa8583 aurel32
                    }
1835 30c7183b aurel32
                }
1836 30c7183b aurel32
            }
1837 4c9649a9 j_mayer
            break;
1838 4c9649a9 j_mayer
        case 0x0F:
1839 4c9649a9 j_mayer
            /* CMPBGE */
1840 a7812ae4 pbrook
            gen_cmpbge(ra, rb, rc, islit, lit);
1841 4c9649a9 j_mayer
            break;
1842 4c9649a9 j_mayer
        case 0x12:
1843 4c9649a9 j_mayer
            /* S8ADDL */
1844 30c7183b aurel32
            if (likely(rc != 31)) {
1845 30c7183b aurel32
                if (ra != 31) {
1846 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1847 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1848 dfaa8583 aurel32
                    if (islit)
1849 dfaa8583 aurel32
                        tcg_gen_addi_i64(tmp, tmp, lit);
1850 dfaa8583 aurel32
                    else
1851 dfaa8583 aurel32
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1852 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1853 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1854 30c7183b aurel32
                } else {
1855 30c7183b aurel32
                    if (islit)
1856 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1857 30c7183b aurel32
                    else
1858 dfaa8583 aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1859 30c7183b aurel32
                }
1860 30c7183b aurel32
            }
1861 4c9649a9 j_mayer
            break;
1862 4c9649a9 j_mayer
        case 0x1B:
1863 4c9649a9 j_mayer
            /* S8SUBL */
1864 30c7183b aurel32
            if (likely(rc != 31)) {
1865 30c7183b aurel32
                if (ra != 31) {
1866 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1867 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1868 dfaa8583 aurel32
                    if (islit)
1869 dfaa8583 aurel32
                        tcg_gen_subi_i64(tmp, tmp, lit);
1870 dfaa8583 aurel32
                    else
1871 dfaa8583 aurel32
                       tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1872 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1873 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1874 30c7183b aurel32
                } else {
1875 30c7183b aurel32
                    if (islit)
1876 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1877 dfaa8583 aurel32
                    else
1878 30c7183b aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1879 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1880 dfaa8583 aurel32
                    }
1881 30c7183b aurel32
                }
1882 30c7183b aurel32
            }
1883 4c9649a9 j_mayer
            break;
1884 4c9649a9 j_mayer
        case 0x1D:
1885 4c9649a9 j_mayer
            /* CMPULT */
1886 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
1887 4c9649a9 j_mayer
            break;
1888 4c9649a9 j_mayer
        case 0x20:
1889 4c9649a9 j_mayer
            /* ADDQ */
1890 30c7183b aurel32
            if (likely(rc != 31)) {
1891 30c7183b aurel32
                if (ra != 31) {
1892 30c7183b aurel32
                    if (islit)
1893 30c7183b aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1894 30c7183b aurel32
                    else
1895 dfaa8583 aurel32
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1896 30c7183b aurel32
                } else {
1897 30c7183b aurel32
                    if (islit)
1898 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1899 30c7183b aurel32
                    else
1900 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1901 30c7183b aurel32
                }
1902 30c7183b aurel32
            }
1903 4c9649a9 j_mayer
            break;
1904 4c9649a9 j_mayer
        case 0x22:
1905 4c9649a9 j_mayer
            /* S4ADDQ */
1906 30c7183b aurel32
            if (likely(rc != 31)) {
1907 30c7183b aurel32
                if (ra != 31) {
1908 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1909 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1910 dfaa8583 aurel32
                    if (islit)
1911 dfaa8583 aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1912 dfaa8583 aurel32
                    else
1913 dfaa8583 aurel32
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1914 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1915 30c7183b aurel32
                } else {
1916 30c7183b aurel32
                    if (islit)
1917 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1918 30c7183b aurel32
                    else
1919 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1920 30c7183b aurel32
                }
1921 30c7183b aurel32
            }
1922 4c9649a9 j_mayer
            break;
1923 4c9649a9 j_mayer
        case 0x29:
1924 4c9649a9 j_mayer
            /* SUBQ */
1925 30c7183b aurel32
            if (likely(rc != 31)) {
1926 30c7183b aurel32
                if (ra != 31) {
1927 30c7183b aurel32
                    if (islit)
1928 30c7183b aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1929 30c7183b aurel32
                    else
1930 dfaa8583 aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1931 30c7183b aurel32
                } else {
1932 30c7183b aurel32
                    if (islit)
1933 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1934 30c7183b aurel32
                    else
1935 dfaa8583 aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1936 30c7183b aurel32
                }
1937 30c7183b aurel32
            }
1938 4c9649a9 j_mayer
            break;
1939 4c9649a9 j_mayer
        case 0x2B:
1940 4c9649a9 j_mayer
            /* S4SUBQ */
1941 30c7183b aurel32
            if (likely(rc != 31)) {
1942 30c7183b aurel32
                if (ra != 31) {
1943 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1944 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1945 dfaa8583 aurel32
                    if (islit)
1946 dfaa8583 aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
1947 dfaa8583 aurel32
                    else
1948 dfaa8583 aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1949 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1950 30c7183b aurel32
                } else {
1951 30c7183b aurel32
                    if (islit)
1952 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1953 30c7183b aurel32
                    else
1954 dfaa8583 aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1955 30c7183b aurel32
                }
1956 30c7183b aurel32
            }
1957 4c9649a9 j_mayer
            break;
1958 4c9649a9 j_mayer
        case 0x2D:
1959 4c9649a9 j_mayer
            /* CMPEQ */
1960 01ff9cc8 aurel32
            gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
1961 4c9649a9 j_mayer
            break;
1962 4c9649a9 j_mayer
        case 0x32:
1963 4c9649a9 j_mayer
            /* S8ADDQ */
1964 30c7183b aurel32
            if (likely(rc != 31)) {
1965 30c7183b aurel32
                if (ra != 31) {
1966 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1967 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1968 dfaa8583 aurel32
                    if (islit)
1969 dfaa8583 aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1970 dfaa8583 aurel32
                    else
1971 dfaa8583 aurel32
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1972 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1973 30c7183b aurel32
                } else {
1974 30c7183b aurel32
                    if (islit)
1975 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1976 30c7183b aurel32
                    else
1977 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1978 30c7183b aurel32
                }
1979 30c7183b aurel32
            }
1980 4c9649a9 j_mayer
            break;
1981 4c9649a9 j_mayer
        case 0x3B:
1982 4c9649a9 j_mayer
            /* S8SUBQ */
1983 30c7183b aurel32
            if (likely(rc != 31)) {
1984 30c7183b aurel32
                if (ra != 31) {
1985 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1986 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1987 dfaa8583 aurel32
                    if (islit)
1988 dfaa8583 aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
1989 dfaa8583 aurel32
                    else
1990 dfaa8583 aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1991 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1992 30c7183b aurel32
                } else {
1993 30c7183b aurel32
                    if (islit)
1994 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1995 30c7183b aurel32
                    else
1996 dfaa8583 aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1997 30c7183b aurel32
                }
1998 30c7183b aurel32
            }
1999 4c9649a9 j_mayer
            break;
2000 4c9649a9 j_mayer
        case 0x3D:
2001 4c9649a9 j_mayer
            /* CMPULE */
2002 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
2003 4c9649a9 j_mayer
            break;
2004 4c9649a9 j_mayer
        case 0x40:
2005 4c9649a9 j_mayer
            /* ADDL/V */
2006 a7812ae4 pbrook
            gen_addlv(ra, rb, rc, islit, lit);
2007 4c9649a9 j_mayer
            break;
2008 4c9649a9 j_mayer
        case 0x49:
2009 4c9649a9 j_mayer
            /* SUBL/V */
2010 a7812ae4 pbrook
            gen_sublv(ra, rb, rc, islit, lit);
2011 4c9649a9 j_mayer
            break;
2012 4c9649a9 j_mayer
        case 0x4D:
2013 4c9649a9 j_mayer
            /* CMPLT */
2014 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
2015 4c9649a9 j_mayer
            break;
2016 4c9649a9 j_mayer
        case 0x60:
2017 4c9649a9 j_mayer
            /* ADDQ/V */
2018 a7812ae4 pbrook
            gen_addqv(ra, rb, rc, islit, lit);
2019 4c9649a9 j_mayer
            break;
2020 4c9649a9 j_mayer
        case 0x69:
2021 4c9649a9 j_mayer
            /* SUBQ/V */
2022 a7812ae4 pbrook
            gen_subqv(ra, rb, rc, islit, lit);
2023 4c9649a9 j_mayer
            break;
2024 4c9649a9 j_mayer
        case 0x6D:
2025 4c9649a9 j_mayer
            /* CMPLE */
2026 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
2027 4c9649a9 j_mayer
            break;
2028 4c9649a9 j_mayer
        default:
2029 4c9649a9 j_mayer
            goto invalid_opc;
2030 4c9649a9 j_mayer
        }
2031 4c9649a9 j_mayer
        break;
2032 4c9649a9 j_mayer
    case 0x11:
2033 4c9649a9 j_mayer
        switch (fn7) {
2034 4c9649a9 j_mayer
        case 0x00:
2035 4c9649a9 j_mayer
            /* AND */
2036 30c7183b aurel32
            if (likely(rc != 31)) {
2037 dfaa8583 aurel32
                if (ra == 31)
2038 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2039 30c7183b aurel32
                else if (islit)
2040 30c7183b aurel32
                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2041 30c7183b aurel32
                else
2042 30c7183b aurel32
                    tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2043 30c7183b aurel32
            }
2044 4c9649a9 j_mayer
            break;
2045 4c9649a9 j_mayer
        case 0x08:
2046 4c9649a9 j_mayer
            /* BIC */
2047 30c7183b aurel32
            if (likely(rc != 31)) {
2048 30c7183b aurel32
                if (ra != 31) {
2049 30c7183b aurel32
                    if (islit)
2050 30c7183b aurel32
                        tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2051 1b581c44 aurel32
                    else
2052 1b581c44 aurel32
                        tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2053 30c7183b aurel32
                } else
2054 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2055 30c7183b aurel32
            }
2056 4c9649a9 j_mayer
            break;
2057 4c9649a9 j_mayer
        case 0x14:
2058 4c9649a9 j_mayer
            /* CMOVLBS */
2059 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
2060 4c9649a9 j_mayer
            break;
2061 4c9649a9 j_mayer
        case 0x16:
2062 4c9649a9 j_mayer
            /* CMOVLBC */
2063 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
2064 4c9649a9 j_mayer
            break;
2065 4c9649a9 j_mayer
        case 0x20:
2066 4c9649a9 j_mayer
            /* BIS */
2067 30c7183b aurel32
            if (likely(rc != 31)) {
2068 30c7183b aurel32
                if (ra != 31) {
2069 30c7183b aurel32
                    if (islit)
2070 30c7183b aurel32
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2071 8bb6e981 aurel32
                    else
2072 30c7183b aurel32
                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2073 4c9649a9 j_mayer
                } else {
2074 30c7183b aurel32
                    if (islit)
2075 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
2076 30c7183b aurel32
                    else
2077 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2078 4c9649a9 j_mayer
                }
2079 4c9649a9 j_mayer
            }
2080 4c9649a9 j_mayer
            break;
2081 4c9649a9 j_mayer
        case 0x24:
2082 4c9649a9 j_mayer
            /* CMOVEQ */
2083 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
2084 4c9649a9 j_mayer
            break;
2085 4c9649a9 j_mayer
        case 0x26:
2086 4c9649a9 j_mayer
            /* CMOVNE */
2087 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
2088 4c9649a9 j_mayer
            break;
2089 4c9649a9 j_mayer
        case 0x28:
2090 4c9649a9 j_mayer
            /* ORNOT */
2091 30c7183b aurel32
            if (likely(rc != 31)) {
2092 dfaa8583 aurel32
                if (ra != 31) {
2093 30c7183b aurel32
                    if (islit)
2094 30c7183b aurel32
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2095 1b581c44 aurel32
                    else
2096 1b581c44 aurel32
                        tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2097 30c7183b aurel32
                } else {
2098 30c7183b aurel32
                    if (islit)
2099 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2100 30c7183b aurel32
                    else
2101 30c7183b aurel32
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2102 30c7183b aurel32
                }
2103 30c7183b aurel32
            }
2104 4c9649a9 j_mayer
            break;
2105 4c9649a9 j_mayer
        case 0x40:
2106 4c9649a9 j_mayer
            /* XOR */
2107 30c7183b aurel32
            if (likely(rc != 31)) {
2108 30c7183b aurel32
                if (ra != 31) {
2109 30c7183b aurel32
                    if (islit)
2110 30c7183b aurel32
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2111 30c7183b aurel32
                    else
2112 dfaa8583 aurel32
                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2113 30c7183b aurel32
                } else {
2114 30c7183b aurel32
                    if (islit)
2115 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
2116 30c7183b aurel32
                    else
2117 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2118 30c7183b aurel32
                }
2119 30c7183b aurel32
            }
2120 4c9649a9 j_mayer
            break;
2121 4c9649a9 j_mayer
        case 0x44:
2122 4c9649a9 j_mayer
            /* CMOVLT */
2123 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
2124 4c9649a9 j_mayer
            break;
2125 4c9649a9 j_mayer
        case 0x46:
2126 4c9649a9 j_mayer
            /* CMOVGE */
2127 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
2128 4c9649a9 j_mayer
            break;
2129 4c9649a9 j_mayer
        case 0x48:
2130 4c9649a9 j_mayer
            /* EQV */
2131 30c7183b aurel32
            if (likely(rc != 31)) {
2132 30c7183b aurel32
                if (ra != 31) {
2133 30c7183b aurel32
                    if (islit)
2134 30c7183b aurel32
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2135 1b581c44 aurel32
                    else
2136 1b581c44 aurel32
                        tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2137 30c7183b aurel32
                } else {
2138 30c7183b aurel32
                    if (islit)
2139 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2140 30c7183b aurel32
                    else
2141 dfaa8583 aurel32
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2142 30c7183b aurel32
                }
2143 30c7183b aurel32
            }
2144 4c9649a9 j_mayer
            break;
2145 4c9649a9 j_mayer
        case 0x61:
2146 4c9649a9 j_mayer
            /* AMASK */
2147 ae8ecd42 aurel32
            if (likely(rc != 31)) {
2148 a18ad893 Richard Henderson
                uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
2149 a18ad893 Richard Henderson
2150 a18ad893 Richard Henderson
                if (islit) {
2151 a18ad893 Richard Henderson
                    tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
2152 a18ad893 Richard Henderson
                } else {
2153 a18ad893 Richard Henderson
                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
2154 1a1f7dbc aurel32
                }
2155 ae8ecd42 aurel32
            }
2156 4c9649a9 j_mayer
            break;
2157 4c9649a9 j_mayer
        case 0x64:
2158 4c9649a9 j_mayer
            /* CMOVLE */
2159 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
2160 4c9649a9 j_mayer
            break;
2161 4c9649a9 j_mayer
        case 0x66:
2162 4c9649a9 j_mayer
            /* CMOVGT */
2163 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
2164 4c9649a9 j_mayer
            break;
2165 4c9649a9 j_mayer
        case 0x6C:
2166 4c9649a9 j_mayer
            /* IMPLVER */
2167 3761035f aurel32
            if (rc != 31)
2168 8579095b aurel32
                tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
2169 4c9649a9 j_mayer
            break;
2170 4c9649a9 j_mayer
        default:
2171 4c9649a9 j_mayer
            goto invalid_opc;
2172 4c9649a9 j_mayer
        }
2173 4c9649a9 j_mayer
        break;
2174 4c9649a9 j_mayer
    case 0x12:
2175 4c9649a9 j_mayer
        switch (fn7) {
2176 4c9649a9 j_mayer
        case 0x02:
2177 4c9649a9 j_mayer
            /* MSKBL */
2178 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0x01);
2179 4c9649a9 j_mayer
            break;
2180 4c9649a9 j_mayer
        case 0x06:
2181 4c9649a9 j_mayer
            /* EXTBL */
2182 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0x01);
2183 4c9649a9 j_mayer
            break;
2184 4c9649a9 j_mayer
        case 0x0B:
2185 4c9649a9 j_mayer
            /* INSBL */
2186 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0x01);
2187 4c9649a9 j_mayer
            break;
2188 4c9649a9 j_mayer
        case 0x12:
2189 4c9649a9 j_mayer
            /* MSKWL */
2190 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0x03);
2191 4c9649a9 j_mayer
            break;
2192 4c9649a9 j_mayer
        case 0x16:
2193 4c9649a9 j_mayer
            /* EXTWL */
2194 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0x03);
2195 4c9649a9 j_mayer
            break;
2196 4c9649a9 j_mayer
        case 0x1B:
2197 4c9649a9 j_mayer
            /* INSWL */
2198 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0x03);
2199 4c9649a9 j_mayer
            break;
2200 4c9649a9 j_mayer
        case 0x22:
2201 4c9649a9 j_mayer
            /* MSKLL */
2202 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
2203 4c9649a9 j_mayer
            break;
2204 4c9649a9 j_mayer
        case 0x26:
2205 4c9649a9 j_mayer
            /* EXTLL */
2206 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
2207 4c9649a9 j_mayer
            break;
2208 4c9649a9 j_mayer
        case 0x2B:
2209 4c9649a9 j_mayer
            /* INSLL */
2210 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
2211 4c9649a9 j_mayer
            break;
2212 4c9649a9 j_mayer
        case 0x30:
2213 4c9649a9 j_mayer
            /* ZAP */
2214 a7812ae4 pbrook
            gen_zap(ra, rb, rc, islit, lit);
2215 4c9649a9 j_mayer
            break;
2216 4c9649a9 j_mayer
        case 0x31:
2217 4c9649a9 j_mayer
            /* ZAPNOT */
2218 a7812ae4 pbrook
            gen_zapnot(ra, rb, rc, islit, lit);
2219 4c9649a9 j_mayer
            break;
2220 4c9649a9 j_mayer
        case 0x32:
2221 4c9649a9 j_mayer
            /* MSKQL */
2222 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0xff);
2223 4c9649a9 j_mayer
            break;
2224 4c9649a9 j_mayer
        case 0x34:
2225 4c9649a9 j_mayer
            /* SRL */
2226 30c7183b aurel32
            if (likely(rc != 31)) {
2227 30c7183b aurel32
                if (ra != 31) {
2228 30c7183b aurel32
                    if (islit)
2229 30c7183b aurel32
                        tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2230 dfaa8583 aurel32
                    else {
2231 a7812ae4 pbrook
                        TCGv shift = tcg_temp_new();
2232 30c7183b aurel32
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2233 30c7183b aurel32
                        tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
2234 30c7183b aurel32
                        tcg_temp_free(shift);
2235 dfaa8583 aurel32
                    }
2236 30c7183b aurel32
                } else
2237 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2238 30c7183b aurel32
            }
2239 4c9649a9 j_mayer
            break;
2240 4c9649a9 j_mayer
        case 0x36:
2241 4c9649a9 j_mayer
            /* EXTQL */
2242 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0xff);
2243 4c9649a9 j_mayer
            break;
2244 4c9649a9 j_mayer
        case 0x39:
2245 4c9649a9 j_mayer
            /* SLL */
2246 30c7183b aurel32
            if (likely(rc != 31)) {
2247 30c7183b aurel32
                if (ra != 31) {
2248 30c7183b aurel32
                    if (islit)
2249 30c7183b aurel32
                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2250 dfaa8583 aurel32
                    else {
2251 a7812ae4 pbrook
                        TCGv shift = tcg_temp_new();
2252 30c7183b aurel32
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2253 30c7183b aurel32
                        tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
2254 30c7183b aurel32
                        tcg_temp_free(shift);
2255 dfaa8583 aurel32
                    }
2256 30c7183b aurel32
                } else
2257 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2258 30c7183b aurel32
            }
2259 4c9649a9 j_mayer
            break;
2260 4c9649a9 j_mayer
        case 0x3B:
2261 4c9649a9 j_mayer
            /* INSQL */
2262 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0xff);
2263 4c9649a9 j_mayer
            break;
2264 4c9649a9 j_mayer
        case 0x3C:
2265 4c9649a9 j_mayer
            /* SRA */
2266 30c7183b aurel32
            if (likely(rc != 31)) {
2267 30c7183b aurel32
                if (ra != 31) {
2268 30c7183b aurel32
                    if (islit)
2269 30c7183b aurel32
                        tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2270 dfaa8583 aurel32
                    else {
2271 a7812ae4 pbrook
                        TCGv shift = tcg_temp_new();
2272 30c7183b aurel32
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2273 30c7183b aurel32
                        tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
2274 30c7183b aurel32
                        tcg_temp_free(shift);
2275 dfaa8583 aurel32
                    }
2276 30c7183b aurel32
                } else
2277 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2278 30c7183b aurel32
            }
2279 4c9649a9 j_mayer
            break;
2280 4c9649a9 j_mayer
        case 0x52:
2281 4c9649a9 j_mayer
            /* MSKWH */
2282 ffec44f1 Richard Henderson
            gen_msk_h(ra, rb, rc, islit, lit, 0x03);
2283 4c9649a9 j_mayer
            break;
2284 4c9649a9 j_mayer
        case 0x57:
2285 4c9649a9 j_mayer
            /* INSWH */
2286 50eb6e5c Richard Henderson
            gen_ins_h(ra, rb, rc, islit, lit, 0x03);
2287 4c9649a9 j_mayer
            break;
2288 4c9649a9 j_mayer
        case 0x5A:
2289 4c9649a9 j_mayer
            /* EXTWH */
2290 377a43b6 Richard Henderson
            gen_ext_h(ra, rb, rc, islit, lit, 0x03);
2291 4c9649a9 j_mayer
            break;
2292 4c9649a9 j_mayer
        case 0x62:
2293 4c9649a9 j_mayer
            /* MSKLH */
2294 ffec44f1 Richard Henderson
            gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
2295 4c9649a9 j_mayer
            break;
2296 4c9649a9 j_mayer
        case 0x67:
2297 4c9649a9 j_mayer
            /* INSLH */
2298 50eb6e5c Richard Henderson
            gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
2299 4c9649a9 j_mayer
            break;
2300 4c9649a9 j_mayer
        case 0x6A:
2301 4c9649a9 j_mayer
            /* EXTLH */
2302 377a43b6 Richard Henderson
            gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
2303 4c9649a9 j_mayer
            break;
2304 4c9649a9 j_mayer
        case 0x72:
2305 4c9649a9 j_mayer
            /* MSKQH */
2306 ffec44f1 Richard Henderson
            gen_msk_h(ra, rb, rc, islit, lit, 0xff);
2307 4c9649a9 j_mayer
            break;
2308 4c9649a9 j_mayer
        case 0x77:
2309 4c9649a9 j_mayer
            /* INSQH */
2310 50eb6e5c Richard Henderson
            gen_ins_h(ra, rb, rc, islit, lit, 0xff);
2311 4c9649a9 j_mayer
            break;
2312 4c9649a9 j_mayer
        case 0x7A:
2313 4c9649a9 j_mayer
            /* EXTQH */
2314 377a43b6 Richard Henderson
            gen_ext_h(ra, rb, rc, islit, lit, 0xff);
2315 4c9649a9 j_mayer
            break;
2316 4c9649a9 j_mayer
        default:
2317 4c9649a9 j_mayer
            goto invalid_opc;
2318 4c9649a9 j_mayer
        }
2319 4c9649a9 j_mayer
        break;
2320 4c9649a9 j_mayer
    case 0x13:
2321 4c9649a9 j_mayer
        switch (fn7) {
2322 4c9649a9 j_mayer
        case 0x00:
2323 4c9649a9 j_mayer
            /* MULL */
2324 30c7183b aurel32
            if (likely(rc != 31)) {
2325 dfaa8583 aurel32
                if (ra == 31)
2326 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2327 30c7183b aurel32
                else {
2328 30c7183b aurel32
                    if (islit)
2329 30c7183b aurel32
                        tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2330 30c7183b aurel32
                    else
2331 30c7183b aurel32
                        tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2332 30c7183b aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
2333 30c7183b aurel32
                }
2334 30c7183b aurel32
            }
2335 4c9649a9 j_mayer
            break;
2336 4c9649a9 j_mayer
        case 0x20:
2337 4c9649a9 j_mayer
            /* MULQ */
2338 30c7183b aurel32
            if (likely(rc != 31)) {
2339 dfaa8583 aurel32
                if (ra == 31)
2340 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2341 30c7183b aurel32
                else if (islit)
2342 30c7183b aurel32
                    tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2343 30c7183b aurel32
                else
2344 30c7183b aurel32
                    tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2345 30c7183b aurel32
            }
2346 4c9649a9 j_mayer
            break;
2347 4c9649a9 j_mayer
        case 0x30:
2348 4c9649a9 j_mayer
            /* UMULH */
2349 a7812ae4 pbrook
            gen_umulh(ra, rb, rc, islit, lit);
2350 4c9649a9 j_mayer
            break;
2351 4c9649a9 j_mayer
        case 0x40:
2352 4c9649a9 j_mayer
            /* MULL/V */
2353 a7812ae4 pbrook
            gen_mullv(ra, rb, rc, islit, lit);
2354 4c9649a9 j_mayer
            break;
2355 4c9649a9 j_mayer
        case 0x60:
2356 4c9649a9 j_mayer
            /* MULQ/V */
2357 a7812ae4 pbrook
            gen_mulqv(ra, rb, rc, islit, lit);
2358 4c9649a9 j_mayer
            break;
2359 4c9649a9 j_mayer
        default:
2360 4c9649a9 j_mayer
            goto invalid_opc;
2361 4c9649a9 j_mayer
        }
2362 4c9649a9 j_mayer
        break;
2363 4c9649a9 j_mayer
    case 0x14:
2364 f24518b5 Richard Henderson
        switch (fpfn) { /* fn11 & 0x3F */
2365 4c9649a9 j_mayer
        case 0x04:
2366 4c9649a9 j_mayer
            /* ITOFS */
2367 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2368 4c9649a9 j_mayer
                goto invalid_opc;
2369 a18ad893 Richard Henderson
            }
2370 f18cd223 aurel32
            if (likely(rc != 31)) {
2371 f18cd223 aurel32
                if (ra != 31) {
2372 a7812ae4 pbrook
                    TCGv_i32 tmp = tcg_temp_new_i32();
2373 f18cd223 aurel32
                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2374 a7812ae4 pbrook
                    gen_helper_memory_to_s(cpu_fir[rc], tmp);
2375 a7812ae4 pbrook
                    tcg_temp_free_i32(tmp);
2376 f18cd223 aurel32
                } else
2377 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
2378 f18cd223 aurel32
            }
2379 4c9649a9 j_mayer
            break;
2380 4c9649a9 j_mayer
        case 0x0A:
2381 4c9649a9 j_mayer
            /* SQRTF */
2382 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2383 a18ad893 Richard Henderson
                gen_fsqrtf(rb, rc);
2384 a18ad893 Richard Henderson
                break;
2385 a18ad893 Richard Henderson
            }
2386 a18ad893 Richard Henderson
            goto invalid_opc;
2387 4c9649a9 j_mayer
        case 0x0B:
2388 4c9649a9 j_mayer
            /* SQRTS */
2389 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2390 a18ad893 Richard Henderson
                gen_fsqrts(ctx, rb, rc, fn11);
2391 a18ad893 Richard Henderson
                break;
2392 a18ad893 Richard Henderson
            }
2393 a18ad893 Richard Henderson
            goto invalid_opc;
2394 4c9649a9 j_mayer
        case 0x14:
2395 4c9649a9 j_mayer
            /* ITOFF */
2396 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2397 4c9649a9 j_mayer
                goto invalid_opc;
2398 a18ad893 Richard Henderson
            }
2399 f18cd223 aurel32
            if (likely(rc != 31)) {
2400 f18cd223 aurel32
                if (ra != 31) {
2401 a7812ae4 pbrook
                    TCGv_i32 tmp = tcg_temp_new_i32();
2402 f18cd223 aurel32
                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2403 a7812ae4 pbrook
                    gen_helper_memory_to_f(cpu_fir[rc], tmp);
2404 a7812ae4 pbrook
                    tcg_temp_free_i32(tmp);
2405 f18cd223 aurel32
                } else
2406 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
2407 f18cd223 aurel32
            }
2408 4c9649a9 j_mayer
            break;
2409 4c9649a9 j_mayer
        case 0x24:
2410 4c9649a9 j_mayer
            /* ITOFT */
2411 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2412 4c9649a9 j_mayer
                goto invalid_opc;
2413 a18ad893 Richard Henderson
            }
2414 f18cd223 aurel32
            if (likely(rc != 31)) {
2415 f18cd223 aurel32
                if (ra != 31)
2416 f18cd223 aurel32
                    tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
2417 f18cd223 aurel32
                else
2418 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
2419 f18cd223 aurel32
            }
2420 4c9649a9 j_mayer
            break;
2421 4c9649a9 j_mayer
        case 0x2A:
2422 4c9649a9 j_mayer
            /* SQRTG */
2423 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2424 a18ad893 Richard Henderson
                gen_fsqrtg(rb, rc);
2425 a18ad893 Richard Henderson
                break;
2426 a18ad893 Richard Henderson
            }
2427 a18ad893 Richard Henderson
            goto invalid_opc;
2428 4c9649a9 j_mayer
        case 0x02B:
2429 4c9649a9 j_mayer
            /* SQRTT */
2430 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2431 a18ad893 Richard Henderson
                gen_fsqrtt(ctx, rb, rc, fn11);
2432 a18ad893 Richard Henderson
                break;
2433 a18ad893 Richard Henderson
            }
2434 a18ad893 Richard Henderson
            goto invalid_opc;
2435 4c9649a9 j_mayer
        default:
2436 4c9649a9 j_mayer
            goto invalid_opc;
2437 4c9649a9 j_mayer
        }
2438 4c9649a9 j_mayer
        break;
2439 4c9649a9 j_mayer
    case 0x15:
2440 4c9649a9 j_mayer
        /* VAX floating point */
2441 4c9649a9 j_mayer
        /* XXX: rounding mode and trap are ignored (!) */
2442 f24518b5 Richard Henderson
        switch (fpfn) { /* fn11 & 0x3F */
2443 4c9649a9 j_mayer
        case 0x00:
2444 4c9649a9 j_mayer
            /* ADDF */
2445 a7812ae4 pbrook
            gen_faddf(ra, rb, rc);
2446 4c9649a9 j_mayer
            break;
2447 4c9649a9 j_mayer
        case 0x01:
2448 4c9649a9 j_mayer
            /* SUBF */
2449 a7812ae4 pbrook
            gen_fsubf(ra, rb, rc);
2450 4c9649a9 j_mayer
            break;
2451 4c9649a9 j_mayer
        case 0x02:
2452 4c9649a9 j_mayer
            /* MULF */
2453 a7812ae4 pbrook
            gen_fmulf(ra, rb, rc);
2454 4c9649a9 j_mayer
            break;
2455 4c9649a9 j_mayer
        case 0x03:
2456 4c9649a9 j_mayer
            /* DIVF */
2457 a7812ae4 pbrook
            gen_fdivf(ra, rb, rc);
2458 4c9649a9 j_mayer
            break;
2459 4c9649a9 j_mayer
        case 0x1E:
2460 4c9649a9 j_mayer
            /* CVTDG */
2461 4c9649a9 j_mayer
#if 0 // TODO
2462 a7812ae4 pbrook
            gen_fcvtdg(rb, rc);
2463 4c9649a9 j_mayer
#else
2464 4c9649a9 j_mayer
            goto invalid_opc;
2465 4c9649a9 j_mayer
#endif
2466 4c9649a9 j_mayer
            break;
2467 4c9649a9 j_mayer
        case 0x20:
2468 4c9649a9 j_mayer
            /* ADDG */
2469 a7812ae4 pbrook
            gen_faddg(ra, rb, rc);
2470 4c9649a9 j_mayer
            break;
2471 4c9649a9 j_mayer
        case 0x21:
2472 4c9649a9 j_mayer
            /* SUBG */
2473 a7812ae4 pbrook
            gen_fsubg(ra, rb, rc);
2474 4c9649a9 j_mayer
            break;
2475 4c9649a9 j_mayer
        case 0x22:
2476 4c9649a9 j_mayer
            /* MULG */
2477 a7812ae4 pbrook
            gen_fmulg(ra, rb, rc);
2478 4c9649a9 j_mayer
            break;
2479 4c9649a9 j_mayer
        case 0x23:
2480 4c9649a9 j_mayer
            /* DIVG */
2481 a7812ae4 pbrook
            gen_fdivg(ra, rb, rc);
2482 4c9649a9 j_mayer
            break;
2483 4c9649a9 j_mayer
        case 0x25:
2484 4c9649a9 j_mayer
            /* CMPGEQ */
2485 a7812ae4 pbrook
            gen_fcmpgeq(ra, rb, rc);
2486 4c9649a9 j_mayer
            break;
2487 4c9649a9 j_mayer
        case 0x26:
2488 4c9649a9 j_mayer
            /* CMPGLT */
2489 a7812ae4 pbrook
            gen_fcmpglt(ra, rb, rc);
2490 4c9649a9 j_mayer
            break;
2491 4c9649a9 j_mayer
        case 0x27:
2492 4c9649a9 j_mayer
            /* CMPGLE */
2493 a7812ae4 pbrook
            gen_fcmpgle(ra, rb, rc);
2494 4c9649a9 j_mayer
            break;
2495 4c9649a9 j_mayer
        case 0x2C:
2496 4c9649a9 j_mayer
            /* CVTGF */
2497 a7812ae4 pbrook
            gen_fcvtgf(rb, rc);
2498 4c9649a9 j_mayer
            break;
2499 4c9649a9 j_mayer
        case 0x2D:
2500 4c9649a9 j_mayer
            /* CVTGD */
2501 4c9649a9 j_mayer
#if 0 // TODO
2502 a7812ae4 pbrook
            gen_fcvtgd(rb, rc);
2503 4c9649a9 j_mayer
#else
2504 4c9649a9 j_mayer
            goto invalid_opc;
2505 4c9649a9 j_mayer
#endif
2506 4c9649a9 j_mayer
            break;
2507 4c9649a9 j_mayer
        case 0x2F:
2508 4c9649a9 j_mayer
            /* CVTGQ */
2509 a7812ae4 pbrook
            gen_fcvtgq(rb, rc);
2510 4c9649a9 j_mayer
            break;
2511 4c9649a9 j_mayer
        case 0x3C:
2512 4c9649a9 j_mayer
            /* CVTQF */
2513 a7812ae4 pbrook
            gen_fcvtqf(rb, rc);
2514 4c9649a9 j_mayer
            break;
2515 4c9649a9 j_mayer
        case 0x3E:
2516 4c9649a9 j_mayer
            /* CVTQG */
2517 a7812ae4 pbrook
            gen_fcvtqg(rb, rc);
2518 4c9649a9 j_mayer
            break;
2519 4c9649a9 j_mayer
        default:
2520 4c9649a9 j_mayer
            goto invalid_opc;
2521 4c9649a9 j_mayer
        }
2522 4c9649a9 j_mayer
        break;
2523 4c9649a9 j_mayer
    case 0x16:
2524 4c9649a9 j_mayer
        /* IEEE floating-point */
2525 f24518b5 Richard Henderson
        switch (fpfn) { /* fn11 & 0x3F */
2526 4c9649a9 j_mayer
        case 0x00:
2527 4c9649a9 j_mayer
            /* ADDS */
2528 f24518b5 Richard Henderson
            gen_fadds(ctx, ra, rb, rc, fn11);
2529 4c9649a9 j_mayer
            break;
2530 4c9649a9 j_mayer
        case 0x01:
2531 4c9649a9 j_mayer
            /* SUBS */
2532 f24518b5 Richard Henderson
            gen_fsubs(ctx, ra, rb, rc, fn11);
2533 4c9649a9 j_mayer
            break;
2534 4c9649a9 j_mayer
        case 0x02:
2535 4c9649a9 j_mayer
            /* MULS */
2536 f24518b5 Richard Henderson
            gen_fmuls(ctx, ra, rb, rc, fn11);
2537 4c9649a9 j_mayer
            break;
2538 4c9649a9 j_mayer
        case 0x03:
2539 4c9649a9 j_mayer
            /* DIVS */
2540 f24518b5 Richard Henderson
            gen_fdivs(ctx, ra, rb, rc, fn11);
2541 4c9649a9 j_mayer
            break;
2542 4c9649a9 j_mayer
        case 0x20:
2543 4c9649a9 j_mayer
            /* ADDT */
2544 f24518b5 Richard Henderson
            gen_faddt(ctx, ra, rb, rc, fn11);
2545 4c9649a9 j_mayer
            break;
2546 4c9649a9 j_mayer
        case 0x21:
2547 4c9649a9 j_mayer
            /* SUBT */
2548 f24518b5 Richard Henderson
            gen_fsubt(ctx, ra, rb, rc, fn11);
2549 4c9649a9 j_mayer
            break;
2550 4c9649a9 j_mayer
        case 0x22:
2551 4c9649a9 j_mayer
            /* MULT */
2552 f24518b5 Richard Henderson
            gen_fmult(ctx, ra, rb, rc, fn11);
2553 4c9649a9 j_mayer
            break;
2554 4c9649a9 j_mayer
        case 0x23:
2555 4c9649a9 j_mayer
            /* DIVT */
2556 f24518b5 Richard Henderson
            gen_fdivt(ctx, ra, rb, rc, fn11);
2557 4c9649a9 j_mayer
            break;
2558 4c9649a9 j_mayer
        case 0x24:
2559 4c9649a9 j_mayer
            /* CMPTUN */
2560 f24518b5 Richard Henderson
            gen_fcmptun(ctx, ra, rb, rc, fn11);
2561 4c9649a9 j_mayer
            break;
2562 4c9649a9 j_mayer
        case 0x25:
2563 4c9649a9 j_mayer
            /* CMPTEQ */
2564 f24518b5 Richard Henderson
            gen_fcmpteq(ctx, ra, rb, rc, fn11);
2565 4c9649a9 j_mayer
            break;
2566 4c9649a9 j_mayer
        case 0x26:
2567 4c9649a9 j_mayer
            /* CMPTLT */
2568 f24518b5 Richard Henderson
            gen_fcmptlt(ctx, ra, rb, rc, fn11);
2569 4c9649a9 j_mayer
            break;
2570 4c9649a9 j_mayer
        case 0x27:
2571 4c9649a9 j_mayer
            /* CMPTLE */
2572 f24518b5 Richard Henderson
            gen_fcmptle(ctx, ra, rb, rc, fn11);
2573 4c9649a9 j_mayer
            break;
2574 4c9649a9 j_mayer
        case 0x2C:
2575 a74b4d2c aurel32
            if (fn11 == 0x2AC || fn11 == 0x6AC) {
2576 4c9649a9 j_mayer
                /* CVTST */
2577 f24518b5 Richard Henderson
                gen_fcvtst(ctx, rb, rc, fn11);
2578 4c9649a9 j_mayer
            } else {
2579 4c9649a9 j_mayer
                /* CVTTS */
2580 f24518b5 Richard Henderson
                gen_fcvtts(ctx, rb, rc, fn11);
2581 4c9649a9 j_mayer
            }
2582 4c9649a9 j_mayer
            break;
2583 4c9649a9 j_mayer
        case 0x2F:
2584 4c9649a9 j_mayer
            /* CVTTQ */
2585 f24518b5 Richard Henderson
            gen_fcvttq(ctx, rb, rc, fn11);
2586 4c9649a9 j_mayer
            break;
2587 4c9649a9 j_mayer
        case 0x3C:
2588 4c9649a9 j_mayer
            /* CVTQS */
2589 f24518b5 Richard Henderson
            gen_fcvtqs(ctx, rb, rc, fn11);
2590 4c9649a9 j_mayer
            break;
2591 4c9649a9 j_mayer
        case 0x3E:
2592 4c9649a9 j_mayer
            /* CVTQT */
2593 f24518b5 Richard Henderson
            gen_fcvtqt(ctx, rb, rc, fn11);
2594 4c9649a9 j_mayer
            break;
2595 4c9649a9 j_mayer
        default:
2596 4c9649a9 j_mayer
            goto invalid_opc;
2597 4c9649a9 j_mayer
        }
2598 4c9649a9 j_mayer
        break;
2599 4c9649a9 j_mayer
    case 0x17:
2600 4c9649a9 j_mayer
        switch (fn11) {
2601 4c9649a9 j_mayer
        case 0x010:
2602 4c9649a9 j_mayer
            /* CVTLQ */
2603 a7812ae4 pbrook
            gen_fcvtlq(rb, rc);
2604 4c9649a9 j_mayer
            break;
2605 4c9649a9 j_mayer
        case 0x020:
2606 f18cd223 aurel32
            if (likely(rc != 31)) {
2607 a06d48d9 Richard Henderson
                if (ra == rb) {
2608 4c9649a9 j_mayer
                    /* FMOV */
2609 a06d48d9 Richard Henderson
                    if (ra == 31)
2610 a06d48d9 Richard Henderson
                        tcg_gen_movi_i64(cpu_fir[rc], 0);
2611 a06d48d9 Richard Henderson
                    else
2612 a06d48d9 Richard Henderson
                        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
2613 a06d48d9 Richard Henderson
                } else {
2614 f18cd223 aurel32
                    /* CPYS */
2615 a7812ae4 pbrook
                    gen_fcpys(ra, rb, rc);
2616 a06d48d9 Richard Henderson
                }
2617 4c9649a9 j_mayer
            }
2618 4c9649a9 j_mayer
            break;
2619 4c9649a9 j_mayer
        case 0x021:
2620 4c9649a9 j_mayer
            /* CPYSN */
2621 a7812ae4 pbrook
            gen_fcpysn(ra, rb, rc);
2622 4c9649a9 j_mayer
            break;
2623 4c9649a9 j_mayer
        case 0x022:
2624 4c9649a9 j_mayer
            /* CPYSE */
2625 a7812ae4 pbrook
            gen_fcpyse(ra, rb, rc);
2626 4c9649a9 j_mayer
            break;
2627 4c9649a9 j_mayer
        case 0x024:
2628 4c9649a9 j_mayer
            /* MT_FPCR */
2629 f18cd223 aurel32
            if (likely(ra != 31))
2630 a7812ae4 pbrook
                gen_helper_store_fpcr(cpu_fir[ra]);
2631 f18cd223 aurel32
            else {
2632 f18cd223 aurel32
                TCGv tmp = tcg_const_i64(0);
2633 a7812ae4 pbrook
                gen_helper_store_fpcr(tmp);
2634 f18cd223 aurel32
                tcg_temp_free(tmp);
2635 f18cd223 aurel32
            }
2636 4c9649a9 j_mayer
            break;
2637 4c9649a9 j_mayer
        case 0x025:
2638 4c9649a9 j_mayer
            /* MF_FPCR */
2639 f18cd223 aurel32
            if (likely(ra != 31))
2640 a7812ae4 pbrook
                gen_helper_load_fpcr(cpu_fir[ra]);
2641 4c9649a9 j_mayer
            break;
2642 4c9649a9 j_mayer
        case 0x02A:
2643 4c9649a9 j_mayer
            /* FCMOVEQ */
2644 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_EQ, ra, rb, rc);
2645 4c9649a9 j_mayer
            break;
2646 4c9649a9 j_mayer
        case 0x02B:
2647 4c9649a9 j_mayer
            /* FCMOVNE */
2648 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_NE, ra, rb, rc);
2649 4c9649a9 j_mayer
            break;
2650 4c9649a9 j_mayer
        case 0x02C:
2651 4c9649a9 j_mayer
            /* FCMOVLT */
2652 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_LT, ra, rb, rc);
2653 4c9649a9 j_mayer
            break;
2654 4c9649a9 j_mayer
        case 0x02D:
2655 4c9649a9 j_mayer
            /* FCMOVGE */
2656 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_GE, ra, rb, rc);
2657 4c9649a9 j_mayer
            break;
2658 4c9649a9 j_mayer
        case 0x02E:
2659 4c9649a9 j_mayer
            /* FCMOVLE */
2660 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_LE, ra, rb, rc);
2661 4c9649a9 j_mayer
            break;
2662 4c9649a9 j_mayer
        case 0x02F:
2663 4c9649a9 j_mayer
            /* FCMOVGT */
2664 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_GT, ra, rb, rc);
2665 4c9649a9 j_mayer
            break;
2666 4c9649a9 j_mayer
        case 0x030:
2667 4c9649a9 j_mayer
            /* CVTQL */
2668 a7812ae4 pbrook
            gen_fcvtql(rb, rc);
2669 4c9649a9 j_mayer
            break;
2670 4c9649a9 j_mayer
        case 0x130:
2671 4c9649a9 j_mayer
            /* CVTQL/V */
2672 4c9649a9 j_mayer
        case 0x530:
2673 4c9649a9 j_mayer
            /* CVTQL/SV */
2674 735cf45f Richard Henderson
            /* ??? I'm pretty sure there's nothing that /sv needs to do that
2675 735cf45f Richard Henderson
               /v doesn't do.  The only thing I can think is that /sv is a
2676 735cf45f Richard Henderson
               valid instruction merely for completeness in the ISA.  */
2677 735cf45f Richard Henderson
            gen_fcvtql_v(ctx, rb, rc);
2678 4c9649a9 j_mayer
            break;
2679 4c9649a9 j_mayer
        default:
2680 4c9649a9 j_mayer
            goto invalid_opc;
2681 4c9649a9 j_mayer
        }
2682 4c9649a9 j_mayer
        break;
2683 4c9649a9 j_mayer
    case 0x18:
2684 4c9649a9 j_mayer
        switch ((uint16_t)disp16) {
2685 4c9649a9 j_mayer
        case 0x0000:
2686 4c9649a9 j_mayer
            /* TRAPB */
2687 4af70374 Richard Henderson
            /* No-op.  */
2688 4c9649a9 j_mayer
            break;
2689 4c9649a9 j_mayer
        case 0x0400:
2690 4c9649a9 j_mayer
            /* EXCB */
2691 4af70374 Richard Henderson
            /* No-op.  */
2692 4c9649a9 j_mayer
            break;
2693 4c9649a9 j_mayer
        case 0x4000:
2694 4c9649a9 j_mayer
            /* MB */
2695 4c9649a9 j_mayer
            /* No-op */
2696 4c9649a9 j_mayer
            break;
2697 4c9649a9 j_mayer
        case 0x4400:
2698 4c9649a9 j_mayer
            /* WMB */
2699 4c9649a9 j_mayer
            /* No-op */
2700 4c9649a9 j_mayer
            break;
2701 4c9649a9 j_mayer
        case 0x8000:
2702 4c9649a9 j_mayer
            /* FETCH */
2703 4c9649a9 j_mayer
            /* No-op */
2704 4c9649a9 j_mayer
            break;
2705 4c9649a9 j_mayer
        case 0xA000:
2706 4c9649a9 j_mayer
            /* FETCH_M */
2707 4c9649a9 j_mayer
            /* No-op */
2708 4c9649a9 j_mayer
            break;
2709 4c9649a9 j_mayer
        case 0xC000:
2710 4c9649a9 j_mayer
            /* RPCC */
2711 3761035f aurel32
            if (ra != 31)
2712 a7812ae4 pbrook
                gen_helper_load_pcc(cpu_ir[ra]);
2713 4c9649a9 j_mayer
            break;
2714 4c9649a9 j_mayer
        case 0xE000:
2715 4c9649a9 j_mayer
            /* RC */
2716 ac316ca4 Richard Henderson
            gen_rx(ra, 0);
2717 4c9649a9 j_mayer
            break;
2718 4c9649a9 j_mayer
        case 0xE800:
2719 4c9649a9 j_mayer
            /* ECB */
2720 4c9649a9 j_mayer
            break;
2721 4c9649a9 j_mayer
        case 0xF000:
2722 4c9649a9 j_mayer
            /* RS */
2723 ac316ca4 Richard Henderson
            gen_rx(ra, 1);
2724 4c9649a9 j_mayer
            break;
2725 4c9649a9 j_mayer
        case 0xF800:
2726 4c9649a9 j_mayer
            /* WH64 */
2727 4c9649a9 j_mayer
            /* No-op */
2728 4c9649a9 j_mayer
            break;
2729 4c9649a9 j_mayer
        default:
2730 4c9649a9 j_mayer
            goto invalid_opc;
2731 4c9649a9 j_mayer
        }
2732 4c9649a9 j_mayer
        break;
2733 4c9649a9 j_mayer
    case 0x19:
2734 4c9649a9 j_mayer
        /* HW_MFPR (PALcode) */
2735 26b46094 Richard Henderson
#ifndef CONFIG_USER_ONLY
2736 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2737 26b46094 Richard Henderson
            gen_mfpr(ra, insn & 0xffff);
2738 26b46094 Richard Henderson
            break;
2739 26b46094 Richard Henderson
        }
2740 26b46094 Richard Henderson
#endif
2741 4c9649a9 j_mayer
        goto invalid_opc;
2742 4c9649a9 j_mayer
    case 0x1A:
2743 49563a72 Richard Henderson
        /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
2744 49563a72 Richard Henderson
           prediction stack action, which of course we don't implement.  */
2745 49563a72 Richard Henderson
        if (rb != 31) {
2746 3761035f aurel32
            tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
2747 49563a72 Richard Henderson
        } else {
2748 3761035f aurel32
            tcg_gen_movi_i64(cpu_pc, 0);
2749 49563a72 Richard Henderson
        }
2750 49563a72 Richard Henderson
        if (ra != 31) {
2751 1304ca87 aurel32
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2752 49563a72 Richard Henderson
        }
2753 4af70374 Richard Henderson
        ret = EXIT_PC_UPDATED;
2754 4c9649a9 j_mayer
        break;
2755 4c9649a9 j_mayer
    case 0x1B:
2756 4c9649a9 j_mayer
        /* HW_LD (PALcode) */
2757 a18ad893 Richard Henderson
#ifndef CONFIG_USER_ONLY
2758 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2759 a18ad893 Richard Henderson
            TCGv addr;
2760 a18ad893 Richard Henderson
2761 a18ad893 Richard Henderson
            if (ra == 31) {
2762 a18ad893 Richard Henderson
                break;
2763 a18ad893 Richard Henderson
            }
2764 a18ad893 Richard Henderson
2765 a18ad893 Richard Henderson
            addr = tcg_temp_new();
2766 8bb6e981 aurel32
            if (rb != 31)
2767 8bb6e981 aurel32
                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2768 8bb6e981 aurel32
            else
2769 8bb6e981 aurel32
                tcg_gen_movi_i64(addr, disp12);
2770 8bb6e981 aurel32
            switch ((insn >> 12) & 0xF) {
2771 8bb6e981 aurel32
            case 0x0:
2772 b5d51029 aurel32
                /* Longword physical access (hw_ldl/p) */
2773 2374e73e Richard Henderson
                gen_helper_ldl_phys(cpu_ir[ra], addr);
2774 8bb6e981 aurel32
                break;
2775 8bb6e981 aurel32
            case 0x1:
2776 b5d51029 aurel32
                /* Quadword physical access (hw_ldq/p) */
2777 2374e73e Richard Henderson
                gen_helper_ldq_phys(cpu_ir[ra], addr);
2778 8bb6e981 aurel32
                break;
2779 8bb6e981 aurel32
            case 0x2:
2780 b5d51029 aurel32
                /* Longword physical access with lock (hw_ldl_l/p) */
2781 2374e73e Richard Henderson
                gen_helper_ldl_l_phys(cpu_ir[ra], addr);
2782 8bb6e981 aurel32
                break;
2783 8bb6e981 aurel32
            case 0x3:
2784 b5d51029 aurel32
                /* Quadword physical access with lock (hw_ldq_l/p) */
2785 2374e73e Richard Henderson
                gen_helper_ldq_l_phys(cpu_ir[ra], addr);
2786 8bb6e981 aurel32
                break;
2787 8bb6e981 aurel32
            case 0x4:
2788 b5d51029 aurel32
                /* Longword virtual PTE fetch (hw_ldl/v) */
2789 2374e73e Richard Henderson
                goto invalid_opc;
2790 8bb6e981 aurel32
            case 0x5:
2791 b5d51029 aurel32
                /* Quadword virtual PTE fetch (hw_ldq/v) */
2792 2374e73e Richard Henderson
                goto invalid_opc;
2793 8bb6e981 aurel32
                break;
2794 8bb6e981 aurel32
            case 0x6:
2795 8bb6e981 aurel32
                /* Incpu_ir[ra]id */
2796 b5d51029 aurel32
                goto invalid_opc;
2797 8bb6e981 aurel32
            case 0x7:
2798 8bb6e981 aurel32
                /* Incpu_ir[ra]id */
2799 b5d51029 aurel32
                goto invalid_opc;
2800 8bb6e981 aurel32
            case 0x8:
2801 b5d51029 aurel32
                /* Longword virtual access (hw_ldl) */
2802 2374e73e Richard Henderson
                goto invalid_opc;
2803 8bb6e981 aurel32
            case 0x9:
2804 b5d51029 aurel32
                /* Quadword virtual access (hw_ldq) */
2805 2374e73e Richard Henderson
                goto invalid_opc;
2806 8bb6e981 aurel32
            case 0xA:
2807 b5d51029 aurel32
                /* Longword virtual access with protection check (hw_ldl/w) */
2808 8417845e Richard Henderson
                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_KERNEL_IDX);
2809 8bb6e981 aurel32
                break;
2810 8bb6e981 aurel32
            case 0xB:
2811 b5d51029 aurel32
                /* Quadword virtual access with protection check (hw_ldq/w) */
2812 8417845e Richard Henderson
                tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_KERNEL_IDX);
2813 8bb6e981 aurel32
                break;
2814 8bb6e981 aurel32
            case 0xC:
2815 b5d51029 aurel32
                /* Longword virtual access with alt access mode (hw_ldl/a)*/
2816 2374e73e Richard Henderson
                goto invalid_opc;
2817 8bb6e981 aurel32
            case 0xD:
2818 b5d51029 aurel32
                /* Quadword virtual access with alt access mode (hw_ldq/a) */
2819 2374e73e Richard Henderson
                goto invalid_opc;
2820 8bb6e981 aurel32
            case 0xE:
2821 8bb6e981 aurel32
                /* Longword virtual access with alternate access mode and
2822 2374e73e Richard Henderson
                   protection checks (hw_ldl/wa) */
2823 2374e73e Richard Henderson
                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_USER_IDX);
2824 8bb6e981 aurel32
                break;
2825 8bb6e981 aurel32
            case 0xF:
2826 8bb6e981 aurel32
                /* Quadword virtual access with alternate access mode and
2827 2374e73e Richard Henderson
                   protection checks (hw_ldq/wa) */
2828 2374e73e Richard Henderson
                tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_USER_IDX);
2829 8bb6e981 aurel32
                break;
2830 8bb6e981 aurel32
            }
2831 8bb6e981 aurel32
            tcg_temp_free(addr);
2832 a18ad893 Richard Henderson
            break;
2833 4c9649a9 j_mayer
        }
2834 4c9649a9 j_mayer
#endif
2835 a18ad893 Richard Henderson
        goto invalid_opc;
2836 4c9649a9 j_mayer
    case 0x1C:
2837 4c9649a9 j_mayer
        switch (fn7) {
2838 4c9649a9 j_mayer
        case 0x00:
2839 4c9649a9 j_mayer
            /* SEXTB */
2840 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) {
2841 4c9649a9 j_mayer
                goto invalid_opc;
2842 a18ad893 Richard Henderson
            }
2843 ae8ecd42 aurel32
            if (likely(rc != 31)) {
2844 ae8ecd42 aurel32
                if (islit)
2845 ae8ecd42 aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
2846 ae8ecd42 aurel32
                else
2847 dfaa8583 aurel32
                    tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
2848 ae8ecd42 aurel32
            }
2849 4c9649a9 j_mayer
            break;
2850 4c9649a9 j_mayer
        case 0x01:
2851 4c9649a9 j_mayer
            /* SEXTW */
2852 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
2853 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2854 a18ad893 Richard Henderson
                    if (islit) {
2855 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
2856 a18ad893 Richard Henderson
                    } else {
2857 a18ad893 Richard Henderson
                        tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
2858 a18ad893 Richard Henderson
                    }
2859 a18ad893 Richard Henderson
                }
2860 a18ad893 Richard Henderson
                break;
2861 ae8ecd42 aurel32
            }
2862 a18ad893 Richard Henderson
            goto invalid_opc;
2863 4c9649a9 j_mayer
        case 0x30:
2864 4c9649a9 j_mayer
            /* CTPOP */
2865 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2866 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2867 a18ad893 Richard Henderson
                    if (islit) {
2868 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
2869 a18ad893 Richard Henderson
                    } else {
2870 a18ad893 Richard Henderson
                        gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
2871 a18ad893 Richard Henderson
                    }
2872 a18ad893 Richard Henderson
                }
2873 a18ad893 Richard Henderson
                break;
2874 ae8ecd42 aurel32
            }
2875 a18ad893 Richard Henderson
            goto invalid_opc;
2876 4c9649a9 j_mayer
        case 0x31:
2877 4c9649a9 j_mayer
            /* PERR */
2878 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2879 a18ad893 Richard Henderson
                gen_perr(ra, rb, rc, islit, lit);
2880 a18ad893 Richard Henderson
                break;
2881 a18ad893 Richard Henderson
            }
2882 a18ad893 Richard Henderson
            goto invalid_opc;
2883 4c9649a9 j_mayer
        case 0x32:
2884 4c9649a9 j_mayer
            /* CTLZ */
2885 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2886 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2887 a18ad893 Richard Henderson
                    if (islit) {
2888 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
2889 a18ad893 Richard Henderson
                    } else {
2890 a18ad893 Richard Henderson
                        gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
2891 a18ad893 Richard Henderson
                    }
2892 a18ad893 Richard Henderson
                }
2893 a18ad893 Richard Henderson
                break;
2894 ae8ecd42 aurel32
            }
2895 a18ad893 Richard Henderson
            goto invalid_opc;
2896 4c9649a9 j_mayer
        case 0x33:
2897 4c9649a9 j_mayer
            /* CTTZ */
2898 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2899 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2900 a18ad893 Richard Henderson
                    if (islit) {
2901 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
2902 a18ad893 Richard Henderson
                    } else {
2903 a18ad893 Richard Henderson
                        gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
2904 a18ad893 Richard Henderson
                    }
2905 a18ad893 Richard Henderson
                }
2906 a18ad893 Richard Henderson
                break;
2907 ae8ecd42 aurel32
            }
2908 a18ad893 Richard Henderson
            goto invalid_opc;
2909 4c9649a9 j_mayer
        case 0x34:
2910 4c9649a9 j_mayer
            /* UNPKBW */
2911 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2912 a18ad893 Richard Henderson
                if (real_islit || ra != 31) {
2913 a18ad893 Richard Henderson
                    goto invalid_opc;
2914 a18ad893 Richard Henderson
                }
2915 a18ad893 Richard Henderson
                gen_unpkbw(rb, rc);
2916 a18ad893 Richard Henderson
                break;
2917 a18ad893 Richard Henderson
            }
2918 a18ad893 Richard Henderson
            goto invalid_opc;
2919 4c9649a9 j_mayer
        case 0x35:
2920 13e4df99 Richard Henderson
            /* UNPKBL */
2921 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2922 a18ad893 Richard Henderson
                if (real_islit || ra != 31) {
2923 a18ad893 Richard Henderson
                    goto invalid_opc;
2924 a18ad893 Richard Henderson
                }
2925 a18ad893 Richard Henderson
                gen_unpkbl(rb, rc);
2926 a18ad893 Richard Henderson
                break;
2927 a18ad893 Richard Henderson
            }
2928 a18ad893 Richard Henderson
            goto invalid_opc;
2929 4c9649a9 j_mayer
        case 0x36:
2930 4c9649a9 j_mayer
            /* PKWB */
2931 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2932 a18ad893 Richard Henderson
                if (real_islit || ra != 31) {
2933 a18ad893 Richard Henderson
                    goto invalid_opc;
2934 a18ad893 Richard Henderson
                }
2935 a18ad893 Richard Henderson
                gen_pkwb(rb, rc);
2936 a18ad893 Richard Henderson
                break;
2937 a18ad893 Richard Henderson
            }
2938 a18ad893 Richard Henderson
            goto invalid_opc;
2939 4c9649a9 j_mayer
        case 0x37:
2940 4c9649a9 j_mayer
            /* PKLB */
2941 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2942 a18ad893 Richard Henderson
                if (real_islit || ra != 31) {
2943 a18ad893 Richard Henderson
                    goto invalid_opc;
2944 a18ad893 Richard Henderson
                }
2945 a18ad893 Richard Henderson
                gen_pklb(rb, rc);
2946 a18ad893 Richard Henderson
                break;
2947 a18ad893 Richard Henderson
            }
2948 a18ad893 Richard Henderson
            goto invalid_opc;
2949 4c9649a9 j_mayer
        case 0x38:
2950 4c9649a9 j_mayer
            /* MINSB8 */
2951 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2952 a18ad893 Richard Henderson
                gen_minsb8(ra, rb, rc, islit, lit);
2953 a18ad893 Richard Henderson
                break;
2954 a18ad893 Richard Henderson
            }
2955 a18ad893 Richard Henderson
            goto invalid_opc;
2956 4c9649a9 j_mayer
        case 0x39:
2957 4c9649a9 j_mayer
            /* MINSW4 */
2958 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2959 a18ad893 Richard Henderson
                gen_minsw4(ra, rb, rc, islit, lit);
2960 a18ad893 Richard Henderson
                break;
2961 a18ad893 Richard Henderson
            }
2962 a18ad893 Richard Henderson
            goto invalid_opc;
2963 4c9649a9 j_mayer
        case 0x3A:
2964 4c9649a9 j_mayer
            /* MINUB8 */
2965 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2966 a18ad893 Richard Henderson
                gen_minub8(ra, rb, rc, islit, lit);
2967 a18ad893 Richard Henderson
                break;
2968 a18ad893 Richard Henderson
            }
2969 a18ad893 Richard Henderson
            goto invalid_opc;
2970 4c9649a9 j_mayer
        case 0x3B:
2971 4c9649a9 j_mayer
            /* MINUW4 */
2972 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2973 a18ad893 Richard Henderson
                gen_minuw4(ra, rb, rc, islit, lit);
2974 a18ad893 Richard Henderson
                break;
2975 a18ad893 Richard Henderson
            }
2976 a18ad893 Richard Henderson
            goto invalid_opc;
2977 4c9649a9 j_mayer
        case 0x3C:
2978 4c9649a9 j_mayer
            /* MAXUB8 */
2979 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2980 a18ad893 Richard Henderson
                gen_maxub8(ra, rb, rc, islit, lit);
2981 a18ad893 Richard Henderson
                break;
2982 a18ad893 Richard Henderson
            }
2983 a18ad893 Richard Henderson
            goto invalid_opc;
2984 4c9649a9 j_mayer
        case 0x3D:
2985 4c9649a9 j_mayer
            /* MAXUW4 */
2986 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2987 a18ad893 Richard Henderson
                gen_maxuw4(ra, rb, rc, islit, lit);
2988 a18ad893 Richard Henderson
                break;
2989 a18ad893 Richard Henderson
            }
2990 a18ad893 Richard Henderson
            goto invalid_opc;
2991 4c9649a9 j_mayer
        case 0x3E:
2992 4c9649a9 j_mayer
            /* MAXSB8 */
2993 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2994 a18ad893 Richard Henderson
                gen_maxsb8(ra, rb, rc, islit, lit);
2995 a18ad893 Richard Henderson
                break;
2996 a18ad893 Richard Henderson
            }
2997 a18ad893 Richard Henderson
            goto invalid_opc;
2998 4c9649a9 j_mayer
        case 0x3F:
2999 4c9649a9 j_mayer
            /* MAXSW4 */
3000 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3001 a18ad893 Richard Henderson
                gen_maxsw4(ra, rb, rc, islit, lit);
3002 a18ad893 Richard Henderson
                break;
3003 a18ad893 Richard Henderson
            }
3004 a18ad893 Richard Henderson
            goto invalid_opc;
3005 4c9649a9 j_mayer
        case 0x70:
3006 4c9649a9 j_mayer
            /* FTOIT */
3007 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3008 4c9649a9 j_mayer
                goto invalid_opc;
3009 a18ad893 Richard Henderson
            }
3010 f18cd223 aurel32
            if (likely(rc != 31)) {
3011 f18cd223 aurel32
                if (ra != 31)
3012 f18cd223 aurel32
                    tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
3013 f18cd223 aurel32
                else
3014 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
3015 f18cd223 aurel32
            }
3016 4c9649a9 j_mayer
            break;
3017 4c9649a9 j_mayer
        case 0x78:
3018 4c9649a9 j_mayer
            /* FTOIS */
3019 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3020 4c9649a9 j_mayer
                goto invalid_opc;
3021 a18ad893 Richard Henderson
            }
3022 f18cd223 aurel32
            if (rc != 31) {
3023 a7812ae4 pbrook
                TCGv_i32 tmp1 = tcg_temp_new_i32();
3024 f18cd223 aurel32
                if (ra != 31)
3025 a7812ae4 pbrook
                    gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
3026 f18cd223 aurel32
                else {
3027 f18cd223 aurel32
                    TCGv tmp2 = tcg_const_i64(0);
3028 a7812ae4 pbrook
                    gen_helper_s_to_memory(tmp1, tmp2);
3029 f18cd223 aurel32
                    tcg_temp_free(tmp2);
3030 f18cd223 aurel32
                }
3031 f18cd223 aurel32
                tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
3032 a7812ae4 pbrook
                tcg_temp_free_i32(tmp1);
3033 f18cd223 aurel32
            }
3034 4c9649a9 j_mayer
            break;
3035 4c9649a9 j_mayer
        default:
3036 4c9649a9 j_mayer
            goto invalid_opc;
3037 4c9649a9 j_mayer
        }
3038 4c9649a9 j_mayer
        break;
3039 4c9649a9 j_mayer
    case 0x1D:
3040 4c9649a9 j_mayer
        /* HW_MTPR (PALcode) */
3041 26b46094 Richard Henderson
#ifndef CONFIG_USER_ONLY
3042 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3043 a18ad893 Richard Henderson
            gen_mtpr(rb, insn & 0xffff);
3044 26b46094 Richard Henderson
            break;
3045 26b46094 Richard Henderson
        }
3046 26b46094 Richard Henderson
#endif
3047 4c9649a9 j_mayer
        goto invalid_opc;
3048 4c9649a9 j_mayer
    case 0x1E:
3049 508b43ea Richard Henderson
        /* HW_RET (PALcode) */
3050 a18ad893 Richard Henderson
#ifndef CONFIG_USER_ONLY
3051 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3052 a18ad893 Richard Henderson
            if (rb == 31) {
3053 a18ad893 Richard Henderson
                /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
3054 a18ad893 Richard Henderson
                   address from EXC_ADDR.  This turns out to be useful for our
3055 a18ad893 Richard Henderson
                   emulation PALcode, so continue to accept it.  */
3056 a18ad893 Richard Henderson
                TCGv tmp = tcg_temp_new();
3057 a18ad893 Richard Henderson
                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, exc_addr));
3058 a18ad893 Richard Henderson
                gen_helper_hw_ret(tmp);
3059 a18ad893 Richard Henderson
                tcg_temp_free(tmp);
3060 a18ad893 Richard Henderson
            } else {
3061 a18ad893 Richard Henderson
                gen_helper_hw_ret(cpu_ir[rb]);
3062 a18ad893 Richard Henderson
            }
3063 a18ad893 Richard Henderson
            ret = EXIT_PC_UPDATED;
3064 a18ad893 Richard Henderson
            break;
3065 4c9649a9 j_mayer
        }
3066 4c9649a9 j_mayer
#endif
3067 a18ad893 Richard Henderson
        goto invalid_opc;
3068 4c9649a9 j_mayer
    case 0x1F:
3069 4c9649a9 j_mayer
        /* HW_ST (PALcode) */
3070 a18ad893 Richard Henderson
#ifndef CONFIG_USER_ONLY
3071 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3072 8bb6e981 aurel32
            TCGv addr, val;
3073 a7812ae4 pbrook
            addr = tcg_temp_new();
3074 8bb6e981 aurel32
            if (rb != 31)
3075 8bb6e981 aurel32
                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
3076 8bb6e981 aurel32
            else
3077 8bb6e981 aurel32
                tcg_gen_movi_i64(addr, disp12);
3078 8bb6e981 aurel32
            if (ra != 31)
3079 8bb6e981 aurel32
                val = cpu_ir[ra];
3080 8bb6e981 aurel32
            else {
3081 a7812ae4 pbrook
                val = tcg_temp_new();
3082 8bb6e981 aurel32
                tcg_gen_movi_i64(val, 0);
3083 8bb6e981 aurel32
            }
3084 8bb6e981 aurel32
            switch ((insn >> 12) & 0xF) {
3085 8bb6e981 aurel32
            case 0x0:
3086 8bb6e981 aurel32
                /* Longword physical access */
3087 2374e73e Richard Henderson
                gen_helper_stl_phys(addr, val);
3088 8bb6e981 aurel32
                break;
3089 8bb6e981 aurel32
            case 0x1:
3090 8bb6e981 aurel32
                /* Quadword physical access */
3091 2374e73e Richard Henderson
                gen_helper_stq_phys(addr, val);
3092 8bb6e981 aurel32
                break;
3093 8bb6e981 aurel32
            case 0x2:
3094 8bb6e981 aurel32
                /* Longword physical access with lock */
3095 2374e73e Richard Henderson
                gen_helper_stl_c_phys(val, addr, val);
3096 8bb6e981 aurel32
                break;
3097 8bb6e981 aurel32
            case 0x3:
3098 8bb6e981 aurel32
                /* Quadword physical access with lock */
3099 2374e73e Richard Henderson
                gen_helper_stq_c_phys(val, addr, val);
3100 8bb6e981 aurel32
                break;
3101 8bb6e981 aurel32
            case 0x4:
3102 8bb6e981 aurel32
                /* Longword virtual access */
3103 2374e73e Richard Henderson
                goto invalid_opc;
3104 8bb6e981 aurel32
            case 0x5:
3105 8bb6e981 aurel32
                /* Quadword virtual access */
3106 2374e73e Richard Henderson
                goto invalid_opc;
3107 8bb6e981 aurel32
            case 0x6:
3108 8bb6e981 aurel32
                /* Invalid */
3109 8bb6e981 aurel32
                goto invalid_opc;
3110 8bb6e981 aurel32
            case 0x7:
3111 8bb6e981 aurel32
                /* Invalid */
3112 8bb6e981 aurel32
                goto invalid_opc;
3113 8bb6e981 aurel32
            case 0x8:
3114 8bb6e981 aurel32
                /* Invalid */
3115 8bb6e981 aurel32
                goto invalid_opc;
3116 8bb6e981 aurel32
            case 0x9:
3117 8bb6e981 aurel32
                /* Invalid */
3118 8bb6e981 aurel32
                goto invalid_opc;
3119 8bb6e981 aurel32
            case 0xA:
3120 8bb6e981 aurel32
                /* Invalid */
3121 8bb6e981 aurel32
                goto invalid_opc;
3122 8bb6e981 aurel32
            case 0xB:
3123 8bb6e981 aurel32
                /* Invalid */
3124 8bb6e981 aurel32
                goto invalid_opc;
3125 8bb6e981 aurel32
            case 0xC:
3126 8bb6e981 aurel32
                /* Longword virtual access with alternate access mode */
3127 2374e73e Richard Henderson
                goto invalid_opc;
3128 8bb6e981 aurel32
            case 0xD:
3129 8bb6e981 aurel32
                /* Quadword virtual access with alternate access mode */
3130 2374e73e Richard Henderson
                goto invalid_opc;
3131 8bb6e981 aurel32
            case 0xE:
3132 8bb6e981 aurel32
                /* Invalid */
3133 8bb6e981 aurel32
                goto invalid_opc;
3134 8bb6e981 aurel32
            case 0xF:
3135 8bb6e981 aurel32
                /* Invalid */
3136 8bb6e981 aurel32
                goto invalid_opc;
3137 8bb6e981 aurel32
            }
3138 45d46ce8 aurel32
            if (ra == 31)
3139 8bb6e981 aurel32
                tcg_temp_free(val);
3140 8bb6e981 aurel32
            tcg_temp_free(addr);
3141 a18ad893 Richard Henderson
            break;
3142 4c9649a9 j_mayer
        }
3143 4c9649a9 j_mayer
#endif
3144 a18ad893 Richard Henderson
        goto invalid_opc;
3145 4c9649a9 j_mayer
    case 0x20:
3146 4c9649a9 j_mayer
        /* LDF */
3147 f18cd223 aurel32
        gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
3148 4c9649a9 j_mayer
        break;
3149 4c9649a9 j_mayer
    case 0x21:
3150 4c9649a9 j_mayer
        /* LDG */
3151 f18cd223 aurel32
        gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
3152 4c9649a9 j_mayer
        break;
3153 4c9649a9 j_mayer
    case 0x22:
3154 4c9649a9 j_mayer
        /* LDS */
3155 f18cd223 aurel32
        gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
3156 4c9649a9 j_mayer
        break;
3157 4c9649a9 j_mayer
    case 0x23:
3158 4c9649a9 j_mayer
        /* LDT */
3159 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
3160 4c9649a9 j_mayer
        break;
3161 4c9649a9 j_mayer
    case 0x24:
3162 4c9649a9 j_mayer
        /* STF */
3163 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
3164 4c9649a9 j_mayer
        break;
3165 4c9649a9 j_mayer
    case 0x25:
3166 4c9649a9 j_mayer
        /* STG */
3167 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
3168 4c9649a9 j_mayer
        break;
3169 4c9649a9 j_mayer
    case 0x26:
3170 4c9649a9 j_mayer
        /* STS */
3171 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
3172 4c9649a9 j_mayer
        break;
3173 4c9649a9 j_mayer
    case 0x27:
3174 4c9649a9 j_mayer
        /* STT */
3175 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
3176 4c9649a9 j_mayer
        break;
3177 4c9649a9 j_mayer
    case 0x28:
3178 4c9649a9 j_mayer
        /* LDL */
3179 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
3180 4c9649a9 j_mayer
        break;
3181 4c9649a9 j_mayer
    case 0x29:
3182 4c9649a9 j_mayer
        /* LDQ */
3183 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
3184 4c9649a9 j_mayer
        break;
3185 4c9649a9 j_mayer
    case 0x2A:
3186 4c9649a9 j_mayer
        /* LDL_L */
3187 f4ed8679 aurel32
        gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
3188 4c9649a9 j_mayer
        break;
3189 4c9649a9 j_mayer
    case 0x2B:
3190 4c9649a9 j_mayer
        /* LDQ_L */
3191 f4ed8679 aurel32
        gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
3192 4c9649a9 j_mayer
        break;
3193 4c9649a9 j_mayer
    case 0x2C:
3194 4c9649a9 j_mayer
        /* STL */
3195 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
3196 4c9649a9 j_mayer
        break;
3197 4c9649a9 j_mayer
    case 0x2D:
3198 4c9649a9 j_mayer
        /* STQ */
3199 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
3200 4c9649a9 j_mayer
        break;
3201 4c9649a9 j_mayer
    case 0x2E:
3202 4c9649a9 j_mayer
        /* STL_C */
3203 6910b8f6 Richard Henderson
        ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
3204 4c9649a9 j_mayer
        break;
3205 4c9649a9 j_mayer
    case 0x2F:
3206 4c9649a9 j_mayer
        /* STQ_C */
3207 6910b8f6 Richard Henderson
        ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
3208 4c9649a9 j_mayer
        break;
3209 4c9649a9 j_mayer
    case 0x30:
3210 4c9649a9 j_mayer
        /* BR */
3211 4af70374 Richard Henderson
        ret = gen_bdirect(ctx, ra, disp21);
3212 4c9649a9 j_mayer
        break;
3213 a7812ae4 pbrook
    case 0x31: /* FBEQ */
3214 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
3215 dbb30fe6 Richard Henderson
        break;
3216 a7812ae4 pbrook
    case 0x32: /* FBLT */
3217 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
3218 dbb30fe6 Richard Henderson
        break;
3219 a7812ae4 pbrook
    case 0x33: /* FBLE */
3220 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
3221 4c9649a9 j_mayer
        break;
3222 4c9649a9 j_mayer
    case 0x34:
3223 4c9649a9 j_mayer
        /* BSR */
3224 4af70374 Richard Henderson
        ret = gen_bdirect(ctx, ra, disp21);
3225 4c9649a9 j_mayer
        break;
3226 a7812ae4 pbrook
    case 0x35: /* FBNE */
3227 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
3228 dbb30fe6 Richard Henderson
        break;
3229 a7812ae4 pbrook
    case 0x36: /* FBGE */
3230 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
3231 dbb30fe6 Richard Henderson
        break;
3232 a7812ae4 pbrook
    case 0x37: /* FBGT */
3233 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
3234 4c9649a9 j_mayer
        break;
3235 4c9649a9 j_mayer
    case 0x38:
3236 4c9649a9 j_mayer
        /* BLBC */
3237 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
3238 4c9649a9 j_mayer
        break;
3239 4c9649a9 j_mayer
    case 0x39:
3240 4c9649a9 j_mayer
        /* BEQ */
3241 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
3242 4c9649a9 j_mayer
        break;
3243 4c9649a9 j_mayer
    case 0x3A:
3244 4c9649a9 j_mayer
        /* BLT */
3245 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
3246 4c9649a9 j_mayer
        break;
3247 4c9649a9 j_mayer
    case 0x3B:
3248 4c9649a9 j_mayer
        /* BLE */
3249 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
3250 4c9649a9 j_mayer
        break;
3251 4c9649a9 j_mayer
    case 0x3C:
3252 4c9649a9 j_mayer
        /* BLBS */
3253 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
3254 4c9649a9 j_mayer
        break;
3255 4c9649a9 j_mayer
    case 0x3D:
3256 4c9649a9 j_mayer
        /* BNE */
3257 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
3258 4c9649a9 j_mayer
        break;
3259 4c9649a9 j_mayer
    case 0x3E:
3260 4c9649a9 j_mayer
        /* BGE */
3261 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
3262 4c9649a9 j_mayer
        break;
3263 4c9649a9 j_mayer
    case 0x3F:
3264 4c9649a9 j_mayer
        /* BGT */
3265 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
3266 4c9649a9 j_mayer
        break;
3267 4c9649a9 j_mayer
    invalid_opc:
3268 8aa3fa20 Richard Henderson
        ret = gen_invalid(ctx);
3269 4c9649a9 j_mayer
        break;
3270 4c9649a9 j_mayer
    }
3271 4c9649a9 j_mayer
3272 4c9649a9 j_mayer
    return ret;
3273 4c9649a9 j_mayer
}
3274 4c9649a9 j_mayer
3275 636aa200 Blue Swirl
static inline void gen_intermediate_code_internal(CPUState *env,
3276 636aa200 Blue Swirl
                                                  TranslationBlock *tb,
3277 636aa200 Blue Swirl
                                                  int search_pc)
3278 4c9649a9 j_mayer
{
3279 4c9649a9 j_mayer
    DisasContext ctx, *ctxp = &ctx;
3280 4c9649a9 j_mayer
    target_ulong pc_start;
3281 4c9649a9 j_mayer
    uint32_t insn;
3282 4c9649a9 j_mayer
    uint16_t *gen_opc_end;
3283 a1d1bb31 aliguori
    CPUBreakpoint *bp;
3284 4c9649a9 j_mayer
    int j, lj = -1;
3285 4af70374 Richard Henderson
    ExitStatus ret;
3286 2e70f6ef pbrook
    int num_insns;
3287 2e70f6ef pbrook
    int max_insns;
3288 4c9649a9 j_mayer
3289 4c9649a9 j_mayer
    pc_start = tb->pc;
3290 4c9649a9 j_mayer
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3291 4af70374 Richard Henderson
3292 4af70374 Richard Henderson
    ctx.tb = tb;
3293 4af70374 Richard Henderson
    ctx.env = env;
3294 4c9649a9 j_mayer
    ctx.pc = pc_start;
3295 bba9bdce Richard Henderson
    ctx.mem_idx = cpu_mmu_index(env);
3296 f24518b5 Richard Henderson
3297 f24518b5 Richard Henderson
    /* ??? Every TB begins with unset rounding mode, to be initialized on
3298 f24518b5 Richard Henderson
       the first fp insn of the TB.  Alternately we could define a proper
3299 f24518b5 Richard Henderson
       default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
3300 f24518b5 Richard Henderson
       to reset the FP_STATUS to that default at the end of any TB that
3301 f24518b5 Richard Henderson
       changes the default.  We could even (gasp) dynamiclly figure out
3302 f24518b5 Richard Henderson
       what default would be most efficient given the running program.  */
3303 f24518b5 Richard Henderson
    ctx.tb_rm = -1;
3304 f24518b5 Richard Henderson
    /* Similarly for flush-to-zero.  */
3305 f24518b5 Richard Henderson
    ctx.tb_ftz = -1;
3306 f24518b5 Richard Henderson
3307 2e70f6ef pbrook
    num_insns = 0;
3308 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
3309 2e70f6ef pbrook
    if (max_insns == 0)
3310 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
3311 2e70f6ef pbrook
3312 2e70f6ef pbrook
    gen_icount_start();
3313 4af70374 Richard Henderson
    do {
3314 72cf2d4f Blue Swirl
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3315 72cf2d4f Blue Swirl
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3316 a1d1bb31 aliguori
                if (bp->pc == ctx.pc) {
3317 4c9649a9 j_mayer
                    gen_excp(&ctx, EXCP_DEBUG, 0);
3318 4c9649a9 j_mayer
                    break;
3319 4c9649a9 j_mayer
                }
3320 4c9649a9 j_mayer
            }
3321 4c9649a9 j_mayer
        }
3322 4c9649a9 j_mayer
        if (search_pc) {
3323 4c9649a9 j_mayer
            j = gen_opc_ptr - gen_opc_buf;
3324 4c9649a9 j_mayer
            if (lj < j) {
3325 4c9649a9 j_mayer
                lj++;
3326 4c9649a9 j_mayer
                while (lj < j)
3327 4c9649a9 j_mayer
                    gen_opc_instr_start[lj++] = 0;
3328 4c9649a9 j_mayer
            }
3329 ed1dda53 aurel32
            gen_opc_pc[lj] = ctx.pc;
3330 ed1dda53 aurel32
            gen_opc_instr_start[lj] = 1;
3331 ed1dda53 aurel32
            gen_opc_icount[lj] = num_insns;
3332 4c9649a9 j_mayer
        }
3333 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3334 2e70f6ef pbrook
            gen_io_start();
3335 4c9649a9 j_mayer
        insn = ldl_code(ctx.pc);
3336 2e70f6ef pbrook
        num_insns++;
3337 c4b3be39 Richard Henderson
3338 c4b3be39 Richard Henderson
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
3339 c4b3be39 Richard Henderson
            tcg_gen_debug_insn_start(ctx.pc);
3340 c4b3be39 Richard Henderson
        }
3341 c4b3be39 Richard Henderson
3342 4c9649a9 j_mayer
        ctx.pc += 4;
3343 4c9649a9 j_mayer
        ret = translate_one(ctxp, insn);
3344 19bf517b aurel32
3345 bf1b03fe Richard Henderson
        /* If we reach a page boundary, are single stepping,
3346 bf1b03fe Richard Henderson
           or exhaust instruction count, stop generation.  */
3347 bf1b03fe Richard Henderson
        if (ret == NO_EXIT
3348 bf1b03fe Richard Henderson
            && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
3349 bf1b03fe Richard Henderson
                || gen_opc_ptr >= gen_opc_end
3350 bf1b03fe Richard Henderson
                || num_insns >= max_insns
3351 bf1b03fe Richard Henderson
                || singlestep
3352 bf1b03fe Richard Henderson
                || env->singlestep_enabled)) {
3353 bf1b03fe Richard Henderson
            ret = EXIT_PC_STALE;
3354 1b530a6d aurel32
        }
3355 4af70374 Richard Henderson
    } while (ret == NO_EXIT);
3356 4af70374 Richard Henderson
3357 4af70374 Richard Henderson
    if (tb->cflags & CF_LAST_IO) {
3358 4af70374 Richard Henderson
        gen_io_end();
3359 4c9649a9 j_mayer
    }
3360 4af70374 Richard Henderson
3361 4af70374 Richard Henderson
    switch (ret) {
3362 4af70374 Richard Henderson
    case EXIT_GOTO_TB:
3363 8aa3fa20 Richard Henderson
    case EXIT_NORETURN:
3364 4af70374 Richard Henderson
        break;
3365 4af70374 Richard Henderson
    case EXIT_PC_STALE:
3366 496cb5b9 aurel32
        tcg_gen_movi_i64(cpu_pc, ctx.pc);
3367 4af70374 Richard Henderson
        /* FALLTHRU */
3368 4af70374 Richard Henderson
    case EXIT_PC_UPDATED:
3369 bf1b03fe Richard Henderson
        if (env->singlestep_enabled) {
3370 bf1b03fe Richard Henderson
            gen_excp_1(EXCP_DEBUG, 0);
3371 bf1b03fe Richard Henderson
        } else {
3372 bf1b03fe Richard Henderson
            tcg_gen_exit_tb(0);
3373 bf1b03fe Richard Henderson
        }
3374 4af70374 Richard Henderson
        break;
3375 4af70374 Richard Henderson
    default:
3376 4af70374 Richard Henderson
        abort();
3377 4c9649a9 j_mayer
    }
3378 4af70374 Richard Henderson
3379 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
3380 4c9649a9 j_mayer
    *gen_opc_ptr = INDEX_op_end;
3381 4c9649a9 j_mayer
    if (search_pc) {
3382 4c9649a9 j_mayer
        j = gen_opc_ptr - gen_opc_buf;
3383 4c9649a9 j_mayer
        lj++;
3384 4c9649a9 j_mayer
        while (lj <= j)
3385 4c9649a9 j_mayer
            gen_opc_instr_start[lj++] = 0;
3386 4c9649a9 j_mayer
    } else {
3387 4c9649a9 j_mayer
        tb->size = ctx.pc - pc_start;
3388 2e70f6ef pbrook
        tb->icount = num_insns;
3389 4c9649a9 j_mayer
    }
3390 4af70374 Richard Henderson
3391 806991da Richard Henderson
#ifdef DEBUG_DISAS
3392 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3393 93fcfe39 aliguori
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
3394 93fcfe39 aliguori
        log_target_disas(pc_start, ctx.pc - pc_start, 1);
3395 93fcfe39 aliguori
        qemu_log("\n");
3396 4c9649a9 j_mayer
    }
3397 4c9649a9 j_mayer
#endif
3398 4c9649a9 j_mayer
}
3399 4c9649a9 j_mayer
3400 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3401 4c9649a9 j_mayer
{
3402 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
3403 4c9649a9 j_mayer
}
3404 4c9649a9 j_mayer
3405 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3406 4c9649a9 j_mayer
{
3407 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
3408 4c9649a9 j_mayer
}
3409 4c9649a9 j_mayer
3410 a964acc6 Richard Henderson
struct cpu_def_t {
3411 a964acc6 Richard Henderson
    const char *name;
3412 a964acc6 Richard Henderson
    int implver, amask;
3413 a964acc6 Richard Henderson
};
3414 a964acc6 Richard Henderson
3415 a964acc6 Richard Henderson
static const struct cpu_def_t cpu_defs[] = {
3416 a964acc6 Richard Henderson
    { "ev4",   IMPLVER_2106x, 0 },
3417 a964acc6 Richard Henderson
    { "ev5",   IMPLVER_21164, 0 },
3418 a964acc6 Richard Henderson
    { "ev56",  IMPLVER_21164, AMASK_BWX },
3419 a964acc6 Richard Henderson
    { "pca56", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
3420 a964acc6 Richard Henderson
    { "ev6",   IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
3421 a964acc6 Richard Henderson
    { "ev67",  IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
3422 a964acc6 Richard Henderson
                               | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
3423 a964acc6 Richard Henderson
    { "ev68",  IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
3424 a964acc6 Richard Henderson
                               | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
3425 a964acc6 Richard Henderson
    { "21064", IMPLVER_2106x, 0 },
3426 a964acc6 Richard Henderson
    { "21164", IMPLVER_21164, 0 },
3427 a964acc6 Richard Henderson
    { "21164a", IMPLVER_21164, AMASK_BWX },
3428 a964acc6 Richard Henderson
    { "21164pc", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
3429 a964acc6 Richard Henderson
    { "21264", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
3430 a964acc6 Richard Henderson
    { "21264a", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
3431 a964acc6 Richard Henderson
                                | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), }
3432 a964acc6 Richard Henderson
};
3433 a964acc6 Richard Henderson
3434 aaed909a bellard
CPUAlphaState * cpu_alpha_init (const char *cpu_model)
3435 4c9649a9 j_mayer
{
3436 4c9649a9 j_mayer
    CPUAlphaState *env;
3437 a964acc6 Richard Henderson
    int implver, amask, i, max;
3438 4c9649a9 j_mayer
3439 4c9649a9 j_mayer
    env = qemu_mallocz(sizeof(CPUAlphaState));
3440 4c9649a9 j_mayer
    cpu_exec_init(env);
3441 2e70f6ef pbrook
    alpha_translate_init();
3442 4c9649a9 j_mayer
    tlb_flush(env, 1);
3443 a964acc6 Richard Henderson
3444 a964acc6 Richard Henderson
    /* Default to ev67; no reason not to emulate insns by default.  */
3445 a964acc6 Richard Henderson
    implver = IMPLVER_21264;
3446 a964acc6 Richard Henderson
    amask = (AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_MVI
3447 a964acc6 Richard Henderson
             | AMASK_TRAP | AMASK_PREFETCH);
3448 a964acc6 Richard Henderson
3449 a964acc6 Richard Henderson
    max = ARRAY_SIZE(cpu_defs);
3450 a964acc6 Richard Henderson
    for (i = 0; i < max; i++) {
3451 a964acc6 Richard Henderson
        if (strcmp (cpu_model, cpu_defs[i].name) == 0) {
3452 a964acc6 Richard Henderson
            implver = cpu_defs[i].implver;
3453 a964acc6 Richard Henderson
            amask = cpu_defs[i].amask;
3454 a964acc6 Richard Henderson
            break;
3455 a964acc6 Richard Henderson
        }
3456 a964acc6 Richard Henderson
    }
3457 a964acc6 Richard Henderson
    env->implver = implver;
3458 a964acc6 Richard Henderson
    env->amask = amask;
3459 a964acc6 Richard Henderson
3460 4c9649a9 j_mayer
#if defined (CONFIG_USER_ONLY)
3461 ea879fc7 Richard Henderson
    env->ps = PS_USER_MODE;
3462 2edd07ef Richard Henderson
    cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
3463 2edd07ef Richard Henderson
                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
3464 6049f4f8 Richard Henderson
#endif
3465 6910b8f6 Richard Henderson
    env->lock_addr = -1;
3466 26b46094 Richard Henderson
    env->fen = 1;
3467 dad081ee Richard Henderson
3468 0bf46a40 aliguori
    qemu_init_vcpu(env);
3469 4c9649a9 j_mayer
    return env;
3470 4c9649a9 j_mayer
}
3471 aaed909a bellard
3472 e87b7cb0 Stefan Weil
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
3473 d2856f1a aurel32
{
3474 d2856f1a aurel32
    env->pc = gen_opc_pc[pc_pos];
3475 d2856f1a aurel32
}