Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 57c83dac

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