Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 07b6c13b

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