Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 31d0f80f

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