Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 3b4fefd6

History | View | Annotate | Download (103 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
1625 26b46094 Richard Henderson
    if (rb == 31) {
1626 26b46094 Richard Henderson
        tmp = tcg_const_i64(0);
1627 26b46094 Richard Henderson
    } else {
1628 26b46094 Richard Henderson
        tmp = cpu_ir[rb];
1629 26b46094 Richard Henderson
    }
1630 26b46094 Richard Henderson
1631 3b4fefd6 Richard Henderson
    /* These two register numbers perform a TLB cache flush.  Thankfully we
1632 3b4fefd6 Richard Henderson
       can only do this inside PALmode, which means that the current basic
1633 3b4fefd6 Richard Henderson
       block cannot be affected by the change in mappings.  */
1634 3b4fefd6 Richard Henderson
    if (regno == 255) {
1635 3b4fefd6 Richard Henderson
        /* TBIA */
1636 3b4fefd6 Richard Henderson
        gen_helper_tbia();
1637 3b4fefd6 Richard Henderson
    } else if (regno == 254) {
1638 3b4fefd6 Richard Henderson
        /* TBIS */
1639 3b4fefd6 Richard Henderson
        gen_helper_tbis(tmp);
1640 3b4fefd6 Richard Henderson
    } else {
1641 3b4fefd6 Richard Henderson
        /* The basic registers are data only, and unknown registers
1642 3b4fefd6 Richard Henderson
           are read-zero, write-ignore.  */
1643 3b4fefd6 Richard Henderson
        int data = cpu_pr_data(regno);
1644 3b4fefd6 Richard Henderson
        if (data != 0) {
1645 3b4fefd6 Richard Henderson
            if (data & PR_BYTE) {
1646 3b4fefd6 Richard Henderson
                tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
1647 3b4fefd6 Richard Henderson
            } else if (data & PR_LONG) {
1648 3b4fefd6 Richard Henderson
                tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
1649 3b4fefd6 Richard Henderson
            } else {
1650 3b4fefd6 Richard Henderson
                tcg_gen_st_i64(tmp, cpu_env, data);
1651 3b4fefd6 Richard Henderson
            }
1652 26b46094 Richard Henderson
        }
1653 26b46094 Richard Henderson
    }
1654 26b46094 Richard Henderson
1655 26b46094 Richard Henderson
    if (rb == 31) {
1656 26b46094 Richard Henderson
        tcg_temp_free(tmp);
1657 26b46094 Richard Henderson
    }
1658 26b46094 Richard Henderson
}
1659 26b46094 Richard Henderson
#endif /* !USER_ONLY*/
1660 26b46094 Richard Henderson
1661 4af70374 Richard Henderson
static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
1662 4c9649a9 j_mayer
{
1663 4c9649a9 j_mayer
    uint32_t palcode;
1664 4c9649a9 j_mayer
    int32_t disp21, disp16, disp12;
1665 f88fe4e3 Blue Swirl
    uint16_t fn11;
1666 f88fe4e3 Blue Swirl
    uint8_t opc, ra, rb, rc, fpfn, fn7, fn2, islit, real_islit;
1667 adf3c8b6 aurel32
    uint8_t lit;
1668 4af70374 Richard Henderson
    ExitStatus ret;
1669 4c9649a9 j_mayer
1670 4c9649a9 j_mayer
    /* Decode all instruction fields */
1671 4c9649a9 j_mayer
    opc = insn >> 26;
1672 4c9649a9 j_mayer
    ra = (insn >> 21) & 0x1F;
1673 4c9649a9 j_mayer
    rb = (insn >> 16) & 0x1F;
1674 4c9649a9 j_mayer
    rc = insn & 0x1F;
1675 13e4df99 Richard Henderson
    real_islit = islit = (insn >> 12) & 1;
1676 dfaa8583 aurel32
    if (rb == 31 && !islit) {
1677 dfaa8583 aurel32
        islit = 1;
1678 dfaa8583 aurel32
        lit = 0;
1679 dfaa8583 aurel32
    } else
1680 dfaa8583 aurel32
        lit = (insn >> 13) & 0xFF;
1681 4c9649a9 j_mayer
    palcode = insn & 0x03FFFFFF;
1682 4c9649a9 j_mayer
    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
1683 4c9649a9 j_mayer
    disp16 = (int16_t)(insn & 0x0000FFFF);
1684 4c9649a9 j_mayer
    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
1685 4c9649a9 j_mayer
    fn11 = (insn >> 5) & 0x000007FF;
1686 4c9649a9 j_mayer
    fpfn = fn11 & 0x3F;
1687 4c9649a9 j_mayer
    fn7 = (insn >> 5) & 0x0000007F;
1688 4c9649a9 j_mayer
    fn2 = (insn >> 5) & 0x00000003;
1689 806991da Richard Henderson
    LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
1690 d12d51d5 aliguori
              opc, ra, rb, rc, disp16);
1691 806991da Richard Henderson
1692 4af70374 Richard Henderson
    ret = NO_EXIT;
1693 4c9649a9 j_mayer
    switch (opc) {
1694 4c9649a9 j_mayer
    case 0x00:
1695 4c9649a9 j_mayer
        /* CALL_PAL */
1696 2ace7e55 Richard Henderson
        ret = gen_call_pal(ctx, palcode);
1697 2ace7e55 Richard Henderson
        break;
1698 4c9649a9 j_mayer
    case 0x01:
1699 4c9649a9 j_mayer
        /* OPC01 */
1700 4c9649a9 j_mayer
        goto invalid_opc;
1701 4c9649a9 j_mayer
    case 0x02:
1702 4c9649a9 j_mayer
        /* OPC02 */
1703 4c9649a9 j_mayer
        goto invalid_opc;
1704 4c9649a9 j_mayer
    case 0x03:
1705 4c9649a9 j_mayer
        /* OPC03 */
1706 4c9649a9 j_mayer
        goto invalid_opc;
1707 4c9649a9 j_mayer
    case 0x04:
1708 4c9649a9 j_mayer
        /* OPC04 */
1709 4c9649a9 j_mayer
        goto invalid_opc;
1710 4c9649a9 j_mayer
    case 0x05:
1711 4c9649a9 j_mayer
        /* OPC05 */
1712 4c9649a9 j_mayer
        goto invalid_opc;
1713 4c9649a9 j_mayer
    case 0x06:
1714 4c9649a9 j_mayer
        /* OPC06 */
1715 4c9649a9 j_mayer
        goto invalid_opc;
1716 4c9649a9 j_mayer
    case 0x07:
1717 4c9649a9 j_mayer
        /* OPC07 */
1718 4c9649a9 j_mayer
        goto invalid_opc;
1719 4c9649a9 j_mayer
    case 0x08:
1720 4c9649a9 j_mayer
        /* LDA */
1721 1ef4ef4e aurel32
        if (likely(ra != 31)) {
1722 496cb5b9 aurel32
            if (rb != 31)
1723 3761035f aurel32
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
1724 3761035f aurel32
            else
1725 3761035f aurel32
                tcg_gen_movi_i64(cpu_ir[ra], disp16);
1726 496cb5b9 aurel32
        }
1727 4c9649a9 j_mayer
        break;
1728 4c9649a9 j_mayer
    case 0x09:
1729 4c9649a9 j_mayer
        /* LDAH */
1730 1ef4ef4e aurel32
        if (likely(ra != 31)) {
1731 496cb5b9 aurel32
            if (rb != 31)
1732 3761035f aurel32
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
1733 3761035f aurel32
            else
1734 3761035f aurel32
                tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
1735 496cb5b9 aurel32
        }
1736 4c9649a9 j_mayer
        break;
1737 4c9649a9 j_mayer
    case 0x0A:
1738 4c9649a9 j_mayer
        /* LDBU */
1739 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1740 a18ad893 Richard Henderson
            gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1741 a18ad893 Richard Henderson
            break;
1742 a18ad893 Richard Henderson
        }
1743 a18ad893 Richard Henderson
        goto invalid_opc;
1744 4c9649a9 j_mayer
    case 0x0B:
1745 4c9649a9 j_mayer
        /* LDQ_U */
1746 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1747 4c9649a9 j_mayer
        break;
1748 4c9649a9 j_mayer
    case 0x0C:
1749 4c9649a9 j_mayer
        /* LDWU */
1750 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1751 a18ad893 Richard Henderson
            gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1752 a18ad893 Richard Henderson
            break;
1753 a18ad893 Richard Henderson
        }
1754 a18ad893 Richard Henderson
        goto invalid_opc;
1755 4c9649a9 j_mayer
    case 0x0D:
1756 4c9649a9 j_mayer
        /* STW */
1757 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1758 4c9649a9 j_mayer
        break;
1759 4c9649a9 j_mayer
    case 0x0E:
1760 4c9649a9 j_mayer
        /* STB */
1761 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1762 4c9649a9 j_mayer
        break;
1763 4c9649a9 j_mayer
    case 0x0F:
1764 4c9649a9 j_mayer
        /* STQ_U */
1765 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1766 4c9649a9 j_mayer
        break;
1767 4c9649a9 j_mayer
    case 0x10:
1768 4c9649a9 j_mayer
        switch (fn7) {
1769 4c9649a9 j_mayer
        case 0x00:
1770 4c9649a9 j_mayer
            /* ADDL */
1771 30c7183b aurel32
            if (likely(rc != 31)) {
1772 30c7183b aurel32
                if (ra != 31) {
1773 30c7183b aurel32
                    if (islit) {
1774 30c7183b aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1775 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1776 dfaa8583 aurel32
                    } else {
1777 30c7183b aurel32
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1778 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1779 dfaa8583 aurel32
                    }
1780 30c7183b aurel32
                } else {
1781 30c7183b aurel32
                    if (islit)
1782 dfaa8583 aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1783 30c7183b aurel32
                    else
1784 dfaa8583 aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1785 30c7183b aurel32
                }
1786 30c7183b aurel32
            }
1787 4c9649a9 j_mayer
            break;
1788 4c9649a9 j_mayer
        case 0x02:
1789 4c9649a9 j_mayer
            /* S4ADDL */
1790 30c7183b aurel32
            if (likely(rc != 31)) {
1791 30c7183b aurel32
                if (ra != 31) {
1792 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1793 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1794 dfaa8583 aurel32
                    if (islit)
1795 dfaa8583 aurel32
                        tcg_gen_addi_i64(tmp, tmp, lit);
1796 dfaa8583 aurel32
                    else
1797 dfaa8583 aurel32
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1798 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1799 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1800 30c7183b aurel32
                } else {
1801 30c7183b aurel32
                    if (islit)
1802 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1803 30c7183b aurel32
                    else
1804 dfaa8583 aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1805 30c7183b aurel32
                }
1806 30c7183b aurel32
            }
1807 4c9649a9 j_mayer
            break;
1808 4c9649a9 j_mayer
        case 0x09:
1809 4c9649a9 j_mayer
            /* SUBL */
1810 30c7183b aurel32
            if (likely(rc != 31)) {
1811 30c7183b aurel32
                if (ra != 31) {
1812 dfaa8583 aurel32
                    if (islit)
1813 30c7183b aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1814 dfaa8583 aurel32
                    else
1815 30c7183b aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1816 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1817 30c7183b aurel32
                } else {
1818 30c7183b aurel32
                    if (islit)
1819 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1820 dfaa8583 aurel32
                    else {
1821 30c7183b aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1822 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1823 30c7183b aurel32
                }
1824 30c7183b aurel32
            }
1825 4c9649a9 j_mayer
            break;
1826 4c9649a9 j_mayer
        case 0x0B:
1827 4c9649a9 j_mayer
            /* S4SUBL */
1828 30c7183b aurel32
            if (likely(rc != 31)) {
1829 30c7183b aurel32
                if (ra != 31) {
1830 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1831 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1832 dfaa8583 aurel32
                    if (islit)
1833 dfaa8583 aurel32
                        tcg_gen_subi_i64(tmp, tmp, lit);
1834 dfaa8583 aurel32
                    else
1835 dfaa8583 aurel32
                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1836 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1837 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1838 30c7183b aurel32
                } else {
1839 30c7183b aurel32
                    if (islit)
1840 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1841 dfaa8583 aurel32
                    else {
1842 30c7183b aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1843 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1844 dfaa8583 aurel32
                    }
1845 30c7183b aurel32
                }
1846 30c7183b aurel32
            }
1847 4c9649a9 j_mayer
            break;
1848 4c9649a9 j_mayer
        case 0x0F:
1849 4c9649a9 j_mayer
            /* CMPBGE */
1850 a7812ae4 pbrook
            gen_cmpbge(ra, rb, rc, islit, lit);
1851 4c9649a9 j_mayer
            break;
1852 4c9649a9 j_mayer
        case 0x12:
1853 4c9649a9 j_mayer
            /* S8ADDL */
1854 30c7183b aurel32
            if (likely(rc != 31)) {
1855 30c7183b aurel32
                if (ra != 31) {
1856 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1857 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1858 dfaa8583 aurel32
                    if (islit)
1859 dfaa8583 aurel32
                        tcg_gen_addi_i64(tmp, tmp, lit);
1860 dfaa8583 aurel32
                    else
1861 dfaa8583 aurel32
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1862 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1863 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1864 30c7183b aurel32
                } else {
1865 30c7183b aurel32
                    if (islit)
1866 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1867 30c7183b aurel32
                    else
1868 dfaa8583 aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1869 30c7183b aurel32
                }
1870 30c7183b aurel32
            }
1871 4c9649a9 j_mayer
            break;
1872 4c9649a9 j_mayer
        case 0x1B:
1873 4c9649a9 j_mayer
            /* S8SUBL */
1874 30c7183b aurel32
            if (likely(rc != 31)) {
1875 30c7183b aurel32
                if (ra != 31) {
1876 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1877 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1878 dfaa8583 aurel32
                    if (islit)
1879 dfaa8583 aurel32
                        tcg_gen_subi_i64(tmp, tmp, lit);
1880 dfaa8583 aurel32
                    else
1881 dfaa8583 aurel32
                       tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1882 dfaa8583 aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1883 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1884 30c7183b aurel32
                } else {
1885 30c7183b aurel32
                    if (islit)
1886 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1887 dfaa8583 aurel32
                    else
1888 30c7183b aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1889 30c7183b aurel32
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1890 dfaa8583 aurel32
                    }
1891 30c7183b aurel32
                }
1892 30c7183b aurel32
            }
1893 4c9649a9 j_mayer
            break;
1894 4c9649a9 j_mayer
        case 0x1D:
1895 4c9649a9 j_mayer
            /* CMPULT */
1896 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
1897 4c9649a9 j_mayer
            break;
1898 4c9649a9 j_mayer
        case 0x20:
1899 4c9649a9 j_mayer
            /* ADDQ */
1900 30c7183b aurel32
            if (likely(rc != 31)) {
1901 30c7183b aurel32
                if (ra != 31) {
1902 30c7183b aurel32
                    if (islit)
1903 30c7183b aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1904 30c7183b aurel32
                    else
1905 dfaa8583 aurel32
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1906 30c7183b aurel32
                } else {
1907 30c7183b aurel32
                    if (islit)
1908 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1909 30c7183b aurel32
                    else
1910 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1911 30c7183b aurel32
                }
1912 30c7183b aurel32
            }
1913 4c9649a9 j_mayer
            break;
1914 4c9649a9 j_mayer
        case 0x22:
1915 4c9649a9 j_mayer
            /* S4ADDQ */
1916 30c7183b aurel32
            if (likely(rc != 31)) {
1917 30c7183b aurel32
                if (ra != 31) {
1918 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1919 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1920 dfaa8583 aurel32
                    if (islit)
1921 dfaa8583 aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1922 dfaa8583 aurel32
                    else
1923 dfaa8583 aurel32
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1924 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1925 30c7183b aurel32
                } else {
1926 30c7183b aurel32
                    if (islit)
1927 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1928 30c7183b aurel32
                    else
1929 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1930 30c7183b aurel32
                }
1931 30c7183b aurel32
            }
1932 4c9649a9 j_mayer
            break;
1933 4c9649a9 j_mayer
        case 0x29:
1934 4c9649a9 j_mayer
            /* SUBQ */
1935 30c7183b aurel32
            if (likely(rc != 31)) {
1936 30c7183b aurel32
                if (ra != 31) {
1937 30c7183b aurel32
                    if (islit)
1938 30c7183b aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1939 30c7183b aurel32
                    else
1940 dfaa8583 aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1941 30c7183b aurel32
                } else {
1942 30c7183b aurel32
                    if (islit)
1943 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1944 30c7183b aurel32
                    else
1945 dfaa8583 aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1946 30c7183b aurel32
                }
1947 30c7183b aurel32
            }
1948 4c9649a9 j_mayer
            break;
1949 4c9649a9 j_mayer
        case 0x2B:
1950 4c9649a9 j_mayer
            /* S4SUBQ */
1951 30c7183b aurel32
            if (likely(rc != 31)) {
1952 30c7183b aurel32
                if (ra != 31) {
1953 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1954 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1955 dfaa8583 aurel32
                    if (islit)
1956 dfaa8583 aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
1957 dfaa8583 aurel32
                    else
1958 dfaa8583 aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1959 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1960 30c7183b aurel32
                } else {
1961 30c7183b aurel32
                    if (islit)
1962 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1963 30c7183b aurel32
                    else
1964 dfaa8583 aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1965 30c7183b aurel32
                }
1966 30c7183b aurel32
            }
1967 4c9649a9 j_mayer
            break;
1968 4c9649a9 j_mayer
        case 0x2D:
1969 4c9649a9 j_mayer
            /* CMPEQ */
1970 01ff9cc8 aurel32
            gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
1971 4c9649a9 j_mayer
            break;
1972 4c9649a9 j_mayer
        case 0x32:
1973 4c9649a9 j_mayer
            /* S8ADDQ */
1974 30c7183b aurel32
            if (likely(rc != 31)) {
1975 30c7183b aurel32
                if (ra != 31) {
1976 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1977 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1978 dfaa8583 aurel32
                    if (islit)
1979 dfaa8583 aurel32
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1980 dfaa8583 aurel32
                    else
1981 dfaa8583 aurel32
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1982 dfaa8583 aurel32
                    tcg_temp_free(tmp);
1983 30c7183b aurel32
                } else {
1984 30c7183b aurel32
                    if (islit)
1985 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1986 30c7183b aurel32
                    else
1987 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1988 30c7183b aurel32
                }
1989 30c7183b aurel32
            }
1990 4c9649a9 j_mayer
            break;
1991 4c9649a9 j_mayer
        case 0x3B:
1992 4c9649a9 j_mayer
            /* S8SUBQ */
1993 30c7183b aurel32
            if (likely(rc != 31)) {
1994 30c7183b aurel32
                if (ra != 31) {
1995 a7812ae4 pbrook
                    TCGv tmp = tcg_temp_new();
1996 dfaa8583 aurel32
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1997 dfaa8583 aurel32
                    if (islit)
1998 dfaa8583 aurel32
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
1999 dfaa8583 aurel32
                    else
2000 dfaa8583 aurel32
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2001 dfaa8583 aurel32
                    tcg_temp_free(tmp);
2002 30c7183b aurel32
                } else {
2003 30c7183b aurel32
                    if (islit)
2004 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
2005 30c7183b aurel32
                    else
2006 dfaa8583 aurel32
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2007 30c7183b aurel32
                }
2008 30c7183b aurel32
            }
2009 4c9649a9 j_mayer
            break;
2010 4c9649a9 j_mayer
        case 0x3D:
2011 4c9649a9 j_mayer
            /* CMPULE */
2012 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
2013 4c9649a9 j_mayer
            break;
2014 4c9649a9 j_mayer
        case 0x40:
2015 4c9649a9 j_mayer
            /* ADDL/V */
2016 a7812ae4 pbrook
            gen_addlv(ra, rb, rc, islit, lit);
2017 4c9649a9 j_mayer
            break;
2018 4c9649a9 j_mayer
        case 0x49:
2019 4c9649a9 j_mayer
            /* SUBL/V */
2020 a7812ae4 pbrook
            gen_sublv(ra, rb, rc, islit, lit);
2021 4c9649a9 j_mayer
            break;
2022 4c9649a9 j_mayer
        case 0x4D:
2023 4c9649a9 j_mayer
            /* CMPLT */
2024 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
2025 4c9649a9 j_mayer
            break;
2026 4c9649a9 j_mayer
        case 0x60:
2027 4c9649a9 j_mayer
            /* ADDQ/V */
2028 a7812ae4 pbrook
            gen_addqv(ra, rb, rc, islit, lit);
2029 4c9649a9 j_mayer
            break;
2030 4c9649a9 j_mayer
        case 0x69:
2031 4c9649a9 j_mayer
            /* SUBQ/V */
2032 a7812ae4 pbrook
            gen_subqv(ra, rb, rc, islit, lit);
2033 4c9649a9 j_mayer
            break;
2034 4c9649a9 j_mayer
        case 0x6D:
2035 4c9649a9 j_mayer
            /* CMPLE */
2036 01ff9cc8 aurel32
            gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
2037 4c9649a9 j_mayer
            break;
2038 4c9649a9 j_mayer
        default:
2039 4c9649a9 j_mayer
            goto invalid_opc;
2040 4c9649a9 j_mayer
        }
2041 4c9649a9 j_mayer
        break;
2042 4c9649a9 j_mayer
    case 0x11:
2043 4c9649a9 j_mayer
        switch (fn7) {
2044 4c9649a9 j_mayer
        case 0x00:
2045 4c9649a9 j_mayer
            /* AND */
2046 30c7183b aurel32
            if (likely(rc != 31)) {
2047 dfaa8583 aurel32
                if (ra == 31)
2048 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2049 30c7183b aurel32
                else if (islit)
2050 30c7183b aurel32
                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2051 30c7183b aurel32
                else
2052 30c7183b aurel32
                    tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2053 30c7183b aurel32
            }
2054 4c9649a9 j_mayer
            break;
2055 4c9649a9 j_mayer
        case 0x08:
2056 4c9649a9 j_mayer
            /* BIC */
2057 30c7183b aurel32
            if (likely(rc != 31)) {
2058 30c7183b aurel32
                if (ra != 31) {
2059 30c7183b aurel32
                    if (islit)
2060 30c7183b aurel32
                        tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2061 1b581c44 aurel32
                    else
2062 1b581c44 aurel32
                        tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2063 30c7183b aurel32
                } else
2064 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2065 30c7183b aurel32
            }
2066 4c9649a9 j_mayer
            break;
2067 4c9649a9 j_mayer
        case 0x14:
2068 4c9649a9 j_mayer
            /* CMOVLBS */
2069 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
2070 4c9649a9 j_mayer
            break;
2071 4c9649a9 j_mayer
        case 0x16:
2072 4c9649a9 j_mayer
            /* CMOVLBC */
2073 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
2074 4c9649a9 j_mayer
            break;
2075 4c9649a9 j_mayer
        case 0x20:
2076 4c9649a9 j_mayer
            /* BIS */
2077 30c7183b aurel32
            if (likely(rc != 31)) {
2078 30c7183b aurel32
                if (ra != 31) {
2079 30c7183b aurel32
                    if (islit)
2080 30c7183b aurel32
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2081 8bb6e981 aurel32
                    else
2082 30c7183b aurel32
                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2083 4c9649a9 j_mayer
                } else {
2084 30c7183b aurel32
                    if (islit)
2085 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
2086 30c7183b aurel32
                    else
2087 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2088 4c9649a9 j_mayer
                }
2089 4c9649a9 j_mayer
            }
2090 4c9649a9 j_mayer
            break;
2091 4c9649a9 j_mayer
        case 0x24:
2092 4c9649a9 j_mayer
            /* CMOVEQ */
2093 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
2094 4c9649a9 j_mayer
            break;
2095 4c9649a9 j_mayer
        case 0x26:
2096 4c9649a9 j_mayer
            /* CMOVNE */
2097 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
2098 4c9649a9 j_mayer
            break;
2099 4c9649a9 j_mayer
        case 0x28:
2100 4c9649a9 j_mayer
            /* ORNOT */
2101 30c7183b aurel32
            if (likely(rc != 31)) {
2102 dfaa8583 aurel32
                if (ra != 31) {
2103 30c7183b aurel32
                    if (islit)
2104 30c7183b aurel32
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2105 1b581c44 aurel32
                    else
2106 1b581c44 aurel32
                        tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2107 30c7183b aurel32
                } else {
2108 30c7183b aurel32
                    if (islit)
2109 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2110 30c7183b aurel32
                    else
2111 30c7183b aurel32
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2112 30c7183b aurel32
                }
2113 30c7183b aurel32
            }
2114 4c9649a9 j_mayer
            break;
2115 4c9649a9 j_mayer
        case 0x40:
2116 4c9649a9 j_mayer
            /* XOR */
2117 30c7183b aurel32
            if (likely(rc != 31)) {
2118 30c7183b aurel32
                if (ra != 31) {
2119 30c7183b aurel32
                    if (islit)
2120 30c7183b aurel32
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2121 30c7183b aurel32
                    else
2122 dfaa8583 aurel32
                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2123 30c7183b aurel32
                } else {
2124 30c7183b aurel32
                    if (islit)
2125 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
2126 30c7183b aurel32
                    else
2127 dfaa8583 aurel32
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2128 30c7183b aurel32
                }
2129 30c7183b aurel32
            }
2130 4c9649a9 j_mayer
            break;
2131 4c9649a9 j_mayer
        case 0x44:
2132 4c9649a9 j_mayer
            /* CMOVLT */
2133 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
2134 4c9649a9 j_mayer
            break;
2135 4c9649a9 j_mayer
        case 0x46:
2136 4c9649a9 j_mayer
            /* CMOVGE */
2137 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
2138 4c9649a9 j_mayer
            break;
2139 4c9649a9 j_mayer
        case 0x48:
2140 4c9649a9 j_mayer
            /* EQV */
2141 30c7183b aurel32
            if (likely(rc != 31)) {
2142 30c7183b aurel32
                if (ra != 31) {
2143 30c7183b aurel32
                    if (islit)
2144 30c7183b aurel32
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2145 1b581c44 aurel32
                    else
2146 1b581c44 aurel32
                        tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2147 30c7183b aurel32
                } else {
2148 30c7183b aurel32
                    if (islit)
2149 30c7183b aurel32
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2150 30c7183b aurel32
                    else
2151 dfaa8583 aurel32
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2152 30c7183b aurel32
                }
2153 30c7183b aurel32
            }
2154 4c9649a9 j_mayer
            break;
2155 4c9649a9 j_mayer
        case 0x61:
2156 4c9649a9 j_mayer
            /* AMASK */
2157 ae8ecd42 aurel32
            if (likely(rc != 31)) {
2158 a18ad893 Richard Henderson
                uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
2159 a18ad893 Richard Henderson
2160 a18ad893 Richard Henderson
                if (islit) {
2161 a18ad893 Richard Henderson
                    tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
2162 a18ad893 Richard Henderson
                } else {
2163 a18ad893 Richard Henderson
                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
2164 1a1f7dbc aurel32
                }
2165 ae8ecd42 aurel32
            }
2166 4c9649a9 j_mayer
            break;
2167 4c9649a9 j_mayer
        case 0x64:
2168 4c9649a9 j_mayer
            /* CMOVLE */
2169 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
2170 4c9649a9 j_mayer
            break;
2171 4c9649a9 j_mayer
        case 0x66:
2172 4c9649a9 j_mayer
            /* CMOVGT */
2173 bbe1dab4 Richard Henderson
            gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
2174 4c9649a9 j_mayer
            break;
2175 4c9649a9 j_mayer
        case 0x6C:
2176 4c9649a9 j_mayer
            /* IMPLVER */
2177 3761035f aurel32
            if (rc != 31)
2178 8579095b aurel32
                tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
2179 4c9649a9 j_mayer
            break;
2180 4c9649a9 j_mayer
        default:
2181 4c9649a9 j_mayer
            goto invalid_opc;
2182 4c9649a9 j_mayer
        }
2183 4c9649a9 j_mayer
        break;
2184 4c9649a9 j_mayer
    case 0x12:
2185 4c9649a9 j_mayer
        switch (fn7) {
2186 4c9649a9 j_mayer
        case 0x02:
2187 4c9649a9 j_mayer
            /* MSKBL */
2188 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0x01);
2189 4c9649a9 j_mayer
            break;
2190 4c9649a9 j_mayer
        case 0x06:
2191 4c9649a9 j_mayer
            /* EXTBL */
2192 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0x01);
2193 4c9649a9 j_mayer
            break;
2194 4c9649a9 j_mayer
        case 0x0B:
2195 4c9649a9 j_mayer
            /* INSBL */
2196 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0x01);
2197 4c9649a9 j_mayer
            break;
2198 4c9649a9 j_mayer
        case 0x12:
2199 4c9649a9 j_mayer
            /* MSKWL */
2200 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0x03);
2201 4c9649a9 j_mayer
            break;
2202 4c9649a9 j_mayer
        case 0x16:
2203 4c9649a9 j_mayer
            /* EXTWL */
2204 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0x03);
2205 4c9649a9 j_mayer
            break;
2206 4c9649a9 j_mayer
        case 0x1B:
2207 4c9649a9 j_mayer
            /* INSWL */
2208 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0x03);
2209 4c9649a9 j_mayer
            break;
2210 4c9649a9 j_mayer
        case 0x22:
2211 4c9649a9 j_mayer
            /* MSKLL */
2212 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
2213 4c9649a9 j_mayer
            break;
2214 4c9649a9 j_mayer
        case 0x26:
2215 4c9649a9 j_mayer
            /* EXTLL */
2216 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
2217 4c9649a9 j_mayer
            break;
2218 4c9649a9 j_mayer
        case 0x2B:
2219 4c9649a9 j_mayer
            /* INSLL */
2220 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
2221 4c9649a9 j_mayer
            break;
2222 4c9649a9 j_mayer
        case 0x30:
2223 4c9649a9 j_mayer
            /* ZAP */
2224 a7812ae4 pbrook
            gen_zap(ra, rb, rc, islit, lit);
2225 4c9649a9 j_mayer
            break;
2226 4c9649a9 j_mayer
        case 0x31:
2227 4c9649a9 j_mayer
            /* ZAPNOT */
2228 a7812ae4 pbrook
            gen_zapnot(ra, rb, rc, islit, lit);
2229 4c9649a9 j_mayer
            break;
2230 4c9649a9 j_mayer
        case 0x32:
2231 4c9649a9 j_mayer
            /* MSKQL */
2232 14ab1634 Richard Henderson
            gen_msk_l(ra, rb, rc, islit, lit, 0xff);
2233 4c9649a9 j_mayer
            break;
2234 4c9649a9 j_mayer
        case 0x34:
2235 4c9649a9 j_mayer
            /* SRL */
2236 30c7183b aurel32
            if (likely(rc != 31)) {
2237 30c7183b aurel32
                if (ra != 31) {
2238 30c7183b aurel32
                    if (islit)
2239 30c7183b aurel32
                        tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2240 dfaa8583 aurel32
                    else {
2241 a7812ae4 pbrook
                        TCGv shift = tcg_temp_new();
2242 30c7183b aurel32
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2243 30c7183b aurel32
                        tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
2244 30c7183b aurel32
                        tcg_temp_free(shift);
2245 dfaa8583 aurel32
                    }
2246 30c7183b aurel32
                } else
2247 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2248 30c7183b aurel32
            }
2249 4c9649a9 j_mayer
            break;
2250 4c9649a9 j_mayer
        case 0x36:
2251 4c9649a9 j_mayer
            /* EXTQL */
2252 377a43b6 Richard Henderson
            gen_ext_l(ra, rb, rc, islit, lit, 0xff);
2253 4c9649a9 j_mayer
            break;
2254 4c9649a9 j_mayer
        case 0x39:
2255 4c9649a9 j_mayer
            /* SLL */
2256 30c7183b aurel32
            if (likely(rc != 31)) {
2257 30c7183b aurel32
                if (ra != 31) {
2258 30c7183b aurel32
                    if (islit)
2259 30c7183b aurel32
                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2260 dfaa8583 aurel32
                    else {
2261 a7812ae4 pbrook
                        TCGv shift = tcg_temp_new();
2262 30c7183b aurel32
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2263 30c7183b aurel32
                        tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
2264 30c7183b aurel32
                        tcg_temp_free(shift);
2265 dfaa8583 aurel32
                    }
2266 30c7183b aurel32
                } else
2267 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2268 30c7183b aurel32
            }
2269 4c9649a9 j_mayer
            break;
2270 4c9649a9 j_mayer
        case 0x3B:
2271 4c9649a9 j_mayer
            /* INSQL */
2272 248c42f3 Richard Henderson
            gen_ins_l(ra, rb, rc, islit, lit, 0xff);
2273 4c9649a9 j_mayer
            break;
2274 4c9649a9 j_mayer
        case 0x3C:
2275 4c9649a9 j_mayer
            /* SRA */
2276 30c7183b aurel32
            if (likely(rc != 31)) {
2277 30c7183b aurel32
                if (ra != 31) {
2278 30c7183b aurel32
                    if (islit)
2279 30c7183b aurel32
                        tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2280 dfaa8583 aurel32
                    else {
2281 a7812ae4 pbrook
                        TCGv shift = tcg_temp_new();
2282 30c7183b aurel32
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2283 30c7183b aurel32
                        tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
2284 30c7183b aurel32
                        tcg_temp_free(shift);
2285 dfaa8583 aurel32
                    }
2286 30c7183b aurel32
                } else
2287 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2288 30c7183b aurel32
            }
2289 4c9649a9 j_mayer
            break;
2290 4c9649a9 j_mayer
        case 0x52:
2291 4c9649a9 j_mayer
            /* MSKWH */
2292 ffec44f1 Richard Henderson
            gen_msk_h(ra, rb, rc, islit, lit, 0x03);
2293 4c9649a9 j_mayer
            break;
2294 4c9649a9 j_mayer
        case 0x57:
2295 4c9649a9 j_mayer
            /* INSWH */
2296 50eb6e5c Richard Henderson
            gen_ins_h(ra, rb, rc, islit, lit, 0x03);
2297 4c9649a9 j_mayer
            break;
2298 4c9649a9 j_mayer
        case 0x5A:
2299 4c9649a9 j_mayer
            /* EXTWH */
2300 377a43b6 Richard Henderson
            gen_ext_h(ra, rb, rc, islit, lit, 0x03);
2301 4c9649a9 j_mayer
            break;
2302 4c9649a9 j_mayer
        case 0x62:
2303 4c9649a9 j_mayer
            /* MSKLH */
2304 ffec44f1 Richard Henderson
            gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
2305 4c9649a9 j_mayer
            break;
2306 4c9649a9 j_mayer
        case 0x67:
2307 4c9649a9 j_mayer
            /* INSLH */
2308 50eb6e5c Richard Henderson
            gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
2309 4c9649a9 j_mayer
            break;
2310 4c9649a9 j_mayer
        case 0x6A:
2311 4c9649a9 j_mayer
            /* EXTLH */
2312 377a43b6 Richard Henderson
            gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
2313 4c9649a9 j_mayer
            break;
2314 4c9649a9 j_mayer
        case 0x72:
2315 4c9649a9 j_mayer
            /* MSKQH */
2316 ffec44f1 Richard Henderson
            gen_msk_h(ra, rb, rc, islit, lit, 0xff);
2317 4c9649a9 j_mayer
            break;
2318 4c9649a9 j_mayer
        case 0x77:
2319 4c9649a9 j_mayer
            /* INSQH */
2320 50eb6e5c Richard Henderson
            gen_ins_h(ra, rb, rc, islit, lit, 0xff);
2321 4c9649a9 j_mayer
            break;
2322 4c9649a9 j_mayer
        case 0x7A:
2323 4c9649a9 j_mayer
            /* EXTQH */
2324 377a43b6 Richard Henderson
            gen_ext_h(ra, rb, rc, islit, lit, 0xff);
2325 4c9649a9 j_mayer
            break;
2326 4c9649a9 j_mayer
        default:
2327 4c9649a9 j_mayer
            goto invalid_opc;
2328 4c9649a9 j_mayer
        }
2329 4c9649a9 j_mayer
        break;
2330 4c9649a9 j_mayer
    case 0x13:
2331 4c9649a9 j_mayer
        switch (fn7) {
2332 4c9649a9 j_mayer
        case 0x00:
2333 4c9649a9 j_mayer
            /* MULL */
2334 30c7183b aurel32
            if (likely(rc != 31)) {
2335 dfaa8583 aurel32
                if (ra == 31)
2336 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2337 30c7183b aurel32
                else {
2338 30c7183b aurel32
                    if (islit)
2339 30c7183b aurel32
                        tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2340 30c7183b aurel32
                    else
2341 30c7183b aurel32
                        tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2342 30c7183b aurel32
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
2343 30c7183b aurel32
                }
2344 30c7183b aurel32
            }
2345 4c9649a9 j_mayer
            break;
2346 4c9649a9 j_mayer
        case 0x20:
2347 4c9649a9 j_mayer
            /* MULQ */
2348 30c7183b aurel32
            if (likely(rc != 31)) {
2349 dfaa8583 aurel32
                if (ra == 31)
2350 30c7183b aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2351 30c7183b aurel32
                else if (islit)
2352 30c7183b aurel32
                    tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2353 30c7183b aurel32
                else
2354 30c7183b aurel32
                    tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2355 30c7183b aurel32
            }
2356 4c9649a9 j_mayer
            break;
2357 4c9649a9 j_mayer
        case 0x30:
2358 4c9649a9 j_mayer
            /* UMULH */
2359 a7812ae4 pbrook
            gen_umulh(ra, rb, rc, islit, lit);
2360 4c9649a9 j_mayer
            break;
2361 4c9649a9 j_mayer
        case 0x40:
2362 4c9649a9 j_mayer
            /* MULL/V */
2363 a7812ae4 pbrook
            gen_mullv(ra, rb, rc, islit, lit);
2364 4c9649a9 j_mayer
            break;
2365 4c9649a9 j_mayer
        case 0x60:
2366 4c9649a9 j_mayer
            /* MULQ/V */
2367 a7812ae4 pbrook
            gen_mulqv(ra, rb, rc, islit, lit);
2368 4c9649a9 j_mayer
            break;
2369 4c9649a9 j_mayer
        default:
2370 4c9649a9 j_mayer
            goto invalid_opc;
2371 4c9649a9 j_mayer
        }
2372 4c9649a9 j_mayer
        break;
2373 4c9649a9 j_mayer
    case 0x14:
2374 f24518b5 Richard Henderson
        switch (fpfn) { /* fn11 & 0x3F */
2375 4c9649a9 j_mayer
        case 0x04:
2376 4c9649a9 j_mayer
            /* ITOFS */
2377 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2378 4c9649a9 j_mayer
                goto invalid_opc;
2379 a18ad893 Richard Henderson
            }
2380 f18cd223 aurel32
            if (likely(rc != 31)) {
2381 f18cd223 aurel32
                if (ra != 31) {
2382 a7812ae4 pbrook
                    TCGv_i32 tmp = tcg_temp_new_i32();
2383 f18cd223 aurel32
                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2384 a7812ae4 pbrook
                    gen_helper_memory_to_s(cpu_fir[rc], tmp);
2385 a7812ae4 pbrook
                    tcg_temp_free_i32(tmp);
2386 f18cd223 aurel32
                } else
2387 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
2388 f18cd223 aurel32
            }
2389 4c9649a9 j_mayer
            break;
2390 4c9649a9 j_mayer
        case 0x0A:
2391 4c9649a9 j_mayer
            /* SQRTF */
2392 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2393 a18ad893 Richard Henderson
                gen_fsqrtf(rb, rc);
2394 a18ad893 Richard Henderson
                break;
2395 a18ad893 Richard Henderson
            }
2396 a18ad893 Richard Henderson
            goto invalid_opc;
2397 4c9649a9 j_mayer
        case 0x0B:
2398 4c9649a9 j_mayer
            /* SQRTS */
2399 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2400 a18ad893 Richard Henderson
                gen_fsqrts(ctx, rb, rc, fn11);
2401 a18ad893 Richard Henderson
                break;
2402 a18ad893 Richard Henderson
            }
2403 a18ad893 Richard Henderson
            goto invalid_opc;
2404 4c9649a9 j_mayer
        case 0x14:
2405 4c9649a9 j_mayer
            /* ITOFF */
2406 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2407 4c9649a9 j_mayer
                goto invalid_opc;
2408 a18ad893 Richard Henderson
            }
2409 f18cd223 aurel32
            if (likely(rc != 31)) {
2410 f18cd223 aurel32
                if (ra != 31) {
2411 a7812ae4 pbrook
                    TCGv_i32 tmp = tcg_temp_new_i32();
2412 f18cd223 aurel32
                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2413 a7812ae4 pbrook
                    gen_helper_memory_to_f(cpu_fir[rc], tmp);
2414 a7812ae4 pbrook
                    tcg_temp_free_i32(tmp);
2415 f18cd223 aurel32
                } else
2416 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
2417 f18cd223 aurel32
            }
2418 4c9649a9 j_mayer
            break;
2419 4c9649a9 j_mayer
        case 0x24:
2420 4c9649a9 j_mayer
            /* ITOFT */
2421 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2422 4c9649a9 j_mayer
                goto invalid_opc;
2423 a18ad893 Richard Henderson
            }
2424 f18cd223 aurel32
            if (likely(rc != 31)) {
2425 f18cd223 aurel32
                if (ra != 31)
2426 f18cd223 aurel32
                    tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
2427 f18cd223 aurel32
                else
2428 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
2429 f18cd223 aurel32
            }
2430 4c9649a9 j_mayer
            break;
2431 4c9649a9 j_mayer
        case 0x2A:
2432 4c9649a9 j_mayer
            /* SQRTG */
2433 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2434 a18ad893 Richard Henderson
                gen_fsqrtg(rb, rc);
2435 a18ad893 Richard Henderson
                break;
2436 a18ad893 Richard Henderson
            }
2437 a18ad893 Richard Henderson
            goto invalid_opc;
2438 4c9649a9 j_mayer
        case 0x02B:
2439 4c9649a9 j_mayer
            /* SQRTT */
2440 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2441 a18ad893 Richard Henderson
                gen_fsqrtt(ctx, rb, rc, fn11);
2442 a18ad893 Richard Henderson
                break;
2443 a18ad893 Richard Henderson
            }
2444 a18ad893 Richard Henderson
            goto invalid_opc;
2445 4c9649a9 j_mayer
        default:
2446 4c9649a9 j_mayer
            goto invalid_opc;
2447 4c9649a9 j_mayer
        }
2448 4c9649a9 j_mayer
        break;
2449 4c9649a9 j_mayer
    case 0x15:
2450 4c9649a9 j_mayer
        /* VAX floating point */
2451 4c9649a9 j_mayer
        /* XXX: rounding mode and trap are ignored (!) */
2452 f24518b5 Richard Henderson
        switch (fpfn) { /* fn11 & 0x3F */
2453 4c9649a9 j_mayer
        case 0x00:
2454 4c9649a9 j_mayer
            /* ADDF */
2455 a7812ae4 pbrook
            gen_faddf(ra, rb, rc);
2456 4c9649a9 j_mayer
            break;
2457 4c9649a9 j_mayer
        case 0x01:
2458 4c9649a9 j_mayer
            /* SUBF */
2459 a7812ae4 pbrook
            gen_fsubf(ra, rb, rc);
2460 4c9649a9 j_mayer
            break;
2461 4c9649a9 j_mayer
        case 0x02:
2462 4c9649a9 j_mayer
            /* MULF */
2463 a7812ae4 pbrook
            gen_fmulf(ra, rb, rc);
2464 4c9649a9 j_mayer
            break;
2465 4c9649a9 j_mayer
        case 0x03:
2466 4c9649a9 j_mayer
            /* DIVF */
2467 a7812ae4 pbrook
            gen_fdivf(ra, rb, rc);
2468 4c9649a9 j_mayer
            break;
2469 4c9649a9 j_mayer
        case 0x1E:
2470 4c9649a9 j_mayer
            /* CVTDG */
2471 4c9649a9 j_mayer
#if 0 // TODO
2472 a7812ae4 pbrook
            gen_fcvtdg(rb, rc);
2473 4c9649a9 j_mayer
#else
2474 4c9649a9 j_mayer
            goto invalid_opc;
2475 4c9649a9 j_mayer
#endif
2476 4c9649a9 j_mayer
            break;
2477 4c9649a9 j_mayer
        case 0x20:
2478 4c9649a9 j_mayer
            /* ADDG */
2479 a7812ae4 pbrook
            gen_faddg(ra, rb, rc);
2480 4c9649a9 j_mayer
            break;
2481 4c9649a9 j_mayer
        case 0x21:
2482 4c9649a9 j_mayer
            /* SUBG */
2483 a7812ae4 pbrook
            gen_fsubg(ra, rb, rc);
2484 4c9649a9 j_mayer
            break;
2485 4c9649a9 j_mayer
        case 0x22:
2486 4c9649a9 j_mayer
            /* MULG */
2487 a7812ae4 pbrook
            gen_fmulg(ra, rb, rc);
2488 4c9649a9 j_mayer
            break;
2489 4c9649a9 j_mayer
        case 0x23:
2490 4c9649a9 j_mayer
            /* DIVG */
2491 a7812ae4 pbrook
            gen_fdivg(ra, rb, rc);
2492 4c9649a9 j_mayer
            break;
2493 4c9649a9 j_mayer
        case 0x25:
2494 4c9649a9 j_mayer
            /* CMPGEQ */
2495 a7812ae4 pbrook
            gen_fcmpgeq(ra, rb, rc);
2496 4c9649a9 j_mayer
            break;
2497 4c9649a9 j_mayer
        case 0x26:
2498 4c9649a9 j_mayer
            /* CMPGLT */
2499 a7812ae4 pbrook
            gen_fcmpglt(ra, rb, rc);
2500 4c9649a9 j_mayer
            break;
2501 4c9649a9 j_mayer
        case 0x27:
2502 4c9649a9 j_mayer
            /* CMPGLE */
2503 a7812ae4 pbrook
            gen_fcmpgle(ra, rb, rc);
2504 4c9649a9 j_mayer
            break;
2505 4c9649a9 j_mayer
        case 0x2C:
2506 4c9649a9 j_mayer
            /* CVTGF */
2507 a7812ae4 pbrook
            gen_fcvtgf(rb, rc);
2508 4c9649a9 j_mayer
            break;
2509 4c9649a9 j_mayer
        case 0x2D:
2510 4c9649a9 j_mayer
            /* CVTGD */
2511 4c9649a9 j_mayer
#if 0 // TODO
2512 a7812ae4 pbrook
            gen_fcvtgd(rb, rc);
2513 4c9649a9 j_mayer
#else
2514 4c9649a9 j_mayer
            goto invalid_opc;
2515 4c9649a9 j_mayer
#endif
2516 4c9649a9 j_mayer
            break;
2517 4c9649a9 j_mayer
        case 0x2F:
2518 4c9649a9 j_mayer
            /* CVTGQ */
2519 a7812ae4 pbrook
            gen_fcvtgq(rb, rc);
2520 4c9649a9 j_mayer
            break;
2521 4c9649a9 j_mayer
        case 0x3C:
2522 4c9649a9 j_mayer
            /* CVTQF */
2523 a7812ae4 pbrook
            gen_fcvtqf(rb, rc);
2524 4c9649a9 j_mayer
            break;
2525 4c9649a9 j_mayer
        case 0x3E:
2526 4c9649a9 j_mayer
            /* CVTQG */
2527 a7812ae4 pbrook
            gen_fcvtqg(rb, rc);
2528 4c9649a9 j_mayer
            break;
2529 4c9649a9 j_mayer
        default:
2530 4c9649a9 j_mayer
            goto invalid_opc;
2531 4c9649a9 j_mayer
        }
2532 4c9649a9 j_mayer
        break;
2533 4c9649a9 j_mayer
    case 0x16:
2534 4c9649a9 j_mayer
        /* IEEE floating-point */
2535 f24518b5 Richard Henderson
        switch (fpfn) { /* fn11 & 0x3F */
2536 4c9649a9 j_mayer
        case 0x00:
2537 4c9649a9 j_mayer
            /* ADDS */
2538 f24518b5 Richard Henderson
            gen_fadds(ctx, ra, rb, rc, fn11);
2539 4c9649a9 j_mayer
            break;
2540 4c9649a9 j_mayer
        case 0x01:
2541 4c9649a9 j_mayer
            /* SUBS */
2542 f24518b5 Richard Henderson
            gen_fsubs(ctx, ra, rb, rc, fn11);
2543 4c9649a9 j_mayer
            break;
2544 4c9649a9 j_mayer
        case 0x02:
2545 4c9649a9 j_mayer
            /* MULS */
2546 f24518b5 Richard Henderson
            gen_fmuls(ctx, ra, rb, rc, fn11);
2547 4c9649a9 j_mayer
            break;
2548 4c9649a9 j_mayer
        case 0x03:
2549 4c9649a9 j_mayer
            /* DIVS */
2550 f24518b5 Richard Henderson
            gen_fdivs(ctx, ra, rb, rc, fn11);
2551 4c9649a9 j_mayer
            break;
2552 4c9649a9 j_mayer
        case 0x20:
2553 4c9649a9 j_mayer
            /* ADDT */
2554 f24518b5 Richard Henderson
            gen_faddt(ctx, ra, rb, rc, fn11);
2555 4c9649a9 j_mayer
            break;
2556 4c9649a9 j_mayer
        case 0x21:
2557 4c9649a9 j_mayer
            /* SUBT */
2558 f24518b5 Richard Henderson
            gen_fsubt(ctx, ra, rb, rc, fn11);
2559 4c9649a9 j_mayer
            break;
2560 4c9649a9 j_mayer
        case 0x22:
2561 4c9649a9 j_mayer
            /* MULT */
2562 f24518b5 Richard Henderson
            gen_fmult(ctx, ra, rb, rc, fn11);
2563 4c9649a9 j_mayer
            break;
2564 4c9649a9 j_mayer
        case 0x23:
2565 4c9649a9 j_mayer
            /* DIVT */
2566 f24518b5 Richard Henderson
            gen_fdivt(ctx, ra, rb, rc, fn11);
2567 4c9649a9 j_mayer
            break;
2568 4c9649a9 j_mayer
        case 0x24:
2569 4c9649a9 j_mayer
            /* CMPTUN */
2570 f24518b5 Richard Henderson
            gen_fcmptun(ctx, ra, rb, rc, fn11);
2571 4c9649a9 j_mayer
            break;
2572 4c9649a9 j_mayer
        case 0x25:
2573 4c9649a9 j_mayer
            /* CMPTEQ */
2574 f24518b5 Richard Henderson
            gen_fcmpteq(ctx, ra, rb, rc, fn11);
2575 4c9649a9 j_mayer
            break;
2576 4c9649a9 j_mayer
        case 0x26:
2577 4c9649a9 j_mayer
            /* CMPTLT */
2578 f24518b5 Richard Henderson
            gen_fcmptlt(ctx, ra, rb, rc, fn11);
2579 4c9649a9 j_mayer
            break;
2580 4c9649a9 j_mayer
        case 0x27:
2581 4c9649a9 j_mayer
            /* CMPTLE */
2582 f24518b5 Richard Henderson
            gen_fcmptle(ctx, ra, rb, rc, fn11);
2583 4c9649a9 j_mayer
            break;
2584 4c9649a9 j_mayer
        case 0x2C:
2585 a74b4d2c aurel32
            if (fn11 == 0x2AC || fn11 == 0x6AC) {
2586 4c9649a9 j_mayer
                /* CVTST */
2587 f24518b5 Richard Henderson
                gen_fcvtst(ctx, rb, rc, fn11);
2588 4c9649a9 j_mayer
            } else {
2589 4c9649a9 j_mayer
                /* CVTTS */
2590 f24518b5 Richard Henderson
                gen_fcvtts(ctx, rb, rc, fn11);
2591 4c9649a9 j_mayer
            }
2592 4c9649a9 j_mayer
            break;
2593 4c9649a9 j_mayer
        case 0x2F:
2594 4c9649a9 j_mayer
            /* CVTTQ */
2595 f24518b5 Richard Henderson
            gen_fcvttq(ctx, rb, rc, fn11);
2596 4c9649a9 j_mayer
            break;
2597 4c9649a9 j_mayer
        case 0x3C:
2598 4c9649a9 j_mayer
            /* CVTQS */
2599 f24518b5 Richard Henderson
            gen_fcvtqs(ctx, rb, rc, fn11);
2600 4c9649a9 j_mayer
            break;
2601 4c9649a9 j_mayer
        case 0x3E:
2602 4c9649a9 j_mayer
            /* CVTQT */
2603 f24518b5 Richard Henderson
            gen_fcvtqt(ctx, rb, rc, fn11);
2604 4c9649a9 j_mayer
            break;
2605 4c9649a9 j_mayer
        default:
2606 4c9649a9 j_mayer
            goto invalid_opc;
2607 4c9649a9 j_mayer
        }
2608 4c9649a9 j_mayer
        break;
2609 4c9649a9 j_mayer
    case 0x17:
2610 4c9649a9 j_mayer
        switch (fn11) {
2611 4c9649a9 j_mayer
        case 0x010:
2612 4c9649a9 j_mayer
            /* CVTLQ */
2613 a7812ae4 pbrook
            gen_fcvtlq(rb, rc);
2614 4c9649a9 j_mayer
            break;
2615 4c9649a9 j_mayer
        case 0x020:
2616 f18cd223 aurel32
            if (likely(rc != 31)) {
2617 a06d48d9 Richard Henderson
                if (ra == rb) {
2618 4c9649a9 j_mayer
                    /* FMOV */
2619 a06d48d9 Richard Henderson
                    if (ra == 31)
2620 a06d48d9 Richard Henderson
                        tcg_gen_movi_i64(cpu_fir[rc], 0);
2621 a06d48d9 Richard Henderson
                    else
2622 a06d48d9 Richard Henderson
                        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
2623 a06d48d9 Richard Henderson
                } else {
2624 f18cd223 aurel32
                    /* CPYS */
2625 a7812ae4 pbrook
                    gen_fcpys(ra, rb, rc);
2626 a06d48d9 Richard Henderson
                }
2627 4c9649a9 j_mayer
            }
2628 4c9649a9 j_mayer
            break;
2629 4c9649a9 j_mayer
        case 0x021:
2630 4c9649a9 j_mayer
            /* CPYSN */
2631 a7812ae4 pbrook
            gen_fcpysn(ra, rb, rc);
2632 4c9649a9 j_mayer
            break;
2633 4c9649a9 j_mayer
        case 0x022:
2634 4c9649a9 j_mayer
            /* CPYSE */
2635 a7812ae4 pbrook
            gen_fcpyse(ra, rb, rc);
2636 4c9649a9 j_mayer
            break;
2637 4c9649a9 j_mayer
        case 0x024:
2638 4c9649a9 j_mayer
            /* MT_FPCR */
2639 f18cd223 aurel32
            if (likely(ra != 31))
2640 a7812ae4 pbrook
                gen_helper_store_fpcr(cpu_fir[ra]);
2641 f18cd223 aurel32
            else {
2642 f18cd223 aurel32
                TCGv tmp = tcg_const_i64(0);
2643 a7812ae4 pbrook
                gen_helper_store_fpcr(tmp);
2644 f18cd223 aurel32
                tcg_temp_free(tmp);
2645 f18cd223 aurel32
            }
2646 4c9649a9 j_mayer
            break;
2647 4c9649a9 j_mayer
        case 0x025:
2648 4c9649a9 j_mayer
            /* MF_FPCR */
2649 f18cd223 aurel32
            if (likely(ra != 31))
2650 a7812ae4 pbrook
                gen_helper_load_fpcr(cpu_fir[ra]);
2651 4c9649a9 j_mayer
            break;
2652 4c9649a9 j_mayer
        case 0x02A:
2653 4c9649a9 j_mayer
            /* FCMOVEQ */
2654 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_EQ, ra, rb, rc);
2655 4c9649a9 j_mayer
            break;
2656 4c9649a9 j_mayer
        case 0x02B:
2657 4c9649a9 j_mayer
            /* FCMOVNE */
2658 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_NE, ra, rb, rc);
2659 4c9649a9 j_mayer
            break;
2660 4c9649a9 j_mayer
        case 0x02C:
2661 4c9649a9 j_mayer
            /* FCMOVLT */
2662 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_LT, ra, rb, rc);
2663 4c9649a9 j_mayer
            break;
2664 4c9649a9 j_mayer
        case 0x02D:
2665 4c9649a9 j_mayer
            /* FCMOVGE */
2666 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_GE, ra, rb, rc);
2667 4c9649a9 j_mayer
            break;
2668 4c9649a9 j_mayer
        case 0x02E:
2669 4c9649a9 j_mayer
            /* FCMOVLE */
2670 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_LE, ra, rb, rc);
2671 4c9649a9 j_mayer
            break;
2672 4c9649a9 j_mayer
        case 0x02F:
2673 4c9649a9 j_mayer
            /* FCMOVGT */
2674 bbe1dab4 Richard Henderson
            gen_fcmov(TCG_COND_GT, ra, rb, rc);
2675 4c9649a9 j_mayer
            break;
2676 4c9649a9 j_mayer
        case 0x030:
2677 4c9649a9 j_mayer
            /* CVTQL */
2678 a7812ae4 pbrook
            gen_fcvtql(rb, rc);
2679 4c9649a9 j_mayer
            break;
2680 4c9649a9 j_mayer
        case 0x130:
2681 4c9649a9 j_mayer
            /* CVTQL/V */
2682 4c9649a9 j_mayer
        case 0x530:
2683 4c9649a9 j_mayer
            /* CVTQL/SV */
2684 735cf45f Richard Henderson
            /* ??? I'm pretty sure there's nothing that /sv needs to do that
2685 735cf45f Richard Henderson
               /v doesn't do.  The only thing I can think is that /sv is a
2686 735cf45f Richard Henderson
               valid instruction merely for completeness in the ISA.  */
2687 735cf45f Richard Henderson
            gen_fcvtql_v(ctx, rb, rc);
2688 4c9649a9 j_mayer
            break;
2689 4c9649a9 j_mayer
        default:
2690 4c9649a9 j_mayer
            goto invalid_opc;
2691 4c9649a9 j_mayer
        }
2692 4c9649a9 j_mayer
        break;
2693 4c9649a9 j_mayer
    case 0x18:
2694 4c9649a9 j_mayer
        switch ((uint16_t)disp16) {
2695 4c9649a9 j_mayer
        case 0x0000:
2696 4c9649a9 j_mayer
            /* TRAPB */
2697 4af70374 Richard Henderson
            /* No-op.  */
2698 4c9649a9 j_mayer
            break;
2699 4c9649a9 j_mayer
        case 0x0400:
2700 4c9649a9 j_mayer
            /* EXCB */
2701 4af70374 Richard Henderson
            /* No-op.  */
2702 4c9649a9 j_mayer
            break;
2703 4c9649a9 j_mayer
        case 0x4000:
2704 4c9649a9 j_mayer
            /* MB */
2705 4c9649a9 j_mayer
            /* No-op */
2706 4c9649a9 j_mayer
            break;
2707 4c9649a9 j_mayer
        case 0x4400:
2708 4c9649a9 j_mayer
            /* WMB */
2709 4c9649a9 j_mayer
            /* No-op */
2710 4c9649a9 j_mayer
            break;
2711 4c9649a9 j_mayer
        case 0x8000:
2712 4c9649a9 j_mayer
            /* FETCH */
2713 4c9649a9 j_mayer
            /* No-op */
2714 4c9649a9 j_mayer
            break;
2715 4c9649a9 j_mayer
        case 0xA000:
2716 4c9649a9 j_mayer
            /* FETCH_M */
2717 4c9649a9 j_mayer
            /* No-op */
2718 4c9649a9 j_mayer
            break;
2719 4c9649a9 j_mayer
        case 0xC000:
2720 4c9649a9 j_mayer
            /* RPCC */
2721 3761035f aurel32
            if (ra != 31)
2722 a7812ae4 pbrook
                gen_helper_load_pcc(cpu_ir[ra]);
2723 4c9649a9 j_mayer
            break;
2724 4c9649a9 j_mayer
        case 0xE000:
2725 4c9649a9 j_mayer
            /* RC */
2726 ac316ca4 Richard Henderson
            gen_rx(ra, 0);
2727 4c9649a9 j_mayer
            break;
2728 4c9649a9 j_mayer
        case 0xE800:
2729 4c9649a9 j_mayer
            /* ECB */
2730 4c9649a9 j_mayer
            break;
2731 4c9649a9 j_mayer
        case 0xF000:
2732 4c9649a9 j_mayer
            /* RS */
2733 ac316ca4 Richard Henderson
            gen_rx(ra, 1);
2734 4c9649a9 j_mayer
            break;
2735 4c9649a9 j_mayer
        case 0xF800:
2736 4c9649a9 j_mayer
            /* WH64 */
2737 4c9649a9 j_mayer
            /* No-op */
2738 4c9649a9 j_mayer
            break;
2739 4c9649a9 j_mayer
        default:
2740 4c9649a9 j_mayer
            goto invalid_opc;
2741 4c9649a9 j_mayer
        }
2742 4c9649a9 j_mayer
        break;
2743 4c9649a9 j_mayer
    case 0x19:
2744 4c9649a9 j_mayer
        /* HW_MFPR (PALcode) */
2745 26b46094 Richard Henderson
#ifndef CONFIG_USER_ONLY
2746 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2747 26b46094 Richard Henderson
            gen_mfpr(ra, insn & 0xffff);
2748 26b46094 Richard Henderson
            break;
2749 26b46094 Richard Henderson
        }
2750 26b46094 Richard Henderson
#endif
2751 4c9649a9 j_mayer
        goto invalid_opc;
2752 4c9649a9 j_mayer
    case 0x1A:
2753 49563a72 Richard Henderson
        /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
2754 49563a72 Richard Henderson
           prediction stack action, which of course we don't implement.  */
2755 49563a72 Richard Henderson
        if (rb != 31) {
2756 3761035f aurel32
            tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
2757 49563a72 Richard Henderson
        } else {
2758 3761035f aurel32
            tcg_gen_movi_i64(cpu_pc, 0);
2759 49563a72 Richard Henderson
        }
2760 49563a72 Richard Henderson
        if (ra != 31) {
2761 1304ca87 aurel32
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2762 49563a72 Richard Henderson
        }
2763 4af70374 Richard Henderson
        ret = EXIT_PC_UPDATED;
2764 4c9649a9 j_mayer
        break;
2765 4c9649a9 j_mayer
    case 0x1B:
2766 4c9649a9 j_mayer
        /* HW_LD (PALcode) */
2767 a18ad893 Richard Henderson
#ifndef CONFIG_USER_ONLY
2768 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2769 a18ad893 Richard Henderson
            TCGv addr;
2770 a18ad893 Richard Henderson
2771 a18ad893 Richard Henderson
            if (ra == 31) {
2772 a18ad893 Richard Henderson
                break;
2773 a18ad893 Richard Henderson
            }
2774 a18ad893 Richard Henderson
2775 a18ad893 Richard Henderson
            addr = tcg_temp_new();
2776 8bb6e981 aurel32
            if (rb != 31)
2777 8bb6e981 aurel32
                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2778 8bb6e981 aurel32
            else
2779 8bb6e981 aurel32
                tcg_gen_movi_i64(addr, disp12);
2780 8bb6e981 aurel32
            switch ((insn >> 12) & 0xF) {
2781 8bb6e981 aurel32
            case 0x0:
2782 b5d51029 aurel32
                /* Longword physical access (hw_ldl/p) */
2783 2374e73e Richard Henderson
                gen_helper_ldl_phys(cpu_ir[ra], addr);
2784 8bb6e981 aurel32
                break;
2785 8bb6e981 aurel32
            case 0x1:
2786 b5d51029 aurel32
                /* Quadword physical access (hw_ldq/p) */
2787 2374e73e Richard Henderson
                gen_helper_ldq_phys(cpu_ir[ra], addr);
2788 8bb6e981 aurel32
                break;
2789 8bb6e981 aurel32
            case 0x2:
2790 b5d51029 aurel32
                /* Longword physical access with lock (hw_ldl_l/p) */
2791 2374e73e Richard Henderson
                gen_helper_ldl_l_phys(cpu_ir[ra], addr);
2792 8bb6e981 aurel32
                break;
2793 8bb6e981 aurel32
            case 0x3:
2794 b5d51029 aurel32
                /* Quadword physical access with lock (hw_ldq_l/p) */
2795 2374e73e Richard Henderson
                gen_helper_ldq_l_phys(cpu_ir[ra], addr);
2796 8bb6e981 aurel32
                break;
2797 8bb6e981 aurel32
            case 0x4:
2798 b5d51029 aurel32
                /* Longword virtual PTE fetch (hw_ldl/v) */
2799 2374e73e Richard Henderson
                goto invalid_opc;
2800 8bb6e981 aurel32
            case 0x5:
2801 b5d51029 aurel32
                /* Quadword virtual PTE fetch (hw_ldq/v) */
2802 2374e73e Richard Henderson
                goto invalid_opc;
2803 8bb6e981 aurel32
                break;
2804 8bb6e981 aurel32
            case 0x6:
2805 8bb6e981 aurel32
                /* Incpu_ir[ra]id */
2806 b5d51029 aurel32
                goto invalid_opc;
2807 8bb6e981 aurel32
            case 0x7:
2808 8bb6e981 aurel32
                /* Incpu_ir[ra]id */
2809 b5d51029 aurel32
                goto invalid_opc;
2810 8bb6e981 aurel32
            case 0x8:
2811 b5d51029 aurel32
                /* Longword virtual access (hw_ldl) */
2812 2374e73e Richard Henderson
                goto invalid_opc;
2813 8bb6e981 aurel32
            case 0x9:
2814 b5d51029 aurel32
                /* Quadword virtual access (hw_ldq) */
2815 2374e73e Richard Henderson
                goto invalid_opc;
2816 8bb6e981 aurel32
            case 0xA:
2817 b5d51029 aurel32
                /* Longword virtual access with protection check (hw_ldl/w) */
2818 8417845e Richard Henderson
                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_KERNEL_IDX);
2819 8bb6e981 aurel32
                break;
2820 8bb6e981 aurel32
            case 0xB:
2821 b5d51029 aurel32
                /* Quadword virtual access with protection check (hw_ldq/w) */
2822 8417845e Richard Henderson
                tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_KERNEL_IDX);
2823 8bb6e981 aurel32
                break;
2824 8bb6e981 aurel32
            case 0xC:
2825 b5d51029 aurel32
                /* Longword virtual access with alt access mode (hw_ldl/a)*/
2826 2374e73e Richard Henderson
                goto invalid_opc;
2827 8bb6e981 aurel32
            case 0xD:
2828 b5d51029 aurel32
                /* Quadword virtual access with alt access mode (hw_ldq/a) */
2829 2374e73e Richard Henderson
                goto invalid_opc;
2830 8bb6e981 aurel32
            case 0xE:
2831 8bb6e981 aurel32
                /* Longword virtual access with alternate access mode and
2832 2374e73e Richard Henderson
                   protection checks (hw_ldl/wa) */
2833 2374e73e Richard Henderson
                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_USER_IDX);
2834 8bb6e981 aurel32
                break;
2835 8bb6e981 aurel32
            case 0xF:
2836 8bb6e981 aurel32
                /* Quadword virtual access with alternate access mode and
2837 2374e73e Richard Henderson
                   protection checks (hw_ldq/wa) */
2838 2374e73e Richard Henderson
                tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_USER_IDX);
2839 8bb6e981 aurel32
                break;
2840 8bb6e981 aurel32
            }
2841 8bb6e981 aurel32
            tcg_temp_free(addr);
2842 a18ad893 Richard Henderson
            break;
2843 4c9649a9 j_mayer
        }
2844 4c9649a9 j_mayer
#endif
2845 a18ad893 Richard Henderson
        goto invalid_opc;
2846 4c9649a9 j_mayer
    case 0x1C:
2847 4c9649a9 j_mayer
        switch (fn7) {
2848 4c9649a9 j_mayer
        case 0x00:
2849 4c9649a9 j_mayer
            /* SEXTB */
2850 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) {
2851 4c9649a9 j_mayer
                goto invalid_opc;
2852 a18ad893 Richard Henderson
            }
2853 ae8ecd42 aurel32
            if (likely(rc != 31)) {
2854 ae8ecd42 aurel32
                if (islit)
2855 ae8ecd42 aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
2856 ae8ecd42 aurel32
                else
2857 dfaa8583 aurel32
                    tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
2858 ae8ecd42 aurel32
            }
2859 4c9649a9 j_mayer
            break;
2860 4c9649a9 j_mayer
        case 0x01:
2861 4c9649a9 j_mayer
            /* SEXTW */
2862 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
2863 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2864 a18ad893 Richard Henderson
                    if (islit) {
2865 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
2866 a18ad893 Richard Henderson
                    } else {
2867 a18ad893 Richard Henderson
                        tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
2868 a18ad893 Richard Henderson
                    }
2869 a18ad893 Richard Henderson
                }
2870 a18ad893 Richard Henderson
                break;
2871 ae8ecd42 aurel32
            }
2872 a18ad893 Richard Henderson
            goto invalid_opc;
2873 4c9649a9 j_mayer
        case 0x30:
2874 4c9649a9 j_mayer
            /* CTPOP */
2875 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2876 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2877 a18ad893 Richard Henderson
                    if (islit) {
2878 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
2879 a18ad893 Richard Henderson
                    } else {
2880 a18ad893 Richard Henderson
                        gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
2881 a18ad893 Richard Henderson
                    }
2882 a18ad893 Richard Henderson
                }
2883 a18ad893 Richard Henderson
                break;
2884 ae8ecd42 aurel32
            }
2885 a18ad893 Richard Henderson
            goto invalid_opc;
2886 4c9649a9 j_mayer
        case 0x31:
2887 4c9649a9 j_mayer
            /* PERR */
2888 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2889 a18ad893 Richard Henderson
                gen_perr(ra, rb, rc, islit, lit);
2890 a18ad893 Richard Henderson
                break;
2891 a18ad893 Richard Henderson
            }
2892 a18ad893 Richard Henderson
            goto invalid_opc;
2893 4c9649a9 j_mayer
        case 0x32:
2894 4c9649a9 j_mayer
            /* CTLZ */
2895 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2896 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2897 a18ad893 Richard Henderson
                    if (islit) {
2898 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
2899 a18ad893 Richard Henderson
                    } else {
2900 a18ad893 Richard Henderson
                        gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
2901 a18ad893 Richard Henderson
                    }
2902 a18ad893 Richard Henderson
                }
2903 a18ad893 Richard Henderson
                break;
2904 ae8ecd42 aurel32
            }
2905 a18ad893 Richard Henderson
            goto invalid_opc;
2906 4c9649a9 j_mayer
        case 0x33:
2907 4c9649a9 j_mayer
            /* CTTZ */
2908 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2909 a18ad893 Richard Henderson
                if (likely(rc != 31)) {
2910 a18ad893 Richard Henderson
                    if (islit) {
2911 a18ad893 Richard Henderson
                        tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
2912 a18ad893 Richard Henderson
                    } else {
2913 a18ad893 Richard Henderson
                        gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
2914 a18ad893 Richard Henderson
                    }
2915 a18ad893 Richard Henderson
                }
2916 a18ad893 Richard Henderson
                break;
2917 ae8ecd42 aurel32
            }
2918 a18ad893 Richard Henderson
            goto invalid_opc;
2919 4c9649a9 j_mayer
        case 0x34:
2920 4c9649a9 j_mayer
            /* UNPKBW */
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_unpkbw(rb, rc);
2926 a18ad893 Richard Henderson
                break;
2927 a18ad893 Richard Henderson
            }
2928 a18ad893 Richard Henderson
            goto invalid_opc;
2929 4c9649a9 j_mayer
        case 0x35:
2930 13e4df99 Richard Henderson
            /* UNPKBL */
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_unpkbl(rb, rc);
2936 a18ad893 Richard Henderson
                break;
2937 a18ad893 Richard Henderson
            }
2938 a18ad893 Richard Henderson
            goto invalid_opc;
2939 4c9649a9 j_mayer
        case 0x36:
2940 4c9649a9 j_mayer
            /* PKWB */
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_pkwb(rb, rc);
2946 a18ad893 Richard Henderson
                break;
2947 a18ad893 Richard Henderson
            }
2948 a18ad893 Richard Henderson
            goto invalid_opc;
2949 4c9649a9 j_mayer
        case 0x37:
2950 4c9649a9 j_mayer
            /* PKLB */
2951 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2952 a18ad893 Richard Henderson
                if (real_islit || ra != 31) {
2953 a18ad893 Richard Henderson
                    goto invalid_opc;
2954 a18ad893 Richard Henderson
                }
2955 a18ad893 Richard Henderson
                gen_pklb(rb, rc);
2956 a18ad893 Richard Henderson
                break;
2957 a18ad893 Richard Henderson
            }
2958 a18ad893 Richard Henderson
            goto invalid_opc;
2959 4c9649a9 j_mayer
        case 0x38:
2960 4c9649a9 j_mayer
            /* MINSB8 */
2961 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2962 a18ad893 Richard Henderson
                gen_minsb8(ra, rb, rc, islit, lit);
2963 a18ad893 Richard Henderson
                break;
2964 a18ad893 Richard Henderson
            }
2965 a18ad893 Richard Henderson
            goto invalid_opc;
2966 4c9649a9 j_mayer
        case 0x39:
2967 4c9649a9 j_mayer
            /* MINSW4 */
2968 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2969 a18ad893 Richard Henderson
                gen_minsw4(ra, rb, rc, islit, lit);
2970 a18ad893 Richard Henderson
                break;
2971 a18ad893 Richard Henderson
            }
2972 a18ad893 Richard Henderson
            goto invalid_opc;
2973 4c9649a9 j_mayer
        case 0x3A:
2974 4c9649a9 j_mayer
            /* MINUB8 */
2975 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2976 a18ad893 Richard Henderson
                gen_minub8(ra, rb, rc, islit, lit);
2977 a18ad893 Richard Henderson
                break;
2978 a18ad893 Richard Henderson
            }
2979 a18ad893 Richard Henderson
            goto invalid_opc;
2980 4c9649a9 j_mayer
        case 0x3B:
2981 4c9649a9 j_mayer
            /* MINUW4 */
2982 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2983 a18ad893 Richard Henderson
                gen_minuw4(ra, rb, rc, islit, lit);
2984 a18ad893 Richard Henderson
                break;
2985 a18ad893 Richard Henderson
            }
2986 a18ad893 Richard Henderson
            goto invalid_opc;
2987 4c9649a9 j_mayer
        case 0x3C:
2988 4c9649a9 j_mayer
            /* MAXUB8 */
2989 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2990 a18ad893 Richard Henderson
                gen_maxub8(ra, rb, rc, islit, lit);
2991 a18ad893 Richard Henderson
                break;
2992 a18ad893 Richard Henderson
            }
2993 a18ad893 Richard Henderson
            goto invalid_opc;
2994 4c9649a9 j_mayer
        case 0x3D:
2995 4c9649a9 j_mayer
            /* MAXUW4 */
2996 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2997 a18ad893 Richard Henderson
                gen_maxuw4(ra, rb, rc, islit, lit);
2998 a18ad893 Richard Henderson
                break;
2999 a18ad893 Richard Henderson
            }
3000 a18ad893 Richard Henderson
            goto invalid_opc;
3001 4c9649a9 j_mayer
        case 0x3E:
3002 4c9649a9 j_mayer
            /* MAXSB8 */
3003 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3004 a18ad893 Richard Henderson
                gen_maxsb8(ra, rb, rc, islit, lit);
3005 a18ad893 Richard Henderson
                break;
3006 a18ad893 Richard Henderson
            }
3007 a18ad893 Richard Henderson
            goto invalid_opc;
3008 4c9649a9 j_mayer
        case 0x3F:
3009 4c9649a9 j_mayer
            /* MAXSW4 */
3010 a18ad893 Richard Henderson
            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3011 a18ad893 Richard Henderson
                gen_maxsw4(ra, rb, rc, islit, lit);
3012 a18ad893 Richard Henderson
                break;
3013 a18ad893 Richard Henderson
            }
3014 a18ad893 Richard Henderson
            goto invalid_opc;
3015 4c9649a9 j_mayer
        case 0x70:
3016 4c9649a9 j_mayer
            /* FTOIT */
3017 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3018 4c9649a9 j_mayer
                goto invalid_opc;
3019 a18ad893 Richard Henderson
            }
3020 f18cd223 aurel32
            if (likely(rc != 31)) {
3021 f18cd223 aurel32
                if (ra != 31)
3022 f18cd223 aurel32
                    tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
3023 f18cd223 aurel32
                else
3024 f18cd223 aurel32
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
3025 f18cd223 aurel32
            }
3026 4c9649a9 j_mayer
            break;
3027 4c9649a9 j_mayer
        case 0x78:
3028 4c9649a9 j_mayer
            /* FTOIS */
3029 a18ad893 Richard Henderson
            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3030 4c9649a9 j_mayer
                goto invalid_opc;
3031 a18ad893 Richard Henderson
            }
3032 f18cd223 aurel32
            if (rc != 31) {
3033 a7812ae4 pbrook
                TCGv_i32 tmp1 = tcg_temp_new_i32();
3034 f18cd223 aurel32
                if (ra != 31)
3035 a7812ae4 pbrook
                    gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
3036 f18cd223 aurel32
                else {
3037 f18cd223 aurel32
                    TCGv tmp2 = tcg_const_i64(0);
3038 a7812ae4 pbrook
                    gen_helper_s_to_memory(tmp1, tmp2);
3039 f18cd223 aurel32
                    tcg_temp_free(tmp2);
3040 f18cd223 aurel32
                }
3041 f18cd223 aurel32
                tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
3042 a7812ae4 pbrook
                tcg_temp_free_i32(tmp1);
3043 f18cd223 aurel32
            }
3044 4c9649a9 j_mayer
            break;
3045 4c9649a9 j_mayer
        default:
3046 4c9649a9 j_mayer
            goto invalid_opc;
3047 4c9649a9 j_mayer
        }
3048 4c9649a9 j_mayer
        break;
3049 4c9649a9 j_mayer
    case 0x1D:
3050 4c9649a9 j_mayer
        /* HW_MTPR (PALcode) */
3051 26b46094 Richard Henderson
#ifndef CONFIG_USER_ONLY
3052 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3053 a18ad893 Richard Henderson
            gen_mtpr(rb, insn & 0xffff);
3054 26b46094 Richard Henderson
            break;
3055 26b46094 Richard Henderson
        }
3056 26b46094 Richard Henderson
#endif
3057 4c9649a9 j_mayer
        goto invalid_opc;
3058 4c9649a9 j_mayer
    case 0x1E:
3059 508b43ea Richard Henderson
        /* HW_RET (PALcode) */
3060 a18ad893 Richard Henderson
#ifndef CONFIG_USER_ONLY
3061 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3062 a18ad893 Richard Henderson
            if (rb == 31) {
3063 a18ad893 Richard Henderson
                /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
3064 a18ad893 Richard Henderson
                   address from EXC_ADDR.  This turns out to be useful for our
3065 a18ad893 Richard Henderson
                   emulation PALcode, so continue to accept it.  */
3066 a18ad893 Richard Henderson
                TCGv tmp = tcg_temp_new();
3067 a18ad893 Richard Henderson
                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, exc_addr));
3068 a18ad893 Richard Henderson
                gen_helper_hw_ret(tmp);
3069 a18ad893 Richard Henderson
                tcg_temp_free(tmp);
3070 a18ad893 Richard Henderson
            } else {
3071 a18ad893 Richard Henderson
                gen_helper_hw_ret(cpu_ir[rb]);
3072 a18ad893 Richard Henderson
            }
3073 a18ad893 Richard Henderson
            ret = EXIT_PC_UPDATED;
3074 a18ad893 Richard Henderson
            break;
3075 4c9649a9 j_mayer
        }
3076 4c9649a9 j_mayer
#endif
3077 a18ad893 Richard Henderson
        goto invalid_opc;
3078 4c9649a9 j_mayer
    case 0x1F:
3079 4c9649a9 j_mayer
        /* HW_ST (PALcode) */
3080 a18ad893 Richard Henderson
#ifndef CONFIG_USER_ONLY
3081 a18ad893 Richard Henderson
        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3082 8bb6e981 aurel32
            TCGv addr, val;
3083 a7812ae4 pbrook
            addr = tcg_temp_new();
3084 8bb6e981 aurel32
            if (rb != 31)
3085 8bb6e981 aurel32
                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
3086 8bb6e981 aurel32
            else
3087 8bb6e981 aurel32
                tcg_gen_movi_i64(addr, disp12);
3088 8bb6e981 aurel32
            if (ra != 31)
3089 8bb6e981 aurel32
                val = cpu_ir[ra];
3090 8bb6e981 aurel32
            else {
3091 a7812ae4 pbrook
                val = tcg_temp_new();
3092 8bb6e981 aurel32
                tcg_gen_movi_i64(val, 0);
3093 8bb6e981 aurel32
            }
3094 8bb6e981 aurel32
            switch ((insn >> 12) & 0xF) {
3095 8bb6e981 aurel32
            case 0x0:
3096 8bb6e981 aurel32
                /* Longword physical access */
3097 2374e73e Richard Henderson
                gen_helper_stl_phys(addr, val);
3098 8bb6e981 aurel32
                break;
3099 8bb6e981 aurel32
            case 0x1:
3100 8bb6e981 aurel32
                /* Quadword physical access */
3101 2374e73e Richard Henderson
                gen_helper_stq_phys(addr, val);
3102 8bb6e981 aurel32
                break;
3103 8bb6e981 aurel32
            case 0x2:
3104 8bb6e981 aurel32
                /* Longword physical access with lock */
3105 2374e73e Richard Henderson
                gen_helper_stl_c_phys(val, addr, val);
3106 8bb6e981 aurel32
                break;
3107 8bb6e981 aurel32
            case 0x3:
3108 8bb6e981 aurel32
                /* Quadword physical access with lock */
3109 2374e73e Richard Henderson
                gen_helper_stq_c_phys(val, addr, val);
3110 8bb6e981 aurel32
                break;
3111 8bb6e981 aurel32
            case 0x4:
3112 8bb6e981 aurel32
                /* Longword virtual access */
3113 2374e73e Richard Henderson
                goto invalid_opc;
3114 8bb6e981 aurel32
            case 0x5:
3115 8bb6e981 aurel32
                /* Quadword virtual access */
3116 2374e73e Richard Henderson
                goto invalid_opc;
3117 8bb6e981 aurel32
            case 0x6:
3118 8bb6e981 aurel32
                /* Invalid */
3119 8bb6e981 aurel32
                goto invalid_opc;
3120 8bb6e981 aurel32
            case 0x7:
3121 8bb6e981 aurel32
                /* Invalid */
3122 8bb6e981 aurel32
                goto invalid_opc;
3123 8bb6e981 aurel32
            case 0x8:
3124 8bb6e981 aurel32
                /* Invalid */
3125 8bb6e981 aurel32
                goto invalid_opc;
3126 8bb6e981 aurel32
            case 0x9:
3127 8bb6e981 aurel32
                /* Invalid */
3128 8bb6e981 aurel32
                goto invalid_opc;
3129 8bb6e981 aurel32
            case 0xA:
3130 8bb6e981 aurel32
                /* Invalid */
3131 8bb6e981 aurel32
                goto invalid_opc;
3132 8bb6e981 aurel32
            case 0xB:
3133 8bb6e981 aurel32
                /* Invalid */
3134 8bb6e981 aurel32
                goto invalid_opc;
3135 8bb6e981 aurel32
            case 0xC:
3136 8bb6e981 aurel32
                /* Longword virtual access with alternate access mode */
3137 2374e73e Richard Henderson
                goto invalid_opc;
3138 8bb6e981 aurel32
            case 0xD:
3139 8bb6e981 aurel32
                /* Quadword virtual access with alternate access mode */
3140 2374e73e Richard Henderson
                goto invalid_opc;
3141 8bb6e981 aurel32
            case 0xE:
3142 8bb6e981 aurel32
                /* Invalid */
3143 8bb6e981 aurel32
                goto invalid_opc;
3144 8bb6e981 aurel32
            case 0xF:
3145 8bb6e981 aurel32
                /* Invalid */
3146 8bb6e981 aurel32
                goto invalid_opc;
3147 8bb6e981 aurel32
            }
3148 45d46ce8 aurel32
            if (ra == 31)
3149 8bb6e981 aurel32
                tcg_temp_free(val);
3150 8bb6e981 aurel32
            tcg_temp_free(addr);
3151 a18ad893 Richard Henderson
            break;
3152 4c9649a9 j_mayer
        }
3153 4c9649a9 j_mayer
#endif
3154 a18ad893 Richard Henderson
        goto invalid_opc;
3155 4c9649a9 j_mayer
    case 0x20:
3156 4c9649a9 j_mayer
        /* LDF */
3157 f18cd223 aurel32
        gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
3158 4c9649a9 j_mayer
        break;
3159 4c9649a9 j_mayer
    case 0x21:
3160 4c9649a9 j_mayer
        /* LDG */
3161 f18cd223 aurel32
        gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
3162 4c9649a9 j_mayer
        break;
3163 4c9649a9 j_mayer
    case 0x22:
3164 4c9649a9 j_mayer
        /* LDS */
3165 f18cd223 aurel32
        gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
3166 4c9649a9 j_mayer
        break;
3167 4c9649a9 j_mayer
    case 0x23:
3168 4c9649a9 j_mayer
        /* LDT */
3169 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
3170 4c9649a9 j_mayer
        break;
3171 4c9649a9 j_mayer
    case 0x24:
3172 4c9649a9 j_mayer
        /* STF */
3173 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
3174 4c9649a9 j_mayer
        break;
3175 4c9649a9 j_mayer
    case 0x25:
3176 4c9649a9 j_mayer
        /* STG */
3177 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
3178 4c9649a9 j_mayer
        break;
3179 4c9649a9 j_mayer
    case 0x26:
3180 4c9649a9 j_mayer
        /* STS */
3181 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
3182 4c9649a9 j_mayer
        break;
3183 4c9649a9 j_mayer
    case 0x27:
3184 4c9649a9 j_mayer
        /* STT */
3185 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
3186 4c9649a9 j_mayer
        break;
3187 4c9649a9 j_mayer
    case 0x28:
3188 4c9649a9 j_mayer
        /* LDL */
3189 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
3190 4c9649a9 j_mayer
        break;
3191 4c9649a9 j_mayer
    case 0x29:
3192 4c9649a9 j_mayer
        /* LDQ */
3193 f18cd223 aurel32
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
3194 4c9649a9 j_mayer
        break;
3195 4c9649a9 j_mayer
    case 0x2A:
3196 4c9649a9 j_mayer
        /* LDL_L */
3197 f4ed8679 aurel32
        gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
3198 4c9649a9 j_mayer
        break;
3199 4c9649a9 j_mayer
    case 0x2B:
3200 4c9649a9 j_mayer
        /* LDQ_L */
3201 f4ed8679 aurel32
        gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
3202 4c9649a9 j_mayer
        break;
3203 4c9649a9 j_mayer
    case 0x2C:
3204 4c9649a9 j_mayer
        /* STL */
3205 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
3206 4c9649a9 j_mayer
        break;
3207 4c9649a9 j_mayer
    case 0x2D:
3208 4c9649a9 j_mayer
        /* STQ */
3209 6910b8f6 Richard Henderson
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
3210 4c9649a9 j_mayer
        break;
3211 4c9649a9 j_mayer
    case 0x2E:
3212 4c9649a9 j_mayer
        /* STL_C */
3213 6910b8f6 Richard Henderson
        ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
3214 4c9649a9 j_mayer
        break;
3215 4c9649a9 j_mayer
    case 0x2F:
3216 4c9649a9 j_mayer
        /* STQ_C */
3217 6910b8f6 Richard Henderson
        ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
3218 4c9649a9 j_mayer
        break;
3219 4c9649a9 j_mayer
    case 0x30:
3220 4c9649a9 j_mayer
        /* BR */
3221 4af70374 Richard Henderson
        ret = gen_bdirect(ctx, ra, disp21);
3222 4c9649a9 j_mayer
        break;
3223 a7812ae4 pbrook
    case 0x31: /* FBEQ */
3224 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
3225 dbb30fe6 Richard Henderson
        break;
3226 a7812ae4 pbrook
    case 0x32: /* FBLT */
3227 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
3228 dbb30fe6 Richard Henderson
        break;
3229 a7812ae4 pbrook
    case 0x33: /* FBLE */
3230 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
3231 4c9649a9 j_mayer
        break;
3232 4c9649a9 j_mayer
    case 0x34:
3233 4c9649a9 j_mayer
        /* BSR */
3234 4af70374 Richard Henderson
        ret = gen_bdirect(ctx, ra, disp21);
3235 4c9649a9 j_mayer
        break;
3236 a7812ae4 pbrook
    case 0x35: /* FBNE */
3237 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
3238 dbb30fe6 Richard Henderson
        break;
3239 a7812ae4 pbrook
    case 0x36: /* FBGE */
3240 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
3241 dbb30fe6 Richard Henderson
        break;
3242 a7812ae4 pbrook
    case 0x37: /* FBGT */
3243 4af70374 Richard Henderson
        ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
3244 4c9649a9 j_mayer
        break;
3245 4c9649a9 j_mayer
    case 0x38:
3246 4c9649a9 j_mayer
        /* BLBC */
3247 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
3248 4c9649a9 j_mayer
        break;
3249 4c9649a9 j_mayer
    case 0x39:
3250 4c9649a9 j_mayer
        /* BEQ */
3251 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
3252 4c9649a9 j_mayer
        break;
3253 4c9649a9 j_mayer
    case 0x3A:
3254 4c9649a9 j_mayer
        /* BLT */
3255 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
3256 4c9649a9 j_mayer
        break;
3257 4c9649a9 j_mayer
    case 0x3B:
3258 4c9649a9 j_mayer
        /* BLE */
3259 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
3260 4c9649a9 j_mayer
        break;
3261 4c9649a9 j_mayer
    case 0x3C:
3262 4c9649a9 j_mayer
        /* BLBS */
3263 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
3264 4c9649a9 j_mayer
        break;
3265 4c9649a9 j_mayer
    case 0x3D:
3266 4c9649a9 j_mayer
        /* BNE */
3267 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
3268 4c9649a9 j_mayer
        break;
3269 4c9649a9 j_mayer
    case 0x3E:
3270 4c9649a9 j_mayer
        /* BGE */
3271 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
3272 4c9649a9 j_mayer
        break;
3273 4c9649a9 j_mayer
    case 0x3F:
3274 4c9649a9 j_mayer
        /* BGT */
3275 4af70374 Richard Henderson
        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
3276 4c9649a9 j_mayer
        break;
3277 4c9649a9 j_mayer
    invalid_opc:
3278 8aa3fa20 Richard Henderson
        ret = gen_invalid(ctx);
3279 4c9649a9 j_mayer
        break;
3280 4c9649a9 j_mayer
    }
3281 4c9649a9 j_mayer
3282 4c9649a9 j_mayer
    return ret;
3283 4c9649a9 j_mayer
}
3284 4c9649a9 j_mayer
3285 636aa200 Blue Swirl
static inline void gen_intermediate_code_internal(CPUState *env,
3286 636aa200 Blue Swirl
                                                  TranslationBlock *tb,
3287 636aa200 Blue Swirl
                                                  int search_pc)
3288 4c9649a9 j_mayer
{
3289 4c9649a9 j_mayer
    DisasContext ctx, *ctxp = &ctx;
3290 4c9649a9 j_mayer
    target_ulong pc_start;
3291 4c9649a9 j_mayer
    uint32_t insn;
3292 4c9649a9 j_mayer
    uint16_t *gen_opc_end;
3293 a1d1bb31 aliguori
    CPUBreakpoint *bp;
3294 4c9649a9 j_mayer
    int j, lj = -1;
3295 4af70374 Richard Henderson
    ExitStatus ret;
3296 2e70f6ef pbrook
    int num_insns;
3297 2e70f6ef pbrook
    int max_insns;
3298 4c9649a9 j_mayer
3299 4c9649a9 j_mayer
    pc_start = tb->pc;
3300 4c9649a9 j_mayer
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3301 4af70374 Richard Henderson
3302 4af70374 Richard Henderson
    ctx.tb = tb;
3303 4af70374 Richard Henderson
    ctx.env = env;
3304 4c9649a9 j_mayer
    ctx.pc = pc_start;
3305 bba9bdce Richard Henderson
    ctx.mem_idx = cpu_mmu_index(env);
3306 f24518b5 Richard Henderson
3307 f24518b5 Richard Henderson
    /* ??? Every TB begins with unset rounding mode, to be initialized on
3308 f24518b5 Richard Henderson
       the first fp insn of the TB.  Alternately we could define a proper
3309 f24518b5 Richard Henderson
       default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
3310 f24518b5 Richard Henderson
       to reset the FP_STATUS to that default at the end of any TB that
3311 f24518b5 Richard Henderson
       changes the default.  We could even (gasp) dynamiclly figure out
3312 f24518b5 Richard Henderson
       what default would be most efficient given the running program.  */
3313 f24518b5 Richard Henderson
    ctx.tb_rm = -1;
3314 f24518b5 Richard Henderson
    /* Similarly for flush-to-zero.  */
3315 f24518b5 Richard Henderson
    ctx.tb_ftz = -1;
3316 f24518b5 Richard Henderson
3317 2e70f6ef pbrook
    num_insns = 0;
3318 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
3319 2e70f6ef pbrook
    if (max_insns == 0)
3320 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
3321 2e70f6ef pbrook
3322 2e70f6ef pbrook
    gen_icount_start();
3323 4af70374 Richard Henderson
    do {
3324 72cf2d4f Blue Swirl
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3325 72cf2d4f Blue Swirl
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3326 a1d1bb31 aliguori
                if (bp->pc == ctx.pc) {
3327 4c9649a9 j_mayer
                    gen_excp(&ctx, EXCP_DEBUG, 0);
3328 4c9649a9 j_mayer
                    break;
3329 4c9649a9 j_mayer
                }
3330 4c9649a9 j_mayer
            }
3331 4c9649a9 j_mayer
        }
3332 4c9649a9 j_mayer
        if (search_pc) {
3333 4c9649a9 j_mayer
            j = gen_opc_ptr - gen_opc_buf;
3334 4c9649a9 j_mayer
            if (lj < j) {
3335 4c9649a9 j_mayer
                lj++;
3336 4c9649a9 j_mayer
                while (lj < j)
3337 4c9649a9 j_mayer
                    gen_opc_instr_start[lj++] = 0;
3338 4c9649a9 j_mayer
            }
3339 ed1dda53 aurel32
            gen_opc_pc[lj] = ctx.pc;
3340 ed1dda53 aurel32
            gen_opc_instr_start[lj] = 1;
3341 ed1dda53 aurel32
            gen_opc_icount[lj] = num_insns;
3342 4c9649a9 j_mayer
        }
3343 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3344 2e70f6ef pbrook
            gen_io_start();
3345 4c9649a9 j_mayer
        insn = ldl_code(ctx.pc);
3346 2e70f6ef pbrook
        num_insns++;
3347 c4b3be39 Richard Henderson
3348 c4b3be39 Richard Henderson
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
3349 c4b3be39 Richard Henderson
            tcg_gen_debug_insn_start(ctx.pc);
3350 c4b3be39 Richard Henderson
        }
3351 c4b3be39 Richard Henderson
3352 4c9649a9 j_mayer
        ctx.pc += 4;
3353 4c9649a9 j_mayer
        ret = translate_one(ctxp, insn);
3354 19bf517b aurel32
3355 bf1b03fe Richard Henderson
        /* If we reach a page boundary, are single stepping,
3356 bf1b03fe Richard Henderson
           or exhaust instruction count, stop generation.  */
3357 bf1b03fe Richard Henderson
        if (ret == NO_EXIT
3358 bf1b03fe Richard Henderson
            && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
3359 bf1b03fe Richard Henderson
                || gen_opc_ptr >= gen_opc_end
3360 bf1b03fe Richard Henderson
                || num_insns >= max_insns
3361 bf1b03fe Richard Henderson
                || singlestep
3362 bf1b03fe Richard Henderson
                || env->singlestep_enabled)) {
3363 bf1b03fe Richard Henderson
            ret = EXIT_PC_STALE;
3364 1b530a6d aurel32
        }
3365 4af70374 Richard Henderson
    } while (ret == NO_EXIT);
3366 4af70374 Richard Henderson
3367 4af70374 Richard Henderson
    if (tb->cflags & CF_LAST_IO) {
3368 4af70374 Richard Henderson
        gen_io_end();
3369 4c9649a9 j_mayer
    }
3370 4af70374 Richard Henderson
3371 4af70374 Richard Henderson
    switch (ret) {
3372 4af70374 Richard Henderson
    case EXIT_GOTO_TB:
3373 8aa3fa20 Richard Henderson
    case EXIT_NORETURN:
3374 4af70374 Richard Henderson
        break;
3375 4af70374 Richard Henderson
    case EXIT_PC_STALE:
3376 496cb5b9 aurel32
        tcg_gen_movi_i64(cpu_pc, ctx.pc);
3377 4af70374 Richard Henderson
        /* FALLTHRU */
3378 4af70374 Richard Henderson
    case EXIT_PC_UPDATED:
3379 bf1b03fe Richard Henderson
        if (env->singlestep_enabled) {
3380 bf1b03fe Richard Henderson
            gen_excp_1(EXCP_DEBUG, 0);
3381 bf1b03fe Richard Henderson
        } else {
3382 bf1b03fe Richard Henderson
            tcg_gen_exit_tb(0);
3383 bf1b03fe Richard Henderson
        }
3384 4af70374 Richard Henderson
        break;
3385 4af70374 Richard Henderson
    default:
3386 4af70374 Richard Henderson
        abort();
3387 4c9649a9 j_mayer
    }
3388 4af70374 Richard Henderson
3389 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
3390 4c9649a9 j_mayer
    *gen_opc_ptr = INDEX_op_end;
3391 4c9649a9 j_mayer
    if (search_pc) {
3392 4c9649a9 j_mayer
        j = gen_opc_ptr - gen_opc_buf;
3393 4c9649a9 j_mayer
        lj++;
3394 4c9649a9 j_mayer
        while (lj <= j)
3395 4c9649a9 j_mayer
            gen_opc_instr_start[lj++] = 0;
3396 4c9649a9 j_mayer
    } else {
3397 4c9649a9 j_mayer
        tb->size = ctx.pc - pc_start;
3398 2e70f6ef pbrook
        tb->icount = num_insns;
3399 4c9649a9 j_mayer
    }
3400 4af70374 Richard Henderson
3401 806991da Richard Henderson
#ifdef DEBUG_DISAS
3402 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3403 93fcfe39 aliguori
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
3404 93fcfe39 aliguori
        log_target_disas(pc_start, ctx.pc - pc_start, 1);
3405 93fcfe39 aliguori
        qemu_log("\n");
3406 4c9649a9 j_mayer
    }
3407 4c9649a9 j_mayer
#endif
3408 4c9649a9 j_mayer
}
3409 4c9649a9 j_mayer
3410 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3411 4c9649a9 j_mayer
{
3412 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
3413 4c9649a9 j_mayer
}
3414 4c9649a9 j_mayer
3415 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3416 4c9649a9 j_mayer
{
3417 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
3418 4c9649a9 j_mayer
}
3419 4c9649a9 j_mayer
3420 a964acc6 Richard Henderson
struct cpu_def_t {
3421 a964acc6 Richard Henderson
    const char *name;
3422 a964acc6 Richard Henderson
    int implver, amask;
3423 a964acc6 Richard Henderson
};
3424 a964acc6 Richard Henderson
3425 a964acc6 Richard Henderson
static const struct cpu_def_t cpu_defs[] = {
3426 a964acc6 Richard Henderson
    { "ev4",   IMPLVER_2106x, 0 },
3427 a964acc6 Richard Henderson
    { "ev5",   IMPLVER_21164, 0 },
3428 a964acc6 Richard Henderson
    { "ev56",  IMPLVER_21164, AMASK_BWX },
3429 a964acc6 Richard Henderson
    { "pca56", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
3430 a964acc6 Richard Henderson
    { "ev6",   IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
3431 a964acc6 Richard Henderson
    { "ev67",  IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
3432 a964acc6 Richard Henderson
                               | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
3433 a964acc6 Richard Henderson
    { "ev68",  IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
3434 a964acc6 Richard Henderson
                               | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
3435 a964acc6 Richard Henderson
    { "21064", IMPLVER_2106x, 0 },
3436 a964acc6 Richard Henderson
    { "21164", IMPLVER_21164, 0 },
3437 a964acc6 Richard Henderson
    { "21164a", IMPLVER_21164, AMASK_BWX },
3438 a964acc6 Richard Henderson
    { "21164pc", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
3439 a964acc6 Richard Henderson
    { "21264", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
3440 a964acc6 Richard Henderson
    { "21264a", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
3441 a964acc6 Richard Henderson
                                | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), }
3442 a964acc6 Richard Henderson
};
3443 a964acc6 Richard Henderson
3444 aaed909a bellard
CPUAlphaState * cpu_alpha_init (const char *cpu_model)
3445 4c9649a9 j_mayer
{
3446 4c9649a9 j_mayer
    CPUAlphaState *env;
3447 a964acc6 Richard Henderson
    int implver, amask, i, max;
3448 4c9649a9 j_mayer
3449 4c9649a9 j_mayer
    env = qemu_mallocz(sizeof(CPUAlphaState));
3450 4c9649a9 j_mayer
    cpu_exec_init(env);
3451 2e70f6ef pbrook
    alpha_translate_init();
3452 4c9649a9 j_mayer
    tlb_flush(env, 1);
3453 a964acc6 Richard Henderson
3454 a964acc6 Richard Henderson
    /* Default to ev67; no reason not to emulate insns by default.  */
3455 a964acc6 Richard Henderson
    implver = IMPLVER_21264;
3456 a964acc6 Richard Henderson
    amask = (AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_MVI
3457 a964acc6 Richard Henderson
             | AMASK_TRAP | AMASK_PREFETCH);
3458 a964acc6 Richard Henderson
3459 a964acc6 Richard Henderson
    max = ARRAY_SIZE(cpu_defs);
3460 a964acc6 Richard Henderson
    for (i = 0; i < max; i++) {
3461 a964acc6 Richard Henderson
        if (strcmp (cpu_model, cpu_defs[i].name) == 0) {
3462 a964acc6 Richard Henderson
            implver = cpu_defs[i].implver;
3463 a964acc6 Richard Henderson
            amask = cpu_defs[i].amask;
3464 a964acc6 Richard Henderson
            break;
3465 a964acc6 Richard Henderson
        }
3466 a964acc6 Richard Henderson
    }
3467 a964acc6 Richard Henderson
    env->implver = implver;
3468 a964acc6 Richard Henderson
    env->amask = amask;
3469 a964acc6 Richard Henderson
3470 4c9649a9 j_mayer
#if defined (CONFIG_USER_ONLY)
3471 ea879fc7 Richard Henderson
    env->ps = PS_USER_MODE;
3472 2edd07ef Richard Henderson
    cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
3473 2edd07ef Richard Henderson
                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
3474 6049f4f8 Richard Henderson
#endif
3475 6910b8f6 Richard Henderson
    env->lock_addr = -1;
3476 26b46094 Richard Henderson
    env->fen = 1;
3477 dad081ee Richard Henderson
3478 0bf46a40 aliguori
    qemu_init_vcpu(env);
3479 4c9649a9 j_mayer
    return env;
3480 4c9649a9 j_mayer
}
3481 aaed909a bellard
3482 e87b7cb0 Stefan Weil
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
3483 d2856f1a aurel32
{
3484 d2856f1a aurel32
    env->pc = gen_opc_pc[pc_pos];
3485 d2856f1a aurel32
}