xref: /openbmc/qemu/target/alpha/translate.c (revision b77af26e)
1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth  *  Alpha emulation cpu translation for qemu.
3fcf5ef2aSThomas Huth  *
4fcf5ef2aSThomas Huth  *  Copyright (c) 2007 Jocelyn Mayer
5fcf5ef2aSThomas Huth  *
6fcf5ef2aSThomas Huth  * This library is free software; you can redistribute it and/or
7fcf5ef2aSThomas Huth  * modify it under the terms of the GNU Lesser General Public
8fcf5ef2aSThomas Huth  * License as published by the Free Software Foundation; either
9d6ea4236SChetan Pant  * version 2.1 of the License, or (at your option) any later version.
10fcf5ef2aSThomas Huth  *
11fcf5ef2aSThomas Huth  * This library is distributed in the hope that it will be useful,
12fcf5ef2aSThomas Huth  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13fcf5ef2aSThomas Huth  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14fcf5ef2aSThomas Huth  * Lesser General Public License for more details.
15fcf5ef2aSThomas Huth  *
16fcf5ef2aSThomas Huth  * You should have received a copy of the GNU Lesser General Public
17fcf5ef2aSThomas Huth  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18fcf5ef2aSThomas Huth  */
19fcf5ef2aSThomas Huth 
20fcf5ef2aSThomas Huth #include "qemu/osdep.h"
21fcf5ef2aSThomas Huth #include "cpu.h"
22d2528bdcSPaolo Bonzini #include "sysemu/cpus.h"
23fcf5ef2aSThomas Huth #include "disas/disas.h"
24fcf5ef2aSThomas Huth #include "qemu/host-utils.h"
25fcf5ef2aSThomas Huth #include "exec/exec-all.h"
26dcb32f1dSPhilippe Mathieu-Daudé #include "tcg/tcg-op.h"
27fcf5ef2aSThomas Huth #include "exec/helper-proto.h"
28fcf5ef2aSThomas Huth #include "exec/helper-gen.h"
293de811c6SRichard Henderson #include "exec/translator.h"
30fcf5ef2aSThomas Huth #include "exec/log.h"
31fcf5ef2aSThomas Huth 
32d53106c9SRichard Henderson #define HELPER_H "helper.h"
33d53106c9SRichard Henderson #include "exec/helper-info.c.inc"
34d53106c9SRichard Henderson #undef  HELPER_H
35fcf5ef2aSThomas Huth 
36fcf5ef2aSThomas Huth #undef ALPHA_DEBUG_DISAS
37fcf5ef2aSThomas Huth #define CONFIG_SOFTFLOAT_INLINE
38fcf5ef2aSThomas Huth 
39fcf5ef2aSThomas Huth #ifdef ALPHA_DEBUG_DISAS
40fcf5ef2aSThomas Huth #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
41fcf5ef2aSThomas Huth #else
42fcf5ef2aSThomas Huth #  define LOG_DISAS(...) do { } while (0)
43fcf5ef2aSThomas Huth #endif
44fcf5ef2aSThomas Huth 
45fcf5ef2aSThomas Huth typedef struct DisasContext DisasContext;
46fcf5ef2aSThomas Huth struct DisasContext {
47c5f80657SRichard Henderson     DisasContextBase base;
48c5f80657SRichard Henderson 
49fed14246SRichard Henderson #ifdef CONFIG_USER_ONLY
50fed14246SRichard Henderson     MemOp unalign;
51fed14246SRichard Henderson #else
52fcf5ef2aSThomas Huth     uint64_t palbr;
53fcf5ef2aSThomas Huth #endif
54489a0e64SRichard Henderson     uint32_t tbflags;
55fcf5ef2aSThomas Huth     int mem_idx;
56fcf5ef2aSThomas Huth 
57c6d41b36SRichard Henderson     /* implver and amask values for this CPU.  */
58c6d41b36SRichard Henderson     int implver;
59c6d41b36SRichard Henderson     int amask;
60c6d41b36SRichard Henderson 
61fcf5ef2aSThomas Huth     /* Current rounding mode for this TB.  */
62fcf5ef2aSThomas Huth     int tb_rm;
63fcf5ef2aSThomas Huth     /* Current flush-to-zero setting for this TB.  */
64fcf5ef2aSThomas Huth     int tb_ftz;
65fcf5ef2aSThomas Huth 
66fcf5ef2aSThomas Huth     /* The set of registers active in the current context.  */
67fcf5ef2aSThomas Huth     TCGv *ir;
68fcf5ef2aSThomas Huth 
69fcf5ef2aSThomas Huth     /* Temporaries for $31 and $f31 as source and destination.  */
70fcf5ef2aSThomas Huth     TCGv zero;
71fcf5ef2aSThomas Huth     TCGv sink;
72fcf5ef2aSThomas Huth };
73fcf5ef2aSThomas Huth 
74fed14246SRichard Henderson #ifdef CONFIG_USER_ONLY
75fed14246SRichard Henderson #define UNALIGN(C)  (C)->unalign
76fed14246SRichard Henderson #else
776ffaac9cSRichard Henderson #define UNALIGN(C)  MO_ALIGN
78fed14246SRichard Henderson #endif
79fed14246SRichard Henderson 
803de811c6SRichard Henderson /* Target-specific return values from translate_one, indicating the
813de811c6SRichard Henderson    state of the TB.  Note that DISAS_NEXT indicates that we are not
82fcf5ef2aSThomas Huth    exiting the TB.  */
833de811c6SRichard Henderson #define DISAS_PC_UPDATED_NOCHAIN  DISAS_TARGET_0
843de811c6SRichard Henderson #define DISAS_PC_UPDATED          DISAS_TARGET_1
853de811c6SRichard Henderson #define DISAS_PC_STALE            DISAS_TARGET_2
86fcf5ef2aSThomas Huth 
87fcf5ef2aSThomas Huth /* global register indexes */
88fcf5ef2aSThomas Huth static TCGv cpu_std_ir[31];
89fcf5ef2aSThomas Huth static TCGv cpu_fir[31];
90fcf5ef2aSThomas Huth static TCGv cpu_pc;
91fcf5ef2aSThomas Huth static TCGv cpu_lock_addr;
92fcf5ef2aSThomas Huth static TCGv cpu_lock_value;
93fcf5ef2aSThomas Huth 
94fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
95fcf5ef2aSThomas Huth static TCGv cpu_pal_ir[31];
96fcf5ef2aSThomas Huth #endif
97fcf5ef2aSThomas Huth 
alpha_translate_init(void)98fcf5ef2aSThomas Huth void alpha_translate_init(void)
99fcf5ef2aSThomas Huth {
100fcf5ef2aSThomas Huth #define DEF_VAR(V)  { &cpu_##V, #V, offsetof(CPUAlphaState, V) }
101fcf5ef2aSThomas Huth 
102fcf5ef2aSThomas Huth     typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar;
103fcf5ef2aSThomas Huth     static const GlobalVar vars[] = {
104fcf5ef2aSThomas Huth         DEF_VAR(pc),
105fcf5ef2aSThomas Huth         DEF_VAR(lock_addr),
106fcf5ef2aSThomas Huth         DEF_VAR(lock_value),
107fcf5ef2aSThomas Huth     };
108fcf5ef2aSThomas Huth 
109fcf5ef2aSThomas Huth #undef DEF_VAR
110fcf5ef2aSThomas Huth 
111fcf5ef2aSThomas Huth     /* Use the symbolic register names that match the disassembler.  */
112fcf5ef2aSThomas Huth     static const char greg_names[31][4] = {
113fcf5ef2aSThomas Huth         "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
114fcf5ef2aSThomas Huth         "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
115fcf5ef2aSThomas Huth         "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
116fcf5ef2aSThomas Huth         "t10", "t11", "ra", "t12", "at", "gp", "sp"
117fcf5ef2aSThomas Huth     };
118fcf5ef2aSThomas Huth     static const char freg_names[31][4] = {
119fcf5ef2aSThomas Huth         "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
120fcf5ef2aSThomas Huth         "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
121fcf5ef2aSThomas Huth         "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
122fcf5ef2aSThomas Huth         "f24", "f25", "f26", "f27", "f28", "f29", "f30"
123fcf5ef2aSThomas Huth     };
124fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
125fcf5ef2aSThomas Huth     static const char shadow_names[8][8] = {
126fcf5ef2aSThomas Huth         "pal_t7", "pal_s0", "pal_s1", "pal_s2",
127fcf5ef2aSThomas Huth         "pal_s3", "pal_s4", "pal_s5", "pal_t11"
128fcf5ef2aSThomas Huth     };
129fcf5ef2aSThomas Huth #endif
130fcf5ef2aSThomas Huth 
131fcf5ef2aSThomas Huth     int i;
132fcf5ef2aSThomas Huth 
133fcf5ef2aSThomas Huth     for (i = 0; i < 31; i++) {
134ad75a51eSRichard Henderson         cpu_std_ir[i] = tcg_global_mem_new_i64(tcg_env,
135fcf5ef2aSThomas Huth                                                offsetof(CPUAlphaState, ir[i]),
136fcf5ef2aSThomas Huth                                                greg_names[i]);
137fcf5ef2aSThomas Huth     }
138fcf5ef2aSThomas Huth 
139fcf5ef2aSThomas Huth     for (i = 0; i < 31; i++) {
140ad75a51eSRichard Henderson         cpu_fir[i] = tcg_global_mem_new_i64(tcg_env,
141fcf5ef2aSThomas Huth                                             offsetof(CPUAlphaState, fir[i]),
142fcf5ef2aSThomas Huth                                             freg_names[i]);
143fcf5ef2aSThomas Huth     }
144fcf5ef2aSThomas Huth 
145fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
146fcf5ef2aSThomas Huth     memcpy(cpu_pal_ir, cpu_std_ir, sizeof(cpu_pal_ir));
147fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
148fcf5ef2aSThomas Huth         int r = (i == 7 ? 25 : i + 8);
149ad75a51eSRichard Henderson         cpu_pal_ir[r] = tcg_global_mem_new_i64(tcg_env,
150fcf5ef2aSThomas Huth                                                offsetof(CPUAlphaState,
151fcf5ef2aSThomas Huth                                                         shadow[i]),
152fcf5ef2aSThomas Huth                                                shadow_names[i]);
153fcf5ef2aSThomas Huth     }
154fcf5ef2aSThomas Huth #endif
155fcf5ef2aSThomas Huth 
156fcf5ef2aSThomas Huth     for (i = 0; i < ARRAY_SIZE(vars); ++i) {
157fcf5ef2aSThomas Huth         const GlobalVar *v = &vars[i];
158ad75a51eSRichard Henderson         *v->var = tcg_global_mem_new_i64(tcg_env, v->ofs, v->name);
159fcf5ef2aSThomas Huth     }
160fcf5ef2aSThomas Huth }
161fcf5ef2aSThomas Huth 
load_zero(DisasContext * ctx)162fcf5ef2aSThomas Huth static TCGv load_zero(DisasContext *ctx)
163fcf5ef2aSThomas Huth {
164f764718dSRichard Henderson     if (!ctx->zero) {
165212c88c0SRichard Henderson         ctx->zero = tcg_constant_i64(0);
166fcf5ef2aSThomas Huth     }
167fcf5ef2aSThomas Huth     return ctx->zero;
168fcf5ef2aSThomas Huth }
169fcf5ef2aSThomas Huth 
dest_sink(DisasContext * ctx)170fcf5ef2aSThomas Huth static TCGv dest_sink(DisasContext *ctx)
171fcf5ef2aSThomas Huth {
172f764718dSRichard Henderson     if (!ctx->sink) {
173fcf5ef2aSThomas Huth         ctx->sink = tcg_temp_new();
174fcf5ef2aSThomas Huth     }
175fcf5ef2aSThomas Huth     return ctx->sink;
176fcf5ef2aSThomas Huth }
177fcf5ef2aSThomas Huth 
free_context_temps(DisasContext * ctx)178fcf5ef2aSThomas Huth static void free_context_temps(DisasContext *ctx)
179fcf5ef2aSThomas Huth {
180f764718dSRichard Henderson     if (ctx->sink) {
181fcf5ef2aSThomas Huth         tcg_gen_discard_i64(ctx->sink);
182f764718dSRichard Henderson         ctx->sink = NULL;
183fcf5ef2aSThomas Huth     }
184fcf5ef2aSThomas Huth }
185fcf5ef2aSThomas Huth 
load_gpr(DisasContext * ctx,unsigned reg)186fcf5ef2aSThomas Huth static TCGv load_gpr(DisasContext *ctx, unsigned reg)
187fcf5ef2aSThomas Huth {
188fcf5ef2aSThomas Huth     if (likely(reg < 31)) {
189fcf5ef2aSThomas Huth         return ctx->ir[reg];
190fcf5ef2aSThomas Huth     } else {
191fcf5ef2aSThomas Huth         return load_zero(ctx);
192fcf5ef2aSThomas Huth     }
193fcf5ef2aSThomas Huth }
194fcf5ef2aSThomas Huth 
load_gpr_lit(DisasContext * ctx,unsigned reg,uint8_t lit,bool islit)195fcf5ef2aSThomas Huth static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg,
196fcf5ef2aSThomas Huth                          uint8_t lit, bool islit)
197fcf5ef2aSThomas Huth {
198fcf5ef2aSThomas Huth     if (islit) {
199212c88c0SRichard Henderson         return tcg_constant_i64(lit);
200fcf5ef2aSThomas Huth     } else if (likely(reg < 31)) {
201fcf5ef2aSThomas Huth         return ctx->ir[reg];
202fcf5ef2aSThomas Huth     } else {
203fcf5ef2aSThomas Huth         return load_zero(ctx);
204fcf5ef2aSThomas Huth     }
205fcf5ef2aSThomas Huth }
206fcf5ef2aSThomas Huth 
dest_gpr(DisasContext * ctx,unsigned reg)207fcf5ef2aSThomas Huth static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
208fcf5ef2aSThomas Huth {
209fcf5ef2aSThomas Huth     if (likely(reg < 31)) {
210fcf5ef2aSThomas Huth         return ctx->ir[reg];
211fcf5ef2aSThomas Huth     } else {
212fcf5ef2aSThomas Huth         return dest_sink(ctx);
213fcf5ef2aSThomas Huth     }
214fcf5ef2aSThomas Huth }
215fcf5ef2aSThomas Huth 
load_fpr(DisasContext * ctx,unsigned reg)216fcf5ef2aSThomas Huth static TCGv load_fpr(DisasContext *ctx, unsigned reg)
217fcf5ef2aSThomas Huth {
218fcf5ef2aSThomas Huth     if (likely(reg < 31)) {
219fcf5ef2aSThomas Huth         return cpu_fir[reg];
220fcf5ef2aSThomas Huth     } else {
221fcf5ef2aSThomas Huth         return load_zero(ctx);
222fcf5ef2aSThomas Huth     }
223fcf5ef2aSThomas Huth }
224fcf5ef2aSThomas Huth 
dest_fpr(DisasContext * ctx,unsigned reg)225fcf5ef2aSThomas Huth static TCGv dest_fpr(DisasContext *ctx, unsigned reg)
226fcf5ef2aSThomas Huth {
227fcf5ef2aSThomas Huth     if (likely(reg < 31)) {
228fcf5ef2aSThomas Huth         return cpu_fir[reg];
229fcf5ef2aSThomas Huth     } else {
230fcf5ef2aSThomas Huth         return dest_sink(ctx);
231fcf5ef2aSThomas Huth     }
232fcf5ef2aSThomas Huth }
233fcf5ef2aSThomas Huth 
get_flag_ofs(unsigned shift)234bcd2625dSRichard Henderson static int get_flag_ofs(unsigned shift)
235bcd2625dSRichard Henderson {
236bcd2625dSRichard Henderson     int ofs = offsetof(CPUAlphaState, flags);
237e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
238bcd2625dSRichard Henderson     ofs += 3 - (shift / 8);
239bcd2625dSRichard Henderson #else
240bcd2625dSRichard Henderson     ofs += shift / 8;
241bcd2625dSRichard Henderson #endif
242bcd2625dSRichard Henderson     return ofs;
243bcd2625dSRichard Henderson }
244bcd2625dSRichard Henderson 
ld_flag_byte(TCGv val,unsigned shift)245bcd2625dSRichard Henderson static void ld_flag_byte(TCGv val, unsigned shift)
246bcd2625dSRichard Henderson {
247ad75a51eSRichard Henderson     tcg_gen_ld8u_i64(val, tcg_env, get_flag_ofs(shift));
248bcd2625dSRichard Henderson }
249bcd2625dSRichard Henderson 
st_flag_byte(TCGv val,unsigned shift)250bcd2625dSRichard Henderson static void st_flag_byte(TCGv val, unsigned shift)
251bcd2625dSRichard Henderson {
252ad75a51eSRichard Henderson     tcg_gen_st8_i64(val, tcg_env, get_flag_ofs(shift));
253bcd2625dSRichard Henderson }
254bcd2625dSRichard Henderson 
gen_excp_1(int exception,int error_code)255fcf5ef2aSThomas Huth static void gen_excp_1(int exception, int error_code)
256fcf5ef2aSThomas Huth {
257fcf5ef2aSThomas Huth     TCGv_i32 tmp1, tmp2;
258fcf5ef2aSThomas Huth 
259904bd855SRichard Henderson     tmp1 = tcg_constant_i32(exception);
260904bd855SRichard Henderson     tmp2 = tcg_constant_i32(error_code);
261ad75a51eSRichard Henderson     gen_helper_excp(tcg_env, tmp1, tmp2);
262fcf5ef2aSThomas Huth }
263fcf5ef2aSThomas Huth 
gen_excp(DisasContext * ctx,int exception,int error_code)2643de811c6SRichard Henderson static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code)
265fcf5ef2aSThomas Huth {
266c5f80657SRichard Henderson     tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
267fcf5ef2aSThomas Huth     gen_excp_1(exception, error_code);
2683de811c6SRichard Henderson     return DISAS_NORETURN;
269fcf5ef2aSThomas Huth }
270fcf5ef2aSThomas Huth 
gen_invalid(DisasContext * ctx)2713de811c6SRichard Henderson static inline DisasJumpType gen_invalid(DisasContext *ctx)
272fcf5ef2aSThomas Huth {
273fcf5ef2aSThomas Huth     return gen_excp(ctx, EXCP_OPCDEC, 0);
274fcf5ef2aSThomas Huth }
275fcf5ef2aSThomas Huth 
gen_ldf(DisasContext * ctx,TCGv dest,TCGv addr)27645263531SRichard Henderson static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr)
277fcf5ef2aSThomas Huth {
278fcf5ef2aSThomas Huth     TCGv_i32 tmp32 = tcg_temp_new_i32();
279fed14246SRichard Henderson     tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
28045263531SRichard Henderson     gen_helper_memory_to_f(dest, tmp32);
281fcf5ef2aSThomas Huth }
282fcf5ef2aSThomas Huth 
gen_ldg(DisasContext * ctx,TCGv dest,TCGv addr)28345263531SRichard Henderson static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr)
284fcf5ef2aSThomas Huth {
285fcf5ef2aSThomas Huth     TCGv tmp = tcg_temp_new();
286fc313c64SFrédéric Pétrot     tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
28745263531SRichard Henderson     gen_helper_memory_to_g(dest, tmp);
288fcf5ef2aSThomas Huth }
289fcf5ef2aSThomas Huth 
gen_lds(DisasContext * ctx,TCGv dest,TCGv addr)29045263531SRichard Henderson static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr)
291fcf5ef2aSThomas Huth {
292fcf5ef2aSThomas Huth     TCGv_i32 tmp32 = tcg_temp_new_i32();
293fed14246SRichard Henderson     tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
29445263531SRichard Henderson     gen_helper_memory_to_s(dest, tmp32);
295fcf5ef2aSThomas Huth }
296fcf5ef2aSThomas Huth 
gen_ldt(DisasContext * ctx,TCGv dest,TCGv addr)29745263531SRichard Henderson static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr)
29845263531SRichard Henderson {
299fc313c64SFrédéric Pétrot     tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
30045263531SRichard Henderson }
30145263531SRichard Henderson 
gen_load_fp(DisasContext * ctx,int ra,int rb,int32_t disp16,void (* func)(DisasContext *,TCGv,TCGv))30245263531SRichard Henderson static void gen_load_fp(DisasContext *ctx, int ra, int rb, int32_t disp16,
30345263531SRichard Henderson                         void (*func)(DisasContext *, TCGv, TCGv))
30445263531SRichard Henderson {
30545263531SRichard Henderson     /* Loads to $f31 are prefetches, which we can treat as nops. */
30645263531SRichard Henderson     if (likely(ra != 31)) {
30745263531SRichard Henderson         TCGv addr = tcg_temp_new();
30845263531SRichard Henderson         tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
30945263531SRichard Henderson         func(ctx, cpu_fir[ra], addr);
31045263531SRichard Henderson     }
31145263531SRichard Henderson }
31245263531SRichard Henderson 
gen_load_int(DisasContext * ctx,int ra,int rb,int32_t disp16,MemOp op,bool clear,bool locked)3135ffcb334SRichard Henderson static void gen_load_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
3145ffcb334SRichard Henderson                          MemOp op, bool clear, bool locked)
315fcf5ef2aSThomas Huth {
3165ffcb334SRichard Henderson     TCGv addr, dest;
317fcf5ef2aSThomas Huth 
318fcf5ef2aSThomas Huth     /* LDQ_U with ra $31 is UNOP.  Other various loads are forms of
319fcf5ef2aSThomas Huth        prefetches, which we can treat as nops.  No worries about
320fcf5ef2aSThomas Huth        missed exceptions here.  */
321fcf5ef2aSThomas Huth     if (unlikely(ra == 31)) {
322fcf5ef2aSThomas Huth         return;
323fcf5ef2aSThomas Huth     }
324fcf5ef2aSThomas Huth 
3255ffcb334SRichard Henderson     addr = tcg_temp_new();
3265ffcb334SRichard Henderson     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
327fcf5ef2aSThomas Huth     if (clear) {
3285ffcb334SRichard Henderson         tcg_gen_andi_i64(addr, addr, ~0x7);
329fed14246SRichard Henderson     } else if (!locked) {
330fed14246SRichard Henderson         op |= UNALIGN(ctx);
331fcf5ef2aSThomas Huth     }
332fcf5ef2aSThomas Huth 
3335ffcb334SRichard Henderson     dest = ctx->ir[ra];
3345ffcb334SRichard Henderson     tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, op);
335fcf5ef2aSThomas Huth 
3365ffcb334SRichard Henderson     if (locked) {
3375ffcb334SRichard Henderson         tcg_gen_mov_i64(cpu_lock_addr, addr);
3385ffcb334SRichard Henderson         tcg_gen_mov_i64(cpu_lock_value, dest);
3395ffcb334SRichard Henderson     }
340fcf5ef2aSThomas Huth }
341fcf5ef2aSThomas Huth 
gen_stf(DisasContext * ctx,TCGv src,TCGv addr)34245263531SRichard Henderson static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr)
343fcf5ef2aSThomas Huth {
344fcf5ef2aSThomas Huth     TCGv_i32 tmp32 = tcg_temp_new_i32();
34545263531SRichard Henderson     gen_helper_f_to_memory(tmp32, addr);
346fed14246SRichard Henderson     tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
347fcf5ef2aSThomas Huth }
348fcf5ef2aSThomas Huth 
gen_stg(DisasContext * ctx,TCGv src,TCGv addr)34945263531SRichard Henderson static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr)
350fcf5ef2aSThomas Huth {
351fcf5ef2aSThomas Huth     TCGv tmp = tcg_temp_new();
35245263531SRichard Henderson     gen_helper_g_to_memory(tmp, src);
353fc313c64SFrédéric Pétrot     tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
354fcf5ef2aSThomas Huth }
355fcf5ef2aSThomas Huth 
gen_sts(DisasContext * ctx,TCGv src,TCGv addr)35645263531SRichard Henderson static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr)
357fcf5ef2aSThomas Huth {
358fcf5ef2aSThomas Huth     TCGv_i32 tmp32 = tcg_temp_new_i32();
35945263531SRichard Henderson     gen_helper_s_to_memory(tmp32, src);
360fed14246SRichard Henderson     tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
361fcf5ef2aSThomas Huth }
362fcf5ef2aSThomas Huth 
gen_stt(DisasContext * ctx,TCGv src,TCGv addr)36345263531SRichard Henderson static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr)
36445263531SRichard Henderson {
365fc313c64SFrédéric Pétrot     tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
36645263531SRichard Henderson }
36745263531SRichard Henderson 
gen_store_fp(DisasContext * ctx,int ra,int rb,int32_t disp16,void (* func)(DisasContext *,TCGv,TCGv))36845263531SRichard Henderson static void gen_store_fp(DisasContext *ctx, int ra, int rb, int32_t disp16,
36945263531SRichard Henderson                          void (*func)(DisasContext *, TCGv, TCGv))
37045263531SRichard Henderson {
37145263531SRichard Henderson     TCGv addr = tcg_temp_new();
37245263531SRichard Henderson     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
37345263531SRichard Henderson     func(ctx, load_fpr(ctx, ra), addr);
37445263531SRichard Henderson }
37545263531SRichard Henderson 
gen_store_int(DisasContext * ctx,int ra,int rb,int32_t disp16,MemOp op,bool clear)3765ffcb334SRichard Henderson static void gen_store_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
3775ffcb334SRichard Henderson                           MemOp op, bool clear)
378fcf5ef2aSThomas Huth {
3795ffcb334SRichard Henderson     TCGv addr, src;
380fcf5ef2aSThomas Huth 
3815ffcb334SRichard Henderson     addr = tcg_temp_new();
3825ffcb334SRichard Henderson     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
383fcf5ef2aSThomas Huth     if (clear) {
3845ffcb334SRichard Henderson         tcg_gen_andi_i64(addr, addr, ~0x7);
385fed14246SRichard Henderson     } else {
386fed14246SRichard Henderson         op |= UNALIGN(ctx);
387fcf5ef2aSThomas Huth     }
388fcf5ef2aSThomas Huth 
3895ffcb334SRichard Henderson     src = load_gpr(ctx, ra);
3905ffcb334SRichard Henderson     tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, op);
391fcf5ef2aSThomas Huth }
392fcf5ef2aSThomas Huth 
gen_store_conditional(DisasContext * ctx,int ra,int rb,int32_t disp16,int mem_idx,MemOp op)3933de811c6SRichard Henderson static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb,
394fcf5ef2aSThomas Huth                                            int32_t disp16, int mem_idx,
39514776ab5STony Nguyen                                            MemOp op)
396fcf5ef2aSThomas Huth {
397fcf5ef2aSThomas Huth     TCGLabel *lab_fail, *lab_done;
398fcf5ef2aSThomas Huth     TCGv addr, val;
399fcf5ef2aSThomas Huth 
400fcf5ef2aSThomas Huth     addr = tcg_temp_new_i64();
401fcf5ef2aSThomas Huth     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
402fcf5ef2aSThomas Huth     free_context_temps(ctx);
403fcf5ef2aSThomas Huth 
404fcf5ef2aSThomas Huth     lab_fail = gen_new_label();
405fcf5ef2aSThomas Huth     lab_done = gen_new_label();
406fcf5ef2aSThomas Huth     tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
407fcf5ef2aSThomas Huth 
408fcf5ef2aSThomas Huth     val = tcg_temp_new_i64();
409fcf5ef2aSThomas Huth     tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value,
410fcf5ef2aSThomas Huth                                load_gpr(ctx, ra), mem_idx, op);
411fcf5ef2aSThomas Huth     free_context_temps(ctx);
412fcf5ef2aSThomas Huth 
413fcf5ef2aSThomas Huth     if (ra != 31) {
414fcf5ef2aSThomas Huth         tcg_gen_setcond_i64(TCG_COND_EQ, ctx->ir[ra], val, cpu_lock_value);
415fcf5ef2aSThomas Huth     }
416fcf5ef2aSThomas Huth     tcg_gen_br(lab_done);
417fcf5ef2aSThomas Huth 
418fcf5ef2aSThomas Huth     gen_set_label(lab_fail);
419fcf5ef2aSThomas Huth     if (ra != 31) {
420fcf5ef2aSThomas Huth         tcg_gen_movi_i64(ctx->ir[ra], 0);
421fcf5ef2aSThomas Huth     }
422fcf5ef2aSThomas Huth 
423fcf5ef2aSThomas Huth     gen_set_label(lab_done);
424fcf5ef2aSThomas Huth     tcg_gen_movi_i64(cpu_lock_addr, -1);
4253de811c6SRichard Henderson     return DISAS_NEXT;
426fcf5ef2aSThomas Huth }
427fcf5ef2aSThomas Huth 
use_goto_tb(DisasContext * ctx,uint64_t dest)428fcf5ef2aSThomas Huth static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
429fcf5ef2aSThomas Huth {
43021a7e89eSRichard Henderson     return translator_use_goto_tb(&ctx->base, dest);
431fcf5ef2aSThomas Huth }
432fcf5ef2aSThomas Huth 
gen_bdirect(DisasContext * ctx,int ra,int32_t disp)4333de811c6SRichard Henderson static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
434fcf5ef2aSThomas Huth {
435c5f80657SRichard Henderson     uint64_t dest = ctx->base.pc_next + (disp << 2);
436fcf5ef2aSThomas Huth 
437fcf5ef2aSThomas Huth     if (ra != 31) {
438c5f80657SRichard Henderson         tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
439fcf5ef2aSThomas Huth     }
440fcf5ef2aSThomas Huth 
441fcf5ef2aSThomas Huth     /* Notice branch-to-next; used to initialize RA with the PC.  */
442fcf5ef2aSThomas Huth     if (disp == 0) {
443fcf5ef2aSThomas Huth         return 0;
444fcf5ef2aSThomas Huth     } else if (use_goto_tb(ctx, dest)) {
445fcf5ef2aSThomas Huth         tcg_gen_goto_tb(0);
446fcf5ef2aSThomas Huth         tcg_gen_movi_i64(cpu_pc, dest);
44707ea28b4SRichard Henderson         tcg_gen_exit_tb(ctx->base.tb, 0);
4483de811c6SRichard Henderson         return DISAS_NORETURN;
449fcf5ef2aSThomas Huth     } else {
450fcf5ef2aSThomas Huth         tcg_gen_movi_i64(cpu_pc, dest);
4513de811c6SRichard Henderson         return DISAS_PC_UPDATED;
452fcf5ef2aSThomas Huth     }
453fcf5ef2aSThomas Huth }
454fcf5ef2aSThomas Huth 
gen_bcond_internal(DisasContext * ctx,TCGCond cond,TCGv cmp,int32_t disp)4553de811c6SRichard Henderson static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
456fcf5ef2aSThomas Huth                                         TCGv cmp, int32_t disp)
457fcf5ef2aSThomas Huth {
458c5f80657SRichard Henderson     uint64_t dest = ctx->base.pc_next + (disp << 2);
459fcf5ef2aSThomas Huth     TCGLabel *lab_true = gen_new_label();
460fcf5ef2aSThomas Huth 
461fcf5ef2aSThomas Huth     if (use_goto_tb(ctx, dest)) {
462fcf5ef2aSThomas Huth         tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
463fcf5ef2aSThomas Huth 
464fcf5ef2aSThomas Huth         tcg_gen_goto_tb(0);
465c5f80657SRichard Henderson         tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
46607ea28b4SRichard Henderson         tcg_gen_exit_tb(ctx->base.tb, 0);
467fcf5ef2aSThomas Huth 
468fcf5ef2aSThomas Huth         gen_set_label(lab_true);
469fcf5ef2aSThomas Huth         tcg_gen_goto_tb(1);
470fcf5ef2aSThomas Huth         tcg_gen_movi_i64(cpu_pc, dest);
47107ea28b4SRichard Henderson         tcg_gen_exit_tb(ctx->base.tb, 1);
472fcf5ef2aSThomas Huth 
4733de811c6SRichard Henderson         return DISAS_NORETURN;
474fcf5ef2aSThomas Huth     } else {
475904bd855SRichard Henderson         TCGv_i64 z = load_zero(ctx);
476904bd855SRichard Henderson         TCGv_i64 d = tcg_constant_i64(dest);
477904bd855SRichard Henderson         TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
478fcf5ef2aSThomas Huth 
479fcf5ef2aSThomas Huth         tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
4803de811c6SRichard Henderson         return DISAS_PC_UPDATED;
481fcf5ef2aSThomas Huth     }
482fcf5ef2aSThomas Huth }
483fcf5ef2aSThomas Huth 
gen_bcond(DisasContext * ctx,TCGCond cond,int ra,int32_t disp,int mask)4843de811c6SRichard Henderson static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
485fcf5ef2aSThomas Huth                                int32_t disp, int mask)
486fcf5ef2aSThomas Huth {
487fcf5ef2aSThomas Huth     if (mask) {
48822d716c2SRichard Henderson         TCGv tmp = tcg_temp_new();
4893de811c6SRichard Henderson         DisasJumpType ret;
490fcf5ef2aSThomas Huth 
49122d716c2SRichard Henderson         tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
49222d716c2SRichard Henderson         ret = gen_bcond_internal(ctx, cond, tmp, disp);
49322d716c2SRichard Henderson         return ret;
49422d716c2SRichard Henderson     }
49522d716c2SRichard Henderson     return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
496fcf5ef2aSThomas Huth }
497fcf5ef2aSThomas Huth 
498fcf5ef2aSThomas Huth /* Fold -0.0 for comparison with COND.  */
499fcf5ef2aSThomas Huth 
gen_fold_mzero(TCGCond cond,TCGv dest,TCGv src)500fcf5ef2aSThomas Huth static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
501fcf5ef2aSThomas Huth {
502fcf5ef2aSThomas Huth     uint64_t mzero = 1ull << 63;
503fcf5ef2aSThomas Huth 
504fcf5ef2aSThomas Huth     switch (cond) {
505fcf5ef2aSThomas Huth     case TCG_COND_LE:
506fcf5ef2aSThomas Huth     case TCG_COND_GT:
507fcf5ef2aSThomas Huth         /* For <= or >, the -0.0 value directly compares the way we want.  */
508fcf5ef2aSThomas Huth         tcg_gen_mov_i64(dest, src);
509fcf5ef2aSThomas Huth         break;
510fcf5ef2aSThomas Huth 
511fcf5ef2aSThomas Huth     case TCG_COND_EQ:
512fcf5ef2aSThomas Huth     case TCG_COND_NE:
513fcf5ef2aSThomas Huth         /* For == or !=, we can simply mask off the sign bit and compare.  */
514fcf5ef2aSThomas Huth         tcg_gen_andi_i64(dest, src, mzero - 1);
515fcf5ef2aSThomas Huth         break;
516fcf5ef2aSThomas Huth 
517fcf5ef2aSThomas Huth     case TCG_COND_GE:
518fcf5ef2aSThomas Huth     case TCG_COND_LT:
519d55a3211SRichard Henderson         /* For >= or <, map -0.0 to +0.0. */
520d55a3211SRichard Henderson         tcg_gen_movcond_i64(TCG_COND_NE, dest, src, tcg_constant_i64(mzero),
521d55a3211SRichard Henderson                             src, tcg_constant_i64(0));
522fcf5ef2aSThomas Huth         break;
523fcf5ef2aSThomas Huth 
524fcf5ef2aSThomas Huth     default:
525fcf5ef2aSThomas Huth         abort();
526fcf5ef2aSThomas Huth     }
527fcf5ef2aSThomas Huth }
528fcf5ef2aSThomas Huth 
gen_fbcond(DisasContext * ctx,TCGCond cond,int ra,int32_t disp)5293de811c6SRichard Henderson static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
530fcf5ef2aSThomas Huth                                 int32_t disp)
531fcf5ef2aSThomas Huth {
532fcf5ef2aSThomas Huth     TCGv cmp_tmp = tcg_temp_new();
5333de811c6SRichard Henderson     DisasJumpType ret;
5346a9b110dSRichard Henderson 
535fcf5ef2aSThomas Huth     gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
5366a9b110dSRichard Henderson     ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
5376a9b110dSRichard Henderson     return ret;
538fcf5ef2aSThomas Huth }
539fcf5ef2aSThomas Huth 
gen_fcmov(DisasContext * ctx,TCGCond cond,int ra,int rb,int rc)540fcf5ef2aSThomas Huth static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc)
541fcf5ef2aSThomas Huth {
542fcf5ef2aSThomas Huth     TCGv_i64 va, vb, z;
543fcf5ef2aSThomas Huth 
544fcf5ef2aSThomas Huth     z = load_zero(ctx);
545fcf5ef2aSThomas Huth     vb = load_fpr(ctx, rb);
546fcf5ef2aSThomas Huth     va = tcg_temp_new();
547fcf5ef2aSThomas Huth     gen_fold_mzero(cond, va, load_fpr(ctx, ra));
548fcf5ef2aSThomas Huth 
549fcf5ef2aSThomas Huth     tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc));
550fcf5ef2aSThomas Huth }
551fcf5ef2aSThomas Huth 
552fcf5ef2aSThomas Huth #define QUAL_RM_N       0x080   /* Round mode nearest even */
553fcf5ef2aSThomas Huth #define QUAL_RM_C       0x000   /* Round mode chopped */
554fcf5ef2aSThomas Huth #define QUAL_RM_M       0x040   /* Round mode minus infinity */
555fcf5ef2aSThomas Huth #define QUAL_RM_D       0x0c0   /* Round mode dynamic */
556fcf5ef2aSThomas Huth #define QUAL_RM_MASK    0x0c0
557fcf5ef2aSThomas Huth 
558fcf5ef2aSThomas Huth #define QUAL_U          0x100   /* Underflow enable (fp output) */
559fcf5ef2aSThomas Huth #define QUAL_V          0x100   /* Overflow enable (int output) */
560fcf5ef2aSThomas Huth #define QUAL_S          0x400   /* Software completion enable */
561fcf5ef2aSThomas Huth #define QUAL_I          0x200   /* Inexact detection enable */
562fcf5ef2aSThomas Huth 
gen_qual_roundmode(DisasContext * ctx,int fn11)563fcf5ef2aSThomas Huth static void gen_qual_roundmode(DisasContext *ctx, int fn11)
564fcf5ef2aSThomas Huth {
565fcf5ef2aSThomas Huth     TCGv_i32 tmp;
566fcf5ef2aSThomas Huth 
567fcf5ef2aSThomas Huth     fn11 &= QUAL_RM_MASK;
568fcf5ef2aSThomas Huth     if (fn11 == ctx->tb_rm) {
569fcf5ef2aSThomas Huth         return;
570fcf5ef2aSThomas Huth     }
571fcf5ef2aSThomas Huth     ctx->tb_rm = fn11;
572fcf5ef2aSThomas Huth 
573fcf5ef2aSThomas Huth     tmp = tcg_temp_new_i32();
574fcf5ef2aSThomas Huth     switch (fn11) {
575fcf5ef2aSThomas Huth     case QUAL_RM_N:
576fcf5ef2aSThomas Huth         tcg_gen_movi_i32(tmp, float_round_nearest_even);
577fcf5ef2aSThomas Huth         break;
578fcf5ef2aSThomas Huth     case QUAL_RM_C:
579fcf5ef2aSThomas Huth         tcg_gen_movi_i32(tmp, float_round_to_zero);
580fcf5ef2aSThomas Huth         break;
581fcf5ef2aSThomas Huth     case QUAL_RM_M:
582fcf5ef2aSThomas Huth         tcg_gen_movi_i32(tmp, float_round_down);
583fcf5ef2aSThomas Huth         break;
584fcf5ef2aSThomas Huth     case QUAL_RM_D:
585ad75a51eSRichard Henderson         tcg_gen_ld8u_i32(tmp, tcg_env,
586fcf5ef2aSThomas Huth                          offsetof(CPUAlphaState, fpcr_dyn_round));
587fcf5ef2aSThomas Huth         break;
588fcf5ef2aSThomas Huth     }
589fcf5ef2aSThomas Huth 
590fcf5ef2aSThomas Huth #if defined(CONFIG_SOFTFLOAT_INLINE)
591fcf5ef2aSThomas Huth     /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode.
592fcf5ef2aSThomas Huth        With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
593fcf5ef2aSThomas Huth        sets the one field.  */
594ad75a51eSRichard Henderson     tcg_gen_st8_i32(tmp, tcg_env,
595fcf5ef2aSThomas Huth                     offsetof(CPUAlphaState, fp_status.float_rounding_mode));
596fcf5ef2aSThomas Huth #else
597fcf5ef2aSThomas Huth     gen_helper_setroundmode(tmp);
598fcf5ef2aSThomas Huth #endif
599fcf5ef2aSThomas Huth }
600fcf5ef2aSThomas Huth 
gen_qual_flushzero(DisasContext * ctx,int fn11)601fcf5ef2aSThomas Huth static void gen_qual_flushzero(DisasContext *ctx, int fn11)
602fcf5ef2aSThomas Huth {
603fcf5ef2aSThomas Huth     TCGv_i32 tmp;
604fcf5ef2aSThomas Huth 
605fcf5ef2aSThomas Huth     fn11 &= QUAL_U;
606fcf5ef2aSThomas Huth     if (fn11 == ctx->tb_ftz) {
607fcf5ef2aSThomas Huth         return;
608fcf5ef2aSThomas Huth     }
609fcf5ef2aSThomas Huth     ctx->tb_ftz = fn11;
610fcf5ef2aSThomas Huth 
611fcf5ef2aSThomas Huth     tmp = tcg_temp_new_i32();
612fcf5ef2aSThomas Huth     if (fn11) {
613fcf5ef2aSThomas Huth         /* Underflow is enabled, use the FPCR setting.  */
614ad75a51eSRichard Henderson         tcg_gen_ld8u_i32(tmp, tcg_env,
615fcf5ef2aSThomas Huth                          offsetof(CPUAlphaState, fpcr_flush_to_zero));
616fcf5ef2aSThomas Huth     } else {
617fcf5ef2aSThomas Huth         /* Underflow is disabled, force flush-to-zero.  */
618fcf5ef2aSThomas Huth         tcg_gen_movi_i32(tmp, 1);
619fcf5ef2aSThomas Huth     }
620fcf5ef2aSThomas Huth 
621fcf5ef2aSThomas Huth #if defined(CONFIG_SOFTFLOAT_INLINE)
622ad75a51eSRichard Henderson     tcg_gen_st8_i32(tmp, tcg_env,
623fcf5ef2aSThomas Huth                     offsetof(CPUAlphaState, fp_status.flush_to_zero));
624fcf5ef2aSThomas Huth #else
625fcf5ef2aSThomas Huth     gen_helper_setflushzero(tmp);
626fcf5ef2aSThomas Huth #endif
627fcf5ef2aSThomas Huth }
628fcf5ef2aSThomas Huth 
gen_ieee_input(DisasContext * ctx,int reg,int fn11,int is_cmp)629fcf5ef2aSThomas Huth static TCGv gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp)
630fcf5ef2aSThomas Huth {
631fcf5ef2aSThomas Huth     TCGv val;
632fcf5ef2aSThomas Huth 
633fcf5ef2aSThomas Huth     if (unlikely(reg == 31)) {
634fcf5ef2aSThomas Huth         val = load_zero(ctx);
635fcf5ef2aSThomas Huth     } else {
636fcf5ef2aSThomas Huth         val = cpu_fir[reg];
637fcf5ef2aSThomas Huth         if ((fn11 & QUAL_S) == 0) {
638fcf5ef2aSThomas Huth             if (is_cmp) {
639ad75a51eSRichard Henderson                 gen_helper_ieee_input_cmp(tcg_env, val);
640fcf5ef2aSThomas Huth             } else {
641ad75a51eSRichard Henderson                 gen_helper_ieee_input(tcg_env, val);
642fcf5ef2aSThomas Huth             }
643fcf5ef2aSThomas Huth         } else {
644fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
645fcf5ef2aSThomas Huth             /* In system mode, raise exceptions for denormals like real
646fcf5ef2aSThomas Huth                hardware.  In user mode, proceed as if the OS completion
647fcf5ef2aSThomas Huth                handler is handling the denormal as per spec.  */
648ad75a51eSRichard Henderson             gen_helper_ieee_input_s(tcg_env, val);
649fcf5ef2aSThomas Huth #endif
650fcf5ef2aSThomas Huth         }
651fcf5ef2aSThomas Huth     }
652fcf5ef2aSThomas Huth     return val;
653fcf5ef2aSThomas Huth }
654fcf5ef2aSThomas Huth 
gen_fp_exc_raise(int rc,int fn11)655fcf5ef2aSThomas Huth static void gen_fp_exc_raise(int rc, int fn11)
656fcf5ef2aSThomas Huth {
657fcf5ef2aSThomas Huth     /* ??? We ought to be able to do something with imprecise exceptions.
658fcf5ef2aSThomas Huth        E.g. notice we're still in the trap shadow of something within the
659fcf5ef2aSThomas Huth        TB and do not generate the code to signal the exception; end the TB
660fcf5ef2aSThomas Huth        when an exception is forced to arrive, either by consumption of a
661fcf5ef2aSThomas Huth        register value or TRAPB or EXCB.  */
662fcf5ef2aSThomas Huth     TCGv_i32 reg, ign;
663fcf5ef2aSThomas Huth     uint32_t ignore = 0;
664fcf5ef2aSThomas Huth 
665fcf5ef2aSThomas Huth     if (!(fn11 & QUAL_U)) {
666fcf5ef2aSThomas Huth         /* Note that QUAL_U == QUAL_V, so ignore either.  */
667fcf5ef2aSThomas Huth         ignore |= FPCR_UNF | FPCR_IOV;
668fcf5ef2aSThomas Huth     }
669fcf5ef2aSThomas Huth     if (!(fn11 & QUAL_I)) {
670fcf5ef2aSThomas Huth         ignore |= FPCR_INE;
671fcf5ef2aSThomas Huth     }
672904bd855SRichard Henderson     ign = tcg_constant_i32(ignore);
673fcf5ef2aSThomas Huth 
674fcf5ef2aSThomas Huth     /* ??? Pass in the regno of the destination so that the helper can
675fcf5ef2aSThomas Huth        set EXC_MASK, which contains a bitmask of destination registers
676fcf5ef2aSThomas Huth        that have caused arithmetic traps.  A simple userspace emulation
677fcf5ef2aSThomas Huth        does not require this.  We do need it for a guest kernel's entArith,
678fcf5ef2aSThomas Huth        or if we were to do something clever with imprecise exceptions.  */
679904bd855SRichard Henderson     reg = tcg_constant_i32(rc + 32);
680fcf5ef2aSThomas Huth     if (fn11 & QUAL_S) {
681ad75a51eSRichard Henderson         gen_helper_fp_exc_raise_s(tcg_env, ign, reg);
682fcf5ef2aSThomas Huth     } else {
683ad75a51eSRichard Henderson         gen_helper_fp_exc_raise(tcg_env, ign, reg);
684fcf5ef2aSThomas Huth     }
685fcf5ef2aSThomas Huth }
686fcf5ef2aSThomas Huth 
gen_cvtlq(TCGv vc,TCGv vb)687fcf5ef2aSThomas Huth static void gen_cvtlq(TCGv vc, TCGv vb)
688fcf5ef2aSThomas Huth {
689fcf5ef2aSThomas Huth     TCGv tmp = tcg_temp_new();
690fcf5ef2aSThomas Huth 
691fcf5ef2aSThomas Huth     /* The arithmetic right shift here, plus the sign-extended mask below
692fcf5ef2aSThomas Huth        yields a sign-extended result without an explicit ext32s_i64.  */
693729028a6SPhilippe Mathieu-Daudé     tcg_gen_shri_i64(tmp, vb, 29);
694729028a6SPhilippe Mathieu-Daudé     tcg_gen_sari_i64(vc, vb, 32);
695729028a6SPhilippe Mathieu-Daudé     tcg_gen_deposit_i64(vc, vc, tmp, 0, 30);
696fcf5ef2aSThomas Huth }
697fcf5ef2aSThomas Huth 
gen_ieee_arith2(DisasContext * ctx,void (* helper)(TCGv,TCGv_ptr,TCGv),int rb,int rc,int fn11)698fcf5ef2aSThomas Huth static void gen_ieee_arith2(DisasContext *ctx,
699fcf5ef2aSThomas Huth                             void (*helper)(TCGv, TCGv_ptr, TCGv),
700fcf5ef2aSThomas Huth                             int rb, int rc, int fn11)
701fcf5ef2aSThomas Huth {
702fcf5ef2aSThomas Huth     TCGv vb;
703fcf5ef2aSThomas Huth 
704fcf5ef2aSThomas Huth     gen_qual_roundmode(ctx, fn11);
705fcf5ef2aSThomas Huth     gen_qual_flushzero(ctx, fn11);
706fcf5ef2aSThomas Huth 
707fcf5ef2aSThomas Huth     vb = gen_ieee_input(ctx, rb, fn11, 0);
708ad75a51eSRichard Henderson     helper(dest_fpr(ctx, rc), tcg_env, vb);
709fcf5ef2aSThomas Huth 
710fcf5ef2aSThomas Huth     gen_fp_exc_raise(rc, fn11);
711fcf5ef2aSThomas Huth }
712fcf5ef2aSThomas Huth 
713fcf5ef2aSThomas Huth #define IEEE_ARITH2(name)                                       \
714fcf5ef2aSThomas Huth static inline void glue(gen_, name)(DisasContext *ctx,          \
715fcf5ef2aSThomas Huth                                     int rb, int rc, int fn11)   \
716fcf5ef2aSThomas Huth {                                                               \
717fcf5ef2aSThomas Huth     gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11);      \
718fcf5ef2aSThomas Huth }
719fcf5ef2aSThomas Huth IEEE_ARITH2(sqrts)
IEEE_ARITH2(sqrtt)720fcf5ef2aSThomas Huth IEEE_ARITH2(sqrtt)
721fcf5ef2aSThomas Huth IEEE_ARITH2(cvtst)
722fcf5ef2aSThomas Huth IEEE_ARITH2(cvtts)
723fcf5ef2aSThomas Huth 
724fcf5ef2aSThomas Huth static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11)
725fcf5ef2aSThomas Huth {
726fcf5ef2aSThomas Huth     TCGv vb, vc;
727fcf5ef2aSThomas Huth 
728fcf5ef2aSThomas Huth     /* No need to set flushzero, since we have an integer output.  */
729fcf5ef2aSThomas Huth     vb = gen_ieee_input(ctx, rb, fn11, 0);
730fcf5ef2aSThomas Huth     vc = dest_fpr(ctx, rc);
731fcf5ef2aSThomas Huth 
732fcf5ef2aSThomas Huth     /* Almost all integer conversions use cropped rounding;
733fcf5ef2aSThomas Huth        special case that.  */
734fcf5ef2aSThomas Huth     if ((fn11 & QUAL_RM_MASK) == QUAL_RM_C) {
735ad75a51eSRichard Henderson         gen_helper_cvttq_c(vc, tcg_env, vb);
736fcf5ef2aSThomas Huth     } else {
737fcf5ef2aSThomas Huth         gen_qual_roundmode(ctx, fn11);
738ad75a51eSRichard Henderson         gen_helper_cvttq(vc, tcg_env, vb);
739fcf5ef2aSThomas Huth     }
740fcf5ef2aSThomas Huth     gen_fp_exc_raise(rc, fn11);
741fcf5ef2aSThomas Huth }
742fcf5ef2aSThomas Huth 
gen_ieee_intcvt(DisasContext * ctx,void (* helper)(TCGv,TCGv_ptr,TCGv),int rb,int rc,int fn11)743fcf5ef2aSThomas Huth static void gen_ieee_intcvt(DisasContext *ctx,
744fcf5ef2aSThomas Huth                             void (*helper)(TCGv, TCGv_ptr, TCGv),
745fcf5ef2aSThomas Huth                             int rb, int rc, int fn11)
746fcf5ef2aSThomas Huth {
747fcf5ef2aSThomas Huth     TCGv vb, vc;
748fcf5ef2aSThomas Huth 
749fcf5ef2aSThomas Huth     gen_qual_roundmode(ctx, fn11);
750fcf5ef2aSThomas Huth     vb = load_fpr(ctx, rb);
751fcf5ef2aSThomas Huth     vc = dest_fpr(ctx, rc);
752fcf5ef2aSThomas Huth 
753fcf5ef2aSThomas Huth     /* The only exception that can be raised by integer conversion
754fcf5ef2aSThomas Huth        is inexact.  Thus we only need to worry about exceptions when
755fcf5ef2aSThomas Huth        inexact handling is requested.  */
756fcf5ef2aSThomas Huth     if (fn11 & QUAL_I) {
757ad75a51eSRichard Henderson         helper(vc, tcg_env, vb);
758fcf5ef2aSThomas Huth         gen_fp_exc_raise(rc, fn11);
759fcf5ef2aSThomas Huth     } else {
760ad75a51eSRichard Henderson         helper(vc, tcg_env, vb);
761fcf5ef2aSThomas Huth     }
762fcf5ef2aSThomas Huth }
763fcf5ef2aSThomas Huth 
764fcf5ef2aSThomas Huth #define IEEE_INTCVT(name)                                       \
765fcf5ef2aSThomas Huth static inline void glue(gen_, name)(DisasContext *ctx,          \
766fcf5ef2aSThomas Huth                                     int rb, int rc, int fn11)   \
767fcf5ef2aSThomas Huth {                                                               \
768fcf5ef2aSThomas Huth     gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11);      \
769fcf5ef2aSThomas Huth }
770fcf5ef2aSThomas Huth IEEE_INTCVT(cvtqs)
IEEE_INTCVT(cvtqt)771fcf5ef2aSThomas Huth IEEE_INTCVT(cvtqt)
772fcf5ef2aSThomas Huth 
773fcf5ef2aSThomas Huth static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask)
774fcf5ef2aSThomas Huth {
775904bd855SRichard Henderson     TCGv vmask = tcg_constant_i64(mask);
776fcf5ef2aSThomas Huth     TCGv tmp = tcg_temp_new_i64();
777fcf5ef2aSThomas Huth 
778fcf5ef2aSThomas Huth     if (inv_a) {
779fcf5ef2aSThomas Huth         tcg_gen_andc_i64(tmp, vmask, va);
780fcf5ef2aSThomas Huth     } else {
781fcf5ef2aSThomas Huth         tcg_gen_and_i64(tmp, va, vmask);
782fcf5ef2aSThomas Huth     }
783fcf5ef2aSThomas Huth 
784fcf5ef2aSThomas Huth     tcg_gen_andc_i64(vc, vb, vmask);
785fcf5ef2aSThomas Huth     tcg_gen_or_i64(vc, vc, tmp);
786fcf5ef2aSThomas Huth }
787fcf5ef2aSThomas Huth 
gen_ieee_arith3(DisasContext * ctx,void (* helper)(TCGv,TCGv_ptr,TCGv,TCGv),int ra,int rb,int rc,int fn11)788fcf5ef2aSThomas Huth static void gen_ieee_arith3(DisasContext *ctx,
789fcf5ef2aSThomas Huth                             void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
790fcf5ef2aSThomas Huth                             int ra, int rb, int rc, int fn11)
791fcf5ef2aSThomas Huth {
792fcf5ef2aSThomas Huth     TCGv va, vb, vc;
793fcf5ef2aSThomas Huth 
794fcf5ef2aSThomas Huth     gen_qual_roundmode(ctx, fn11);
795fcf5ef2aSThomas Huth     gen_qual_flushzero(ctx, fn11);
796fcf5ef2aSThomas Huth 
797fcf5ef2aSThomas Huth     va = gen_ieee_input(ctx, ra, fn11, 0);
798fcf5ef2aSThomas Huth     vb = gen_ieee_input(ctx, rb, fn11, 0);
799fcf5ef2aSThomas Huth     vc = dest_fpr(ctx, rc);
800ad75a51eSRichard Henderson     helper(vc, tcg_env, va, vb);
801fcf5ef2aSThomas Huth 
802fcf5ef2aSThomas Huth     gen_fp_exc_raise(rc, fn11);
803fcf5ef2aSThomas Huth }
804fcf5ef2aSThomas Huth 
805fcf5ef2aSThomas Huth #define IEEE_ARITH3(name)                                               \
806fcf5ef2aSThomas Huth static inline void glue(gen_, name)(DisasContext *ctx,                  \
807fcf5ef2aSThomas Huth                                     int ra, int rb, int rc, int fn11)   \
808fcf5ef2aSThomas Huth {                                                                       \
809fcf5ef2aSThomas Huth     gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11);          \
810fcf5ef2aSThomas Huth }
811fcf5ef2aSThomas Huth IEEE_ARITH3(adds)
IEEE_ARITH3(subs)812fcf5ef2aSThomas Huth IEEE_ARITH3(subs)
813fcf5ef2aSThomas Huth IEEE_ARITH3(muls)
814fcf5ef2aSThomas Huth IEEE_ARITH3(divs)
815fcf5ef2aSThomas Huth IEEE_ARITH3(addt)
816fcf5ef2aSThomas Huth IEEE_ARITH3(subt)
817fcf5ef2aSThomas Huth IEEE_ARITH3(mult)
818fcf5ef2aSThomas Huth IEEE_ARITH3(divt)
819fcf5ef2aSThomas Huth 
820fcf5ef2aSThomas Huth static void gen_ieee_compare(DisasContext *ctx,
821fcf5ef2aSThomas Huth                              void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
822fcf5ef2aSThomas Huth                              int ra, int rb, int rc, int fn11)
823fcf5ef2aSThomas Huth {
824fcf5ef2aSThomas Huth     TCGv va, vb, vc;
825fcf5ef2aSThomas Huth 
826fcf5ef2aSThomas Huth     va = gen_ieee_input(ctx, ra, fn11, 1);
827fcf5ef2aSThomas Huth     vb = gen_ieee_input(ctx, rb, fn11, 1);
828fcf5ef2aSThomas Huth     vc = dest_fpr(ctx, rc);
829ad75a51eSRichard Henderson     helper(vc, tcg_env, va, vb);
830fcf5ef2aSThomas Huth 
831fcf5ef2aSThomas Huth     gen_fp_exc_raise(rc, fn11);
832fcf5ef2aSThomas Huth }
833fcf5ef2aSThomas Huth 
834fcf5ef2aSThomas Huth #define IEEE_CMP3(name)                                                 \
835fcf5ef2aSThomas Huth static inline void glue(gen_, name)(DisasContext *ctx,                  \
836fcf5ef2aSThomas Huth                                     int ra, int rb, int rc, int fn11)   \
837fcf5ef2aSThomas Huth {                                                                       \
838fcf5ef2aSThomas Huth     gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11);         \
839fcf5ef2aSThomas Huth }
840fcf5ef2aSThomas Huth IEEE_CMP3(cmptun)
IEEE_CMP3(cmpteq)841fcf5ef2aSThomas Huth IEEE_CMP3(cmpteq)
842fcf5ef2aSThomas Huth IEEE_CMP3(cmptlt)
843fcf5ef2aSThomas Huth IEEE_CMP3(cmptle)
844fcf5ef2aSThomas Huth 
845fcf5ef2aSThomas Huth static inline uint64_t zapnot_mask(uint8_t lit)
846fcf5ef2aSThomas Huth {
847fcf5ef2aSThomas Huth     uint64_t mask = 0;
848fcf5ef2aSThomas Huth     int i;
849fcf5ef2aSThomas Huth 
850fcf5ef2aSThomas Huth     for (i = 0; i < 8; ++i) {
851fcf5ef2aSThomas Huth         if ((lit >> i) & 1) {
852fcf5ef2aSThomas Huth             mask |= 0xffull << (i * 8);
853fcf5ef2aSThomas Huth         }
854fcf5ef2aSThomas Huth     }
855fcf5ef2aSThomas Huth     return mask;
856fcf5ef2aSThomas Huth }
857fcf5ef2aSThomas Huth 
858fcf5ef2aSThomas Huth /* Implement zapnot with an immediate operand, which expands to some
859fcf5ef2aSThomas Huth    form of immediate AND.  This is a basic building block in the
860fcf5ef2aSThomas Huth    definition of many of the other byte manipulation instructions.  */
gen_zapnoti(TCGv dest,TCGv src,uint8_t lit)861fcf5ef2aSThomas Huth static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
862fcf5ef2aSThomas Huth {
863fcf5ef2aSThomas Huth     switch (lit) {
864fcf5ef2aSThomas Huth     case 0x00:
865fcf5ef2aSThomas Huth         tcg_gen_movi_i64(dest, 0);
866fcf5ef2aSThomas Huth         break;
867fcf5ef2aSThomas Huth     case 0x01:
868fcf5ef2aSThomas Huth         tcg_gen_ext8u_i64(dest, src);
869fcf5ef2aSThomas Huth         break;
870fcf5ef2aSThomas Huth     case 0x03:
871fcf5ef2aSThomas Huth         tcg_gen_ext16u_i64(dest, src);
872fcf5ef2aSThomas Huth         break;
873fcf5ef2aSThomas Huth     case 0x0f:
874fcf5ef2aSThomas Huth         tcg_gen_ext32u_i64(dest, src);
875fcf5ef2aSThomas Huth         break;
876fcf5ef2aSThomas Huth     case 0xff:
877fcf5ef2aSThomas Huth         tcg_gen_mov_i64(dest, src);
878fcf5ef2aSThomas Huth         break;
879fcf5ef2aSThomas Huth     default:
880fcf5ef2aSThomas Huth         tcg_gen_andi_i64(dest, src, zapnot_mask(lit));
881fcf5ef2aSThomas Huth         break;
882fcf5ef2aSThomas Huth     }
883fcf5ef2aSThomas Huth }
884fcf5ef2aSThomas Huth 
885fcf5ef2aSThomas Huth /* EXTWH, EXTLH, EXTQH */
gen_ext_h(DisasContext * ctx,TCGv vc,TCGv va,int rb,bool islit,uint8_t lit,uint8_t byte_mask)886fcf5ef2aSThomas Huth static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
887fcf5ef2aSThomas Huth                       uint8_t lit, uint8_t byte_mask)
888fcf5ef2aSThomas Huth {
889fcf5ef2aSThomas Huth     if (islit) {
890f49f1ae7SRichard Henderson         int pos = (64 - lit * 8) & 0x3f;
891f49f1ae7SRichard Henderson         int len = cto32(byte_mask) * 8;
892f49f1ae7SRichard Henderson         if (pos < len) {
893f49f1ae7SRichard Henderson             tcg_gen_deposit_z_i64(vc, va, pos, len - pos);
894f49f1ae7SRichard Henderson         } else {
895f49f1ae7SRichard Henderson             tcg_gen_movi_i64(vc, 0);
896f49f1ae7SRichard Henderson         }
897fcf5ef2aSThomas Huth     } else {
898fcf5ef2aSThomas Huth         TCGv tmp = tcg_temp_new();
899fcf5ef2aSThomas Huth         tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3);
900fcf5ef2aSThomas Huth         tcg_gen_neg_i64(tmp, tmp);
901fcf5ef2aSThomas Huth         tcg_gen_andi_i64(tmp, tmp, 0x3f);
902fcf5ef2aSThomas Huth         tcg_gen_shl_i64(vc, va, tmp);
903fcf5ef2aSThomas Huth     }
904fcf5ef2aSThomas Huth     gen_zapnoti(vc, vc, byte_mask);
905fcf5ef2aSThomas Huth }
906fcf5ef2aSThomas Huth 
907fcf5ef2aSThomas Huth /* EXTBL, EXTWL, EXTLL, EXTQL */
gen_ext_l(DisasContext * ctx,TCGv vc,TCGv va,int rb,bool islit,uint8_t lit,uint8_t byte_mask)908fcf5ef2aSThomas Huth static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
909fcf5ef2aSThomas Huth                       uint8_t lit, uint8_t byte_mask)
910fcf5ef2aSThomas Huth {
911fcf5ef2aSThomas Huth     if (islit) {
912f49f1ae7SRichard Henderson         int pos = (lit & 7) * 8;
913f49f1ae7SRichard Henderson         int len = cto32(byte_mask) * 8;
914f49f1ae7SRichard Henderson         if (pos + len >= 64) {
915f49f1ae7SRichard Henderson             len = 64 - pos;
916f49f1ae7SRichard Henderson         }
917f49f1ae7SRichard Henderson         tcg_gen_extract_i64(vc, va, pos, len);
918fcf5ef2aSThomas Huth     } else {
919fcf5ef2aSThomas Huth         TCGv tmp = tcg_temp_new();
920fcf5ef2aSThomas Huth         tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7);
921fcf5ef2aSThomas Huth         tcg_gen_shli_i64(tmp, tmp, 3);
922fcf5ef2aSThomas Huth         tcg_gen_shr_i64(vc, va, tmp);
923fcf5ef2aSThomas Huth         gen_zapnoti(vc, vc, byte_mask);
924fcf5ef2aSThomas Huth     }
925f49f1ae7SRichard Henderson }
926fcf5ef2aSThomas Huth 
927fcf5ef2aSThomas Huth /* INSWH, INSLH, INSQH */
gen_ins_h(DisasContext * ctx,TCGv vc,TCGv va,int rb,bool islit,uint8_t lit,uint8_t byte_mask)928fcf5ef2aSThomas Huth static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
929fcf5ef2aSThomas Huth                       uint8_t lit, uint8_t byte_mask)
930fcf5ef2aSThomas Huth {
931fcf5ef2aSThomas Huth     if (islit) {
932f49f1ae7SRichard Henderson         int pos = 64 - (lit & 7) * 8;
933f49f1ae7SRichard Henderson         int len = cto32(byte_mask) * 8;
934f49f1ae7SRichard Henderson         if (pos < len) {
935f49f1ae7SRichard Henderson             tcg_gen_extract_i64(vc, va, pos, len - pos);
936fcf5ef2aSThomas Huth         } else {
937f49f1ae7SRichard Henderson             tcg_gen_movi_i64(vc, 0);
938fcf5ef2aSThomas Huth         }
939fcf5ef2aSThomas Huth     } else {
940f49f1ae7SRichard Henderson         TCGv tmp = tcg_temp_new();
941fcf5ef2aSThomas Huth         TCGv shift = tcg_temp_new();
942fcf5ef2aSThomas Huth 
943f49f1ae7SRichard Henderson         /* The instruction description has us left-shift the byte mask
944f49f1ae7SRichard Henderson            and extract bits <15:8> and apply that zap at the end.  This
945f49f1ae7SRichard Henderson            is equivalent to simply performing the zap first and shifting
946f49f1ae7SRichard Henderson            afterward.  */
947f49f1ae7SRichard Henderson         gen_zapnoti(tmp, va, byte_mask);
948f49f1ae7SRichard Henderson 
949fcf5ef2aSThomas Huth         /* If (B & 7) == 0, we need to shift by 64 and leave a zero.  Do this
950fcf5ef2aSThomas Huth            portably by splitting the shift into two parts: shift_count-1 and 1.
951fcf5ef2aSThomas Huth            Arrange for the -1 by using ones-complement instead of
952fcf5ef2aSThomas Huth            twos-complement in the negation: ~(B * 8) & 63.  */
953fcf5ef2aSThomas Huth 
954fcf5ef2aSThomas Huth         tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
955fcf5ef2aSThomas Huth         tcg_gen_not_i64(shift, shift);
956fcf5ef2aSThomas Huth         tcg_gen_andi_i64(shift, shift, 0x3f);
957fcf5ef2aSThomas Huth 
958fcf5ef2aSThomas Huth         tcg_gen_shr_i64(vc, tmp, shift);
959fcf5ef2aSThomas Huth         tcg_gen_shri_i64(vc, vc, 1);
960fcf5ef2aSThomas Huth     }
961f49f1ae7SRichard Henderson }
962fcf5ef2aSThomas Huth 
963fcf5ef2aSThomas Huth /* INSBL, INSWL, INSLL, INSQL */
gen_ins_l(DisasContext * ctx,TCGv vc,TCGv va,int rb,bool islit,uint8_t lit,uint8_t byte_mask)964fcf5ef2aSThomas Huth static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
965fcf5ef2aSThomas Huth                       uint8_t lit, uint8_t byte_mask)
966fcf5ef2aSThomas Huth {
967f49f1ae7SRichard Henderson     if (islit) {
968f49f1ae7SRichard Henderson         int pos = (lit & 7) * 8;
969f49f1ae7SRichard Henderson         int len = cto32(byte_mask) * 8;
970f49f1ae7SRichard Henderson         if (pos + len > 64) {
971f49f1ae7SRichard Henderson             len = 64 - pos;
972f49f1ae7SRichard Henderson         }
973f49f1ae7SRichard Henderson         tcg_gen_deposit_z_i64(vc, va, pos, len);
974f49f1ae7SRichard Henderson     } else {
975fcf5ef2aSThomas Huth         TCGv tmp = tcg_temp_new();
976f49f1ae7SRichard Henderson         TCGv shift = tcg_temp_new();
977fcf5ef2aSThomas Huth 
978fcf5ef2aSThomas Huth         /* The instruction description has us left-shift the byte mask
979f49f1ae7SRichard Henderson            and extract bits <15:8> and apply that zap at the end.  This
980f49f1ae7SRichard Henderson            is equivalent to simply performing the zap first and shifting
981f49f1ae7SRichard Henderson            afterward.  */
982fcf5ef2aSThomas Huth         gen_zapnoti(tmp, va, byte_mask);
983fcf5ef2aSThomas Huth 
984fcf5ef2aSThomas Huth         tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
985fcf5ef2aSThomas Huth         tcg_gen_shli_i64(shift, shift, 3);
986fcf5ef2aSThomas Huth         tcg_gen_shl_i64(vc, tmp, shift);
987fcf5ef2aSThomas Huth     }
988f49f1ae7SRichard Henderson }
989fcf5ef2aSThomas Huth 
990fcf5ef2aSThomas Huth /* MSKWH, MSKLH, MSKQH */
gen_msk_h(DisasContext * ctx,TCGv vc,TCGv va,int rb,bool islit,uint8_t lit,uint8_t byte_mask)991fcf5ef2aSThomas Huth static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
992fcf5ef2aSThomas Huth                       uint8_t lit, uint8_t byte_mask)
993fcf5ef2aSThomas Huth {
994fcf5ef2aSThomas Huth     if (islit) {
995fcf5ef2aSThomas Huth         gen_zapnoti(vc, va, ~((byte_mask << (lit & 7)) >> 8));
996fcf5ef2aSThomas Huth     } else {
997fcf5ef2aSThomas Huth         TCGv shift = tcg_temp_new();
998fcf5ef2aSThomas Huth         TCGv mask = tcg_temp_new();
999fcf5ef2aSThomas Huth 
1000fcf5ef2aSThomas Huth         /* The instruction description is as above, where the byte_mask
1001fcf5ef2aSThomas Huth            is shifted left, and then we extract bits <15:8>.  This can be
1002fcf5ef2aSThomas Huth            emulated with a right-shift on the expanded byte mask.  This
1003fcf5ef2aSThomas Huth            requires extra care because for an input <2:0> == 0 we need a
1004fcf5ef2aSThomas Huth            shift of 64 bits in order to generate a zero.  This is done by
1005fcf5ef2aSThomas Huth            splitting the shift into two parts, the variable shift - 1
1006fcf5ef2aSThomas Huth            followed by a constant 1 shift.  The code we expand below is
1007fcf5ef2aSThomas Huth            equivalent to ~(B * 8) & 63.  */
1008fcf5ef2aSThomas Huth 
1009fcf5ef2aSThomas Huth         tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
1010fcf5ef2aSThomas Huth         tcg_gen_not_i64(shift, shift);
1011fcf5ef2aSThomas Huth         tcg_gen_andi_i64(shift, shift, 0x3f);
1012fcf5ef2aSThomas Huth         tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1013fcf5ef2aSThomas Huth         tcg_gen_shr_i64(mask, mask, shift);
1014fcf5ef2aSThomas Huth         tcg_gen_shri_i64(mask, mask, 1);
1015fcf5ef2aSThomas Huth 
1016fcf5ef2aSThomas Huth         tcg_gen_andc_i64(vc, va, mask);
1017fcf5ef2aSThomas Huth     }
1018fcf5ef2aSThomas Huth }
1019fcf5ef2aSThomas Huth 
1020fcf5ef2aSThomas Huth /* MSKBL, MSKWL, MSKLL, MSKQL */
gen_msk_l(DisasContext * ctx,TCGv vc,TCGv va,int rb,bool islit,uint8_t lit,uint8_t byte_mask)1021fcf5ef2aSThomas Huth static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1022fcf5ef2aSThomas Huth                       uint8_t lit, uint8_t byte_mask)
1023fcf5ef2aSThomas Huth {
1024fcf5ef2aSThomas Huth     if (islit) {
1025fcf5ef2aSThomas Huth         gen_zapnoti(vc, va, ~(byte_mask << (lit & 7)));
1026fcf5ef2aSThomas Huth     } else {
1027fcf5ef2aSThomas Huth         TCGv shift = tcg_temp_new();
1028fcf5ef2aSThomas Huth         TCGv mask = tcg_temp_new();
1029fcf5ef2aSThomas Huth 
1030fcf5ef2aSThomas Huth         tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1031fcf5ef2aSThomas Huth         tcg_gen_shli_i64(shift, shift, 3);
1032fcf5ef2aSThomas Huth         tcg_gen_movi_i64(mask, zapnot_mask(byte_mask));
1033fcf5ef2aSThomas Huth         tcg_gen_shl_i64(mask, mask, shift);
1034fcf5ef2aSThomas Huth 
1035fcf5ef2aSThomas Huth         tcg_gen_andc_i64(vc, va, mask);
1036fcf5ef2aSThomas Huth     }
1037fcf5ef2aSThomas Huth }
1038fcf5ef2aSThomas Huth 
gen_rx(DisasContext * ctx,int ra,int set)1039fcf5ef2aSThomas Huth static void gen_rx(DisasContext *ctx, int ra, int set)
1040fcf5ef2aSThomas Huth {
1041fcf5ef2aSThomas Huth     if (ra != 31) {
1042bcd2625dSRichard Henderson         ld_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT);
1043fcf5ef2aSThomas Huth     }
1044fcf5ef2aSThomas Huth 
1045492f85b9SRichard Henderson     st_flag_byte(tcg_constant_i64(set), ENV_FLAG_RX_SHIFT);
1046fcf5ef2aSThomas Huth }
1047fcf5ef2aSThomas Huth 
gen_call_pal(DisasContext * ctx,int palcode)10483de811c6SRichard Henderson static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
1049fcf5ef2aSThomas Huth {
1050fcf5ef2aSThomas Huth     /* We're emulating OSF/1 PALcode.  Many of these are trivial access
1051fcf5ef2aSThomas Huth        to internal cpu registers.  */
1052fcf5ef2aSThomas Huth 
1053fcf5ef2aSThomas Huth     /* Unprivileged PAL call */
1054fcf5ef2aSThomas Huth     if (palcode >= 0x80 && palcode < 0xC0) {
1055fcf5ef2aSThomas Huth         switch (palcode) {
1056fcf5ef2aSThomas Huth         case 0x86:
1057fcf5ef2aSThomas Huth             /* IMB */
1058fcf5ef2aSThomas Huth             /* No-op inside QEMU.  */
1059fcf5ef2aSThomas Huth             break;
1060fcf5ef2aSThomas Huth         case 0x9E:
1061fcf5ef2aSThomas Huth             /* RDUNIQUE */
1062ad75a51eSRichard Henderson             tcg_gen_ld_i64(ctx->ir[IR_V0], tcg_env,
1063fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, unique));
1064fcf5ef2aSThomas Huth             break;
1065fcf5ef2aSThomas Huth         case 0x9F:
1066fcf5ef2aSThomas Huth             /* WRUNIQUE */
1067ad75a51eSRichard Henderson             tcg_gen_st_i64(ctx->ir[IR_A0], tcg_env,
1068fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, unique));
1069fcf5ef2aSThomas Huth             break;
1070fcf5ef2aSThomas Huth         default:
1071fcf5ef2aSThomas Huth             palcode &= 0xbf;
1072fcf5ef2aSThomas Huth             goto do_call_pal;
1073fcf5ef2aSThomas Huth         }
10743de811c6SRichard Henderson         return DISAS_NEXT;
1075fcf5ef2aSThomas Huth     }
1076fcf5ef2aSThomas Huth 
1077fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
1078fcf5ef2aSThomas Huth     /* Privileged PAL code */
1079bcd2625dSRichard Henderson     if (palcode < 0x40 && (ctx->tbflags & ENV_FLAG_PS_USER) == 0) {
1080fcf5ef2aSThomas Huth         switch (palcode) {
1081fcf5ef2aSThomas Huth         case 0x01:
1082fcf5ef2aSThomas Huth             /* CFLUSH */
1083fcf5ef2aSThomas Huth             /* No-op inside QEMU.  */
1084fcf5ef2aSThomas Huth             break;
1085fcf5ef2aSThomas Huth         case 0x02:
1086fcf5ef2aSThomas Huth             /* DRAINA */
1087fcf5ef2aSThomas Huth             /* No-op inside QEMU.  */
1088fcf5ef2aSThomas Huth             break;
1089fcf5ef2aSThomas Huth         case 0x2D:
1090fcf5ef2aSThomas Huth             /* WRVPTPTR */
1091ad75a51eSRichard Henderson             tcg_gen_st_i64(ctx->ir[IR_A0], tcg_env,
1092fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, vptptr));
1093fcf5ef2aSThomas Huth             break;
1094fcf5ef2aSThomas Huth         case 0x31:
1095fcf5ef2aSThomas Huth             /* WRVAL */
1096ad75a51eSRichard Henderson             tcg_gen_st_i64(ctx->ir[IR_A0], tcg_env,
1097fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, sysval));
1098fcf5ef2aSThomas Huth             break;
1099fcf5ef2aSThomas Huth         case 0x32:
1100fcf5ef2aSThomas Huth             /* RDVAL */
1101ad75a51eSRichard Henderson             tcg_gen_ld_i64(ctx->ir[IR_V0], tcg_env,
1102fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, sysval));
1103fcf5ef2aSThomas Huth             break;
1104fcf5ef2aSThomas Huth 
1105bec5e2b9SRichard Henderson         case 0x35:
1106fcf5ef2aSThomas Huth             /* SWPIPL */
1107fcf5ef2aSThomas Huth             /* Note that we already know we're in kernel mode, so we know
1108fcf5ef2aSThomas Huth                that PS only contains the 3 IPL bits.  */
1109bcd2625dSRichard Henderson             ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT);
1110fcf5ef2aSThomas Huth 
1111fcf5ef2aSThomas Huth             /* But make sure and store only the 3 IPL bits from the user.  */
1112f401c032SRichard Henderson             {
1113f401c032SRichard Henderson                 TCGv tmp = tcg_temp_new();
1114fcf5ef2aSThomas Huth                 tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK);
1115bcd2625dSRichard Henderson                 st_flag_byte(tmp, ENV_FLAG_PS_SHIFT);
1116f401c032SRichard Henderson             }
111754e1d4edSRichard Henderson 
111854e1d4edSRichard Henderson             /* Allow interrupts to be recognized right away.  */
1119c5f80657SRichard Henderson             tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
11203de811c6SRichard Henderson             return DISAS_PC_UPDATED_NOCHAIN;
1121fcf5ef2aSThomas Huth 
1122fcf5ef2aSThomas Huth         case 0x36:
1123fcf5ef2aSThomas Huth             /* RDPS */
1124bcd2625dSRichard Henderson             ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT);
1125fcf5ef2aSThomas Huth             break;
1126bcd2625dSRichard Henderson 
1127fcf5ef2aSThomas Huth         case 0x38:
1128fcf5ef2aSThomas Huth             /* WRUSP */
1129ad75a51eSRichard Henderson             tcg_gen_st_i64(ctx->ir[IR_A0], tcg_env,
1130fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, usp));
1131fcf5ef2aSThomas Huth             break;
1132fcf5ef2aSThomas Huth         case 0x3A:
1133fcf5ef2aSThomas Huth             /* RDUSP */
1134ad75a51eSRichard Henderson             tcg_gen_ld_i64(ctx->ir[IR_V0], tcg_env,
1135fcf5ef2aSThomas Huth                            offsetof(CPUAlphaState, usp));
1136fcf5ef2aSThomas Huth             break;
1137fcf5ef2aSThomas Huth         case 0x3C:
1138fcf5ef2aSThomas Huth             /* WHAMI */
1139ad75a51eSRichard Henderson             tcg_gen_ld32s_i64(ctx->ir[IR_V0], tcg_env,
1140fcf5ef2aSThomas Huth                 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
1141fcf5ef2aSThomas Huth             break;
1142fcf5ef2aSThomas Huth 
1143bec5e2b9SRichard Henderson         case 0x3E:
1144bec5e2b9SRichard Henderson             /* WTINT */
1145ad75a51eSRichard Henderson             tcg_gen_st_i32(tcg_constant_i32(1), tcg_env,
1146904bd855SRichard Henderson                            -offsetof(AlphaCPU, env) +
1147bec5e2b9SRichard Henderson                            offsetof(CPUState, halted));
1148bec5e2b9SRichard Henderson             tcg_gen_movi_i64(ctx->ir[IR_V0], 0);
1149bec5e2b9SRichard Henderson             return gen_excp(ctx, EXCP_HALTED, 0);
1150bec5e2b9SRichard Henderson 
1151fcf5ef2aSThomas Huth         default:
1152fcf5ef2aSThomas Huth             palcode &= 0x3f;
1153fcf5ef2aSThomas Huth             goto do_call_pal;
1154fcf5ef2aSThomas Huth         }
11553de811c6SRichard Henderson         return DISAS_NEXT;
1156fcf5ef2aSThomas Huth     }
1157fcf5ef2aSThomas Huth #endif
1158fcf5ef2aSThomas Huth     return gen_invalid(ctx);
1159fcf5ef2aSThomas Huth 
1160fcf5ef2aSThomas Huth  do_call_pal:
1161fcf5ef2aSThomas Huth #ifdef CONFIG_USER_ONLY
1162fcf5ef2aSThomas Huth     return gen_excp(ctx, EXCP_CALL_PAL, palcode);
1163fcf5ef2aSThomas Huth #else
1164fcf5ef2aSThomas Huth     {
1165fcf5ef2aSThomas Huth         TCGv tmp = tcg_temp_new();
1166c5f80657SRichard Henderson         uint64_t exc_addr = ctx->base.pc_next;
1167fcf5ef2aSThomas Huth         uint64_t entry = ctx->palbr;
1168fcf5ef2aSThomas Huth 
1169bcd2625dSRichard Henderson         if (ctx->tbflags & ENV_FLAG_PAL_MODE) {
1170fcf5ef2aSThomas Huth             exc_addr |= 1;
1171fcf5ef2aSThomas Huth         } else {
1172fcf5ef2aSThomas Huth             tcg_gen_movi_i64(tmp, 1);
1173bcd2625dSRichard Henderson             st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
1174fcf5ef2aSThomas Huth         }
1175fcf5ef2aSThomas Huth 
1176fcf5ef2aSThomas Huth         tcg_gen_movi_i64(tmp, exc_addr);
1177ad75a51eSRichard Henderson         tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUAlphaState, exc_addr));
1178fcf5ef2aSThomas Huth 
1179fcf5ef2aSThomas Huth         entry += (palcode & 0x80
1180fcf5ef2aSThomas Huth                   ? 0x2000 + (palcode - 0x80) * 64
1181fcf5ef2aSThomas Huth                   : 0x1000 + palcode * 64);
1182fcf5ef2aSThomas Huth 
1183fcf5ef2aSThomas Huth         tcg_gen_movi_i64(cpu_pc, entry);
11843de811c6SRichard Henderson         return DISAS_PC_UPDATED;
1185fcf5ef2aSThomas Huth     }
1186fcf5ef2aSThomas Huth #endif
1187fcf5ef2aSThomas Huth }
1188fcf5ef2aSThomas Huth 
1189fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
1190fcf5ef2aSThomas Huth 
1191fcf5ef2aSThomas Huth #define PR_LONG         0x200000
1192fcf5ef2aSThomas Huth 
cpu_pr_data(int pr)1193fcf5ef2aSThomas Huth static int cpu_pr_data(int pr)
1194fcf5ef2aSThomas Huth {
1195fcf5ef2aSThomas Huth     switch (pr) {
1196fcf5ef2aSThomas Huth     case  2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1197fcf5ef2aSThomas Huth     case  3: return offsetof(CPUAlphaState, trap_arg0);
1198fcf5ef2aSThomas Huth     case  4: return offsetof(CPUAlphaState, trap_arg1);
1199fcf5ef2aSThomas Huth     case  5: return offsetof(CPUAlphaState, trap_arg2);
1200fcf5ef2aSThomas Huth     case  6: return offsetof(CPUAlphaState, exc_addr);
1201fcf5ef2aSThomas Huth     case  7: return offsetof(CPUAlphaState, palbr);
1202fcf5ef2aSThomas Huth     case  8: return offsetof(CPUAlphaState, ptbr);
1203fcf5ef2aSThomas Huth     case  9: return offsetof(CPUAlphaState, vptptr);
1204fcf5ef2aSThomas Huth     case 10: return offsetof(CPUAlphaState, unique);
1205fcf5ef2aSThomas Huth     case 11: return offsetof(CPUAlphaState, sysval);
1206fcf5ef2aSThomas Huth     case 12: return offsetof(CPUAlphaState, usp);
1207fcf5ef2aSThomas Huth 
1208fcf5ef2aSThomas Huth     case 40 ... 63:
1209fcf5ef2aSThomas Huth         return offsetof(CPUAlphaState, scratch[pr - 40]);
1210fcf5ef2aSThomas Huth 
1211fcf5ef2aSThomas Huth     case 251:
1212fcf5ef2aSThomas Huth         return offsetof(CPUAlphaState, alarm_expire);
1213fcf5ef2aSThomas Huth     }
1214fcf5ef2aSThomas Huth     return 0;
1215fcf5ef2aSThomas Huth }
1216fcf5ef2aSThomas Huth 
gen_mfpr(DisasContext * ctx,TCGv va,int regno)12173de811c6SRichard Henderson static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno)
1218fcf5ef2aSThomas Huth {
1219fcf5ef2aSThomas Huth     void (*helper)(TCGv);
1220fcf5ef2aSThomas Huth     int data;
1221fcf5ef2aSThomas Huth 
1222fcf5ef2aSThomas Huth     switch (regno) {
1223fcf5ef2aSThomas Huth     case 32 ... 39:
1224fcf5ef2aSThomas Huth         /* Accessing the "non-shadow" general registers.  */
1225fcf5ef2aSThomas Huth         regno = regno == 39 ? 25 : regno - 32 + 8;
1226fcf5ef2aSThomas Huth         tcg_gen_mov_i64(va, cpu_std_ir[regno]);
1227fcf5ef2aSThomas Huth         break;
1228fcf5ef2aSThomas Huth 
1229fcf5ef2aSThomas Huth     case 250: /* WALLTIME */
1230fcf5ef2aSThomas Huth         helper = gen_helper_get_walltime;
1231fcf5ef2aSThomas Huth         goto do_helper;
1232fcf5ef2aSThomas Huth     case 249: /* VMTIME */
1233fcf5ef2aSThomas Huth         helper = gen_helper_get_vmtime;
1234fcf5ef2aSThomas Huth     do_helper:
1235dfd1b812SRichard Henderson         if (translator_io_start(&ctx->base)) {
1236fcf5ef2aSThomas Huth             helper(va);
12373de811c6SRichard Henderson             return DISAS_PC_STALE;
1238fcf5ef2aSThomas Huth         } else {
1239fcf5ef2aSThomas Huth             helper(va);
1240fcf5ef2aSThomas Huth         }
1241fcf5ef2aSThomas Huth         break;
1242fcf5ef2aSThomas Huth 
1243bcd2625dSRichard Henderson     case 0: /* PS */
1244bcd2625dSRichard Henderson         ld_flag_byte(va, ENV_FLAG_PS_SHIFT);
1245bcd2625dSRichard Henderson         break;
1246bcd2625dSRichard Henderson     case 1: /* FEN */
1247bcd2625dSRichard Henderson         ld_flag_byte(va, ENV_FLAG_FEN_SHIFT);
1248bcd2625dSRichard Henderson         break;
1249bcd2625dSRichard Henderson 
1250fcf5ef2aSThomas Huth     default:
1251fcf5ef2aSThomas Huth         /* The basic registers are data only, and unknown registers
1252fcf5ef2aSThomas Huth            are read-zero, write-ignore.  */
1253fcf5ef2aSThomas Huth         data = cpu_pr_data(regno);
1254fcf5ef2aSThomas Huth         if (data == 0) {
1255fcf5ef2aSThomas Huth             tcg_gen_movi_i64(va, 0);
1256fcf5ef2aSThomas Huth         } else if (data & PR_LONG) {
1257ad75a51eSRichard Henderson             tcg_gen_ld32s_i64(va, tcg_env, data & ~PR_LONG);
1258fcf5ef2aSThomas Huth         } else {
1259ad75a51eSRichard Henderson             tcg_gen_ld_i64(va, tcg_env, data);
1260fcf5ef2aSThomas Huth         }
1261fcf5ef2aSThomas Huth         break;
1262fcf5ef2aSThomas Huth     }
1263fcf5ef2aSThomas Huth 
12643de811c6SRichard Henderson     return DISAS_NEXT;
1265fcf5ef2aSThomas Huth }
1266fcf5ef2aSThomas Huth 
gen_mtpr(DisasContext * ctx,TCGv vb,int regno)12673de811c6SRichard Henderson static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
1268fcf5ef2aSThomas Huth {
1269fcf5ef2aSThomas Huth     int data;
1270ef951ee3SPavel Dovgalyuk     DisasJumpType ret = DISAS_NEXT;
1271fcf5ef2aSThomas Huth 
1272fcf5ef2aSThomas Huth     switch (regno) {
1273fcf5ef2aSThomas Huth     case 255:
1274fcf5ef2aSThomas Huth         /* TBIA */
1275ad75a51eSRichard Henderson         gen_helper_tbia(tcg_env);
1276fcf5ef2aSThomas Huth         break;
1277fcf5ef2aSThomas Huth 
1278fcf5ef2aSThomas Huth     case 254:
1279fcf5ef2aSThomas Huth         /* TBIS */
1280ad75a51eSRichard Henderson         gen_helper_tbis(tcg_env, vb);
1281fcf5ef2aSThomas Huth         break;
1282fcf5ef2aSThomas Huth 
1283fcf5ef2aSThomas Huth     case 253:
1284fcf5ef2aSThomas Huth         /* WAIT */
1285ad75a51eSRichard Henderson         tcg_gen_st_i32(tcg_constant_i32(1), tcg_env,
1286904bd855SRichard Henderson                        -offsetof(AlphaCPU, env) + offsetof(CPUState, halted));
1287bec5e2b9SRichard Henderson         return gen_excp(ctx, EXCP_HALTED, 0);
1288fcf5ef2aSThomas Huth 
1289fcf5ef2aSThomas Huth     case 252:
1290fcf5ef2aSThomas Huth         /* HALT */
1291fcf5ef2aSThomas Huth         gen_helper_halt(vb);
12923de811c6SRichard Henderson         return DISAS_PC_STALE;
1293fcf5ef2aSThomas Huth 
1294fcf5ef2aSThomas Huth     case 251:
1295fcf5ef2aSThomas Huth         /* ALARM */
1296dfd1b812SRichard Henderson         if (translator_io_start(&ctx->base)) {
1297ef951ee3SPavel Dovgalyuk             ret = DISAS_PC_STALE;
1298ef951ee3SPavel Dovgalyuk         }
1299ad75a51eSRichard Henderson         gen_helper_set_alarm(tcg_env, vb);
1300fcf5ef2aSThomas Huth         break;
1301fcf5ef2aSThomas Huth 
1302fcf5ef2aSThomas Huth     case 7:
1303fcf5ef2aSThomas Huth         /* PALBR */
1304ad75a51eSRichard Henderson         tcg_gen_st_i64(vb, tcg_env, offsetof(CPUAlphaState, palbr));
1305fcf5ef2aSThomas Huth         /* Changing the PAL base register implies un-chaining all of the TBs
1306fcf5ef2aSThomas Huth            that ended with a CALL_PAL.  Since the base register usually only
1307fcf5ef2aSThomas Huth            changes during boot, flushing everything works well.  */
1308ad75a51eSRichard Henderson         gen_helper_tb_flush(tcg_env);
13093de811c6SRichard Henderson         return DISAS_PC_STALE;
1310fcf5ef2aSThomas Huth 
1311fcf5ef2aSThomas Huth     case 32 ... 39:
1312fcf5ef2aSThomas Huth         /* Accessing the "non-shadow" general registers.  */
1313fcf5ef2aSThomas Huth         regno = regno == 39 ? 25 : regno - 32 + 8;
1314fcf5ef2aSThomas Huth         tcg_gen_mov_i64(cpu_std_ir[regno], vb);
1315fcf5ef2aSThomas Huth         break;
1316fcf5ef2aSThomas Huth 
1317bcd2625dSRichard Henderson     case 0: /* PS */
1318bcd2625dSRichard Henderson         st_flag_byte(vb, ENV_FLAG_PS_SHIFT);
1319bcd2625dSRichard Henderson         break;
1320bcd2625dSRichard Henderson     case 1: /* FEN */
1321bcd2625dSRichard Henderson         st_flag_byte(vb, ENV_FLAG_FEN_SHIFT);
1322bcd2625dSRichard Henderson         break;
1323bcd2625dSRichard Henderson 
1324fcf5ef2aSThomas Huth     default:
1325fcf5ef2aSThomas Huth         /* The basic registers are data only, and unknown registers
1326fcf5ef2aSThomas Huth            are read-zero, write-ignore.  */
1327fcf5ef2aSThomas Huth         data = cpu_pr_data(regno);
1328fcf5ef2aSThomas Huth         if (data != 0) {
1329bcd2625dSRichard Henderson             if (data & PR_LONG) {
1330ad75a51eSRichard Henderson                 tcg_gen_st32_i64(vb, tcg_env, data & ~PR_LONG);
1331fcf5ef2aSThomas Huth             } else {
1332ad75a51eSRichard Henderson                 tcg_gen_st_i64(vb, tcg_env, data);
1333fcf5ef2aSThomas Huth             }
1334fcf5ef2aSThomas Huth         }
1335fcf5ef2aSThomas Huth         break;
1336fcf5ef2aSThomas Huth     }
1337fcf5ef2aSThomas Huth 
1338ef951ee3SPavel Dovgalyuk     return ret;
1339fcf5ef2aSThomas Huth }
1340fcf5ef2aSThomas Huth #endif /* !USER_ONLY*/
1341fcf5ef2aSThomas Huth 
1342fcf5ef2aSThomas Huth #define REQUIRE_NO_LIT                          \
1343fcf5ef2aSThomas Huth     do {                                        \
1344fcf5ef2aSThomas Huth         if (real_islit) {                       \
1345fcf5ef2aSThomas Huth             goto invalid_opc;                   \
1346fcf5ef2aSThomas Huth         }                                       \
1347fcf5ef2aSThomas Huth     } while (0)
1348fcf5ef2aSThomas Huth 
1349c6d41b36SRichard Henderson #define REQUIRE_AMASK(FLAG)                     \
1350c6d41b36SRichard Henderson     do {                                        \
1351c6d41b36SRichard Henderson         if ((ctx->amask & AMASK_##FLAG) == 0) { \
1352c6d41b36SRichard Henderson             goto invalid_opc;                   \
1353c6d41b36SRichard Henderson         }                                       \
1354c6d41b36SRichard Henderson     } while (0)
1355c6d41b36SRichard Henderson 
1356fcf5ef2aSThomas Huth #define REQUIRE_TB_FLAG(FLAG)                   \
1357fcf5ef2aSThomas Huth     do {                                        \
1358489a0e64SRichard Henderson         if ((ctx->tbflags & (FLAG)) == 0) {     \
1359fcf5ef2aSThomas Huth             goto invalid_opc;                   \
1360fcf5ef2aSThomas Huth         }                                       \
1361fcf5ef2aSThomas Huth     } while (0)
1362fcf5ef2aSThomas Huth 
1363fcf5ef2aSThomas Huth #define REQUIRE_REG_31(WHICH)                   \
1364fcf5ef2aSThomas Huth     do {                                        \
1365fcf5ef2aSThomas Huth         if (WHICH != 31) {                      \
1366fcf5ef2aSThomas Huth             goto invalid_opc;                   \
1367fcf5ef2aSThomas Huth         }                                       \
1368fcf5ef2aSThomas Huth     } while (0)
1369fcf5ef2aSThomas Huth 
13709d14a042SRichard Henderson #define REQUIRE_FEN                             \
13719d14a042SRichard Henderson     do {                                        \
13729d14a042SRichard Henderson         if (!(ctx->tbflags & ENV_FLAG_FEN)) {   \
13739d14a042SRichard Henderson             goto raise_fen;                     \
13749d14a042SRichard Henderson         }                                       \
13759d14a042SRichard Henderson     } while (0)
13769d14a042SRichard Henderson 
translate_one(DisasContext * ctx,uint32_t insn)13773de811c6SRichard Henderson static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
1378fcf5ef2aSThomas Huth {
1379fcf5ef2aSThomas Huth     int32_t disp21, disp16, disp12 __attribute__((unused));
1380fcf5ef2aSThomas Huth     uint16_t fn11;
1381fcf5ef2aSThomas Huth     uint8_t opc, ra, rb, rc, fpfn, fn7, lit;
1382fcf5ef2aSThomas Huth     bool islit, real_islit;
1383fcf5ef2aSThomas Huth     TCGv va, vb, vc, tmp, tmp2;
1384fcf5ef2aSThomas Huth     TCGv_i32 t32;
13853de811c6SRichard Henderson     DisasJumpType ret;
1386fcf5ef2aSThomas Huth 
1387fcf5ef2aSThomas Huth     /* Decode all instruction fields */
1388fcf5ef2aSThomas Huth     opc = extract32(insn, 26, 6);
1389fcf5ef2aSThomas Huth     ra = extract32(insn, 21, 5);
1390fcf5ef2aSThomas Huth     rb = extract32(insn, 16, 5);
1391fcf5ef2aSThomas Huth     rc = extract32(insn, 0, 5);
1392fcf5ef2aSThomas Huth     real_islit = islit = extract32(insn, 12, 1);
1393fcf5ef2aSThomas Huth     lit = extract32(insn, 13, 8);
1394fcf5ef2aSThomas Huth 
1395fcf5ef2aSThomas Huth     disp21 = sextract32(insn, 0, 21);
1396fcf5ef2aSThomas Huth     disp16 = sextract32(insn, 0, 16);
1397fcf5ef2aSThomas Huth     disp12 = sextract32(insn, 0, 12);
1398fcf5ef2aSThomas Huth 
1399fcf5ef2aSThomas Huth     fn11 = extract32(insn, 5, 11);
1400fcf5ef2aSThomas Huth     fpfn = extract32(insn, 5, 6);
1401fcf5ef2aSThomas Huth     fn7 = extract32(insn, 5, 7);
1402fcf5ef2aSThomas Huth 
1403fcf5ef2aSThomas Huth     if (rb == 31 && !islit) {
1404fcf5ef2aSThomas Huth         islit = true;
1405fcf5ef2aSThomas Huth         lit = 0;
1406fcf5ef2aSThomas Huth     }
1407fcf5ef2aSThomas Huth 
14083de811c6SRichard Henderson     ret = DISAS_NEXT;
1409fcf5ef2aSThomas Huth     switch (opc) {
1410fcf5ef2aSThomas Huth     case 0x00:
1411fcf5ef2aSThomas Huth         /* CALL_PAL */
1412fcf5ef2aSThomas Huth         ret = gen_call_pal(ctx, insn & 0x03ffffff);
1413fcf5ef2aSThomas Huth         break;
1414fcf5ef2aSThomas Huth     case 0x01:
1415fcf5ef2aSThomas Huth         /* OPC01 */
1416fcf5ef2aSThomas Huth         goto invalid_opc;
1417fcf5ef2aSThomas Huth     case 0x02:
1418fcf5ef2aSThomas Huth         /* OPC02 */
1419fcf5ef2aSThomas Huth         goto invalid_opc;
1420fcf5ef2aSThomas Huth     case 0x03:
1421fcf5ef2aSThomas Huth         /* OPC03 */
1422fcf5ef2aSThomas Huth         goto invalid_opc;
1423fcf5ef2aSThomas Huth     case 0x04:
1424fcf5ef2aSThomas Huth         /* OPC04 */
1425fcf5ef2aSThomas Huth         goto invalid_opc;
1426fcf5ef2aSThomas Huth     case 0x05:
1427fcf5ef2aSThomas Huth         /* OPC05 */
1428fcf5ef2aSThomas Huth         goto invalid_opc;
1429fcf5ef2aSThomas Huth     case 0x06:
1430fcf5ef2aSThomas Huth         /* OPC06 */
1431fcf5ef2aSThomas Huth         goto invalid_opc;
1432fcf5ef2aSThomas Huth     case 0x07:
1433fcf5ef2aSThomas Huth         /* OPC07 */
1434fcf5ef2aSThomas Huth         goto invalid_opc;
1435fcf5ef2aSThomas Huth 
1436fcf5ef2aSThomas Huth     case 0x09:
1437fcf5ef2aSThomas Huth         /* LDAH */
1438fcf5ef2aSThomas Huth         disp16 = (uint32_t)disp16 << 16;
1439fcf5ef2aSThomas Huth         /* fall through */
1440fcf5ef2aSThomas Huth     case 0x08:
1441fcf5ef2aSThomas Huth         /* LDA */
1442fcf5ef2aSThomas Huth         va = dest_gpr(ctx, ra);
1443fcf5ef2aSThomas Huth         /* It's worth special-casing immediate loads.  */
1444fcf5ef2aSThomas Huth         if (rb == 31) {
1445fcf5ef2aSThomas Huth             tcg_gen_movi_i64(va, disp16);
1446fcf5ef2aSThomas Huth         } else {
1447fcf5ef2aSThomas Huth             tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16);
1448fcf5ef2aSThomas Huth         }
1449fcf5ef2aSThomas Huth         break;
1450fcf5ef2aSThomas Huth 
1451fcf5ef2aSThomas Huth     case 0x0A:
1452fcf5ef2aSThomas Huth         /* LDBU */
1453c6d41b36SRichard Henderson         REQUIRE_AMASK(BWX);
14545ffcb334SRichard Henderson         gen_load_int(ctx, ra, rb, disp16, MO_UB, 0, 0);
1455fcf5ef2aSThomas Huth         break;
1456fcf5ef2aSThomas Huth     case 0x0B:
1457fcf5ef2aSThomas Huth         /* LDQ_U */
1458fc313c64SFrédéric Pétrot         gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 1, 0);
1459fcf5ef2aSThomas Huth         break;
1460fcf5ef2aSThomas Huth     case 0x0C:
1461fcf5ef2aSThomas Huth         /* LDWU */
1462c6d41b36SRichard Henderson         REQUIRE_AMASK(BWX);
14635ffcb334SRichard Henderson         gen_load_int(ctx, ra, rb, disp16, MO_LEUW, 0, 0);
1464fcf5ef2aSThomas Huth         break;
1465fcf5ef2aSThomas Huth     case 0x0D:
1466fcf5ef2aSThomas Huth         /* STW */
1467c6d41b36SRichard Henderson         REQUIRE_AMASK(BWX);
14685ffcb334SRichard Henderson         gen_store_int(ctx, ra, rb, disp16, MO_LEUW, 0);
1469fcf5ef2aSThomas Huth         break;
1470fcf5ef2aSThomas Huth     case 0x0E:
1471fcf5ef2aSThomas Huth         /* STB */
1472c6d41b36SRichard Henderson         REQUIRE_AMASK(BWX);
14735ffcb334SRichard Henderson         gen_store_int(ctx, ra, rb, disp16, MO_UB, 0);
1474fcf5ef2aSThomas Huth         break;
1475fcf5ef2aSThomas Huth     case 0x0F:
1476fcf5ef2aSThomas Huth         /* STQ_U */
1477fc313c64SFrédéric Pétrot         gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 1);
1478fcf5ef2aSThomas Huth         break;
1479fcf5ef2aSThomas Huth 
1480fcf5ef2aSThomas Huth     case 0x10:
1481fcf5ef2aSThomas Huth         vc = dest_gpr(ctx, rc);
1482fcf5ef2aSThomas Huth         vb = load_gpr_lit(ctx, rb, lit, islit);
1483fcf5ef2aSThomas Huth 
1484fcf5ef2aSThomas Huth         if (ra == 31) {
1485fcf5ef2aSThomas Huth             if (fn7 == 0x00) {
1486fcf5ef2aSThomas Huth                 /* Special case ADDL as SEXTL.  */
1487fcf5ef2aSThomas Huth                 tcg_gen_ext32s_i64(vc, vb);
1488fcf5ef2aSThomas Huth                 break;
1489fcf5ef2aSThomas Huth             }
1490fcf5ef2aSThomas Huth             if (fn7 == 0x29) {
1491fcf5ef2aSThomas Huth                 /* Special case SUBQ as NEGQ.  */
1492fcf5ef2aSThomas Huth                 tcg_gen_neg_i64(vc, vb);
1493fcf5ef2aSThomas Huth                 break;
1494fcf5ef2aSThomas Huth             }
1495fcf5ef2aSThomas Huth         }
1496fcf5ef2aSThomas Huth 
1497fcf5ef2aSThomas Huth         va = load_gpr(ctx, ra);
1498fcf5ef2aSThomas Huth         switch (fn7) {
1499fcf5ef2aSThomas Huth         case 0x00:
1500fcf5ef2aSThomas Huth             /* ADDL */
1501fcf5ef2aSThomas Huth             tcg_gen_add_i64(vc, va, vb);
1502fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, vc);
1503fcf5ef2aSThomas Huth             break;
1504fcf5ef2aSThomas Huth         case 0x02:
1505fcf5ef2aSThomas Huth             /* S4ADDL */
1506fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1507fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 2);
1508fcf5ef2aSThomas Huth             tcg_gen_add_i64(tmp, tmp, vb);
1509fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1510fcf5ef2aSThomas Huth             break;
1511fcf5ef2aSThomas Huth         case 0x09:
1512fcf5ef2aSThomas Huth             /* SUBL */
1513fcf5ef2aSThomas Huth             tcg_gen_sub_i64(vc, va, vb);
1514fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, vc);
1515fcf5ef2aSThomas Huth             break;
1516fcf5ef2aSThomas Huth         case 0x0B:
1517fcf5ef2aSThomas Huth             /* S4SUBL */
1518fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1519fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 2);
1520fcf5ef2aSThomas Huth             tcg_gen_sub_i64(tmp, tmp, vb);
1521fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1522fcf5ef2aSThomas Huth             break;
1523fcf5ef2aSThomas Huth         case 0x0F:
1524fcf5ef2aSThomas Huth             /* CMPBGE */
1525fcf5ef2aSThomas Huth             if (ra == 31) {
1526fcf5ef2aSThomas Huth                 /* Special case 0 >= X as X == 0.  */
1527fcf5ef2aSThomas Huth                 gen_helper_cmpbe0(vc, vb);
1528fcf5ef2aSThomas Huth             } else {
1529fcf5ef2aSThomas Huth                 gen_helper_cmpbge(vc, va, vb);
1530fcf5ef2aSThomas Huth             }
1531fcf5ef2aSThomas Huth             break;
1532fcf5ef2aSThomas Huth         case 0x12:
1533fcf5ef2aSThomas Huth             /* S8ADDL */
1534fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1535fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 3);
1536fcf5ef2aSThomas Huth             tcg_gen_add_i64(tmp, tmp, vb);
1537fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1538fcf5ef2aSThomas Huth             break;
1539fcf5ef2aSThomas Huth         case 0x1B:
1540fcf5ef2aSThomas Huth             /* S8SUBL */
1541fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1542fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 3);
1543fcf5ef2aSThomas Huth             tcg_gen_sub_i64(tmp, tmp, vb);
1544fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1545fcf5ef2aSThomas Huth             break;
1546fcf5ef2aSThomas Huth         case 0x1D:
1547fcf5ef2aSThomas Huth             /* CMPULT */
1548fcf5ef2aSThomas Huth             tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb);
1549fcf5ef2aSThomas Huth             break;
1550fcf5ef2aSThomas Huth         case 0x20:
1551fcf5ef2aSThomas Huth             /* ADDQ */
1552fcf5ef2aSThomas Huth             tcg_gen_add_i64(vc, va, vb);
1553fcf5ef2aSThomas Huth             break;
1554fcf5ef2aSThomas Huth         case 0x22:
1555fcf5ef2aSThomas Huth             /* S4ADDQ */
1556fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1557fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 2);
1558fcf5ef2aSThomas Huth             tcg_gen_add_i64(vc, tmp, vb);
1559fcf5ef2aSThomas Huth             break;
1560fcf5ef2aSThomas Huth         case 0x29:
1561fcf5ef2aSThomas Huth             /* SUBQ */
1562fcf5ef2aSThomas Huth             tcg_gen_sub_i64(vc, va, vb);
1563fcf5ef2aSThomas Huth             break;
1564fcf5ef2aSThomas Huth         case 0x2B:
1565fcf5ef2aSThomas Huth             /* S4SUBQ */
1566fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1567fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 2);
1568fcf5ef2aSThomas Huth             tcg_gen_sub_i64(vc, tmp, vb);
1569fcf5ef2aSThomas Huth             break;
1570fcf5ef2aSThomas Huth         case 0x2D:
1571fcf5ef2aSThomas Huth             /* CMPEQ */
1572fcf5ef2aSThomas Huth             tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb);
1573fcf5ef2aSThomas Huth             break;
1574fcf5ef2aSThomas Huth         case 0x32:
1575fcf5ef2aSThomas Huth             /* S8ADDQ */
1576fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1577fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 3);
1578fcf5ef2aSThomas Huth             tcg_gen_add_i64(vc, tmp, vb);
1579fcf5ef2aSThomas Huth             break;
1580fcf5ef2aSThomas Huth         case 0x3B:
1581fcf5ef2aSThomas Huth             /* S8SUBQ */
1582fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1583fcf5ef2aSThomas Huth             tcg_gen_shli_i64(tmp, va, 3);
1584fcf5ef2aSThomas Huth             tcg_gen_sub_i64(vc, tmp, vb);
1585fcf5ef2aSThomas Huth             break;
1586fcf5ef2aSThomas Huth         case 0x3D:
1587fcf5ef2aSThomas Huth             /* CMPULE */
1588fcf5ef2aSThomas Huth             tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb);
1589fcf5ef2aSThomas Huth             break;
1590fcf5ef2aSThomas Huth         case 0x40:
1591fcf5ef2aSThomas Huth             /* ADDL/V */
1592fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1593fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(tmp, va);
1594fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, vb);
1595fcf5ef2aSThomas Huth             tcg_gen_add_i64(tmp, tmp, vc);
1596fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1597ad75a51eSRichard Henderson             gen_helper_check_overflow(tcg_env, vc, tmp);
1598fcf5ef2aSThomas Huth             break;
1599fcf5ef2aSThomas Huth         case 0x49:
1600fcf5ef2aSThomas Huth             /* SUBL/V */
1601fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1602fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(tmp, va);
1603fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, vb);
1604fcf5ef2aSThomas Huth             tcg_gen_sub_i64(tmp, tmp, vc);
1605fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1606ad75a51eSRichard Henderson             gen_helper_check_overflow(tcg_env, vc, tmp);
1607fcf5ef2aSThomas Huth             break;
1608fcf5ef2aSThomas Huth         case 0x4D:
1609fcf5ef2aSThomas Huth             /* CMPLT */
1610fcf5ef2aSThomas Huth             tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb);
1611fcf5ef2aSThomas Huth             break;
1612fcf5ef2aSThomas Huth         case 0x60:
1613fcf5ef2aSThomas Huth             /* ADDQ/V */
1614fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1615fcf5ef2aSThomas Huth             tmp2 = tcg_temp_new();
1616fcf5ef2aSThomas Huth             tcg_gen_eqv_i64(tmp, va, vb);
1617fcf5ef2aSThomas Huth             tcg_gen_mov_i64(tmp2, va);
1618fcf5ef2aSThomas Huth             tcg_gen_add_i64(vc, va, vb);
1619fcf5ef2aSThomas Huth             tcg_gen_xor_i64(tmp2, tmp2, vc);
1620fcf5ef2aSThomas Huth             tcg_gen_and_i64(tmp, tmp, tmp2);
1621fcf5ef2aSThomas Huth             tcg_gen_shri_i64(tmp, tmp, 63);
1622fcf5ef2aSThomas Huth             tcg_gen_movi_i64(tmp2, 0);
1623ad75a51eSRichard Henderson             gen_helper_check_overflow(tcg_env, tmp, tmp2);
1624fcf5ef2aSThomas Huth             break;
1625fcf5ef2aSThomas Huth         case 0x69:
1626fcf5ef2aSThomas Huth             /* SUBQ/V */
1627fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1628fcf5ef2aSThomas Huth             tmp2 = tcg_temp_new();
1629fcf5ef2aSThomas Huth             tcg_gen_xor_i64(tmp, va, vb);
1630fcf5ef2aSThomas Huth             tcg_gen_mov_i64(tmp2, va);
1631fcf5ef2aSThomas Huth             tcg_gen_sub_i64(vc, va, vb);
1632fcf5ef2aSThomas Huth             tcg_gen_xor_i64(tmp2, tmp2, vc);
1633fcf5ef2aSThomas Huth             tcg_gen_and_i64(tmp, tmp, tmp2);
1634fcf5ef2aSThomas Huth             tcg_gen_shri_i64(tmp, tmp, 63);
1635fcf5ef2aSThomas Huth             tcg_gen_movi_i64(tmp2, 0);
1636ad75a51eSRichard Henderson             gen_helper_check_overflow(tcg_env, tmp, tmp2);
1637fcf5ef2aSThomas Huth             break;
1638fcf5ef2aSThomas Huth         case 0x6D:
1639fcf5ef2aSThomas Huth             /* CMPLE */
1640fcf5ef2aSThomas Huth             tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb);
1641fcf5ef2aSThomas Huth             break;
1642fcf5ef2aSThomas Huth         default:
1643fcf5ef2aSThomas Huth             goto invalid_opc;
1644fcf5ef2aSThomas Huth         }
1645fcf5ef2aSThomas Huth         break;
1646fcf5ef2aSThomas Huth 
1647fcf5ef2aSThomas Huth     case 0x11:
1648fcf5ef2aSThomas Huth         if (fn7 == 0x20) {
1649fcf5ef2aSThomas Huth             if (rc == 31) {
1650fcf5ef2aSThomas Huth                 /* Special case BIS as NOP.  */
1651fcf5ef2aSThomas Huth                 break;
1652fcf5ef2aSThomas Huth             }
1653fcf5ef2aSThomas Huth             if (ra == 31) {
1654fcf5ef2aSThomas Huth                 /* Special case BIS as MOV.  */
1655fcf5ef2aSThomas Huth                 vc = dest_gpr(ctx, rc);
1656fcf5ef2aSThomas Huth                 if (islit) {
1657fcf5ef2aSThomas Huth                     tcg_gen_movi_i64(vc, lit);
1658fcf5ef2aSThomas Huth                 } else {
1659fcf5ef2aSThomas Huth                     tcg_gen_mov_i64(vc, load_gpr(ctx, rb));
1660fcf5ef2aSThomas Huth                 }
1661fcf5ef2aSThomas Huth                 break;
1662fcf5ef2aSThomas Huth             }
1663fcf5ef2aSThomas Huth         }
1664fcf5ef2aSThomas Huth 
1665fcf5ef2aSThomas Huth         vc = dest_gpr(ctx, rc);
1666fcf5ef2aSThomas Huth         vb = load_gpr_lit(ctx, rb, lit, islit);
1667fcf5ef2aSThomas Huth 
1668fcf5ef2aSThomas Huth         if (fn7 == 0x28 && ra == 31) {
1669fcf5ef2aSThomas Huth             /* Special case ORNOT as NOT.  */
1670fcf5ef2aSThomas Huth             tcg_gen_not_i64(vc, vb);
1671fcf5ef2aSThomas Huth             break;
1672fcf5ef2aSThomas Huth         }
1673fcf5ef2aSThomas Huth 
1674fcf5ef2aSThomas Huth         va = load_gpr(ctx, ra);
1675fcf5ef2aSThomas Huth         switch (fn7) {
1676fcf5ef2aSThomas Huth         case 0x00:
1677fcf5ef2aSThomas Huth             /* AND */
1678fcf5ef2aSThomas Huth             tcg_gen_and_i64(vc, va, vb);
1679fcf5ef2aSThomas Huth             break;
1680fcf5ef2aSThomas Huth         case 0x08:
1681fcf5ef2aSThomas Huth             /* BIC */
1682fcf5ef2aSThomas Huth             tcg_gen_andc_i64(vc, va, vb);
1683fcf5ef2aSThomas Huth             break;
1684fcf5ef2aSThomas Huth         case 0x14:
1685fcf5ef2aSThomas Huth             /* CMOVLBS */
1686fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1687fcf5ef2aSThomas Huth             tcg_gen_andi_i64(tmp, va, 1);
1688fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),
1689fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1690fcf5ef2aSThomas Huth             break;
1691fcf5ef2aSThomas Huth         case 0x16:
1692fcf5ef2aSThomas Huth             /* CMOVLBC */
1693fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1694fcf5ef2aSThomas Huth             tcg_gen_andi_i64(tmp, va, 1);
1695fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),
1696fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1697fcf5ef2aSThomas Huth             break;
1698fcf5ef2aSThomas Huth         case 0x20:
1699fcf5ef2aSThomas Huth             /* BIS */
1700fcf5ef2aSThomas Huth             tcg_gen_or_i64(vc, va, vb);
1701fcf5ef2aSThomas Huth             break;
1702fcf5ef2aSThomas Huth         case 0x24:
1703fcf5ef2aSThomas Huth             /* CMOVEQ */
1704fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_EQ, vc, va, load_zero(ctx),
1705fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1706fcf5ef2aSThomas Huth             break;
1707fcf5ef2aSThomas Huth         case 0x26:
1708fcf5ef2aSThomas Huth             /* CMOVNE */
1709fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_NE, vc, va, load_zero(ctx),
1710fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1711fcf5ef2aSThomas Huth             break;
1712fcf5ef2aSThomas Huth         case 0x28:
1713fcf5ef2aSThomas Huth             /* ORNOT */
1714fcf5ef2aSThomas Huth             tcg_gen_orc_i64(vc, va, vb);
1715fcf5ef2aSThomas Huth             break;
1716fcf5ef2aSThomas Huth         case 0x40:
1717fcf5ef2aSThomas Huth             /* XOR */
1718fcf5ef2aSThomas Huth             tcg_gen_xor_i64(vc, va, vb);
1719fcf5ef2aSThomas Huth             break;
1720fcf5ef2aSThomas Huth         case 0x44:
1721fcf5ef2aSThomas Huth             /* CMOVLT */
1722fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_LT, vc, va, load_zero(ctx),
1723fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1724fcf5ef2aSThomas Huth             break;
1725fcf5ef2aSThomas Huth         case 0x46:
1726fcf5ef2aSThomas Huth             /* CMOVGE */
1727fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_GE, vc, va, load_zero(ctx),
1728fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1729fcf5ef2aSThomas Huth             break;
1730fcf5ef2aSThomas Huth         case 0x48:
1731fcf5ef2aSThomas Huth             /* EQV */
1732fcf5ef2aSThomas Huth             tcg_gen_eqv_i64(vc, va, vb);
1733fcf5ef2aSThomas Huth             break;
1734fcf5ef2aSThomas Huth         case 0x61:
1735fcf5ef2aSThomas Huth             /* AMASK */
1736fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
1737c6d41b36SRichard Henderson             tcg_gen_andi_i64(vc, vb, ~ctx->amask);
1738fcf5ef2aSThomas Huth             break;
1739fcf5ef2aSThomas Huth         case 0x64:
1740fcf5ef2aSThomas Huth             /* CMOVLE */
1741fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_LE, vc, va, load_zero(ctx),
1742fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1743fcf5ef2aSThomas Huth             break;
1744fcf5ef2aSThomas Huth         case 0x66:
1745fcf5ef2aSThomas Huth             /* CMOVGT */
1746fcf5ef2aSThomas Huth             tcg_gen_movcond_i64(TCG_COND_GT, vc, va, load_zero(ctx),
1747fcf5ef2aSThomas Huth                                 vb, load_gpr(ctx, rc));
1748fcf5ef2aSThomas Huth             break;
1749fcf5ef2aSThomas Huth         case 0x6C:
1750fcf5ef2aSThomas Huth             /* IMPLVER */
1751fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
1752fcf5ef2aSThomas Huth             tcg_gen_movi_i64(vc, ctx->implver);
1753fcf5ef2aSThomas Huth             break;
1754fcf5ef2aSThomas Huth         default:
1755fcf5ef2aSThomas Huth             goto invalid_opc;
1756fcf5ef2aSThomas Huth         }
1757fcf5ef2aSThomas Huth         break;
1758fcf5ef2aSThomas Huth 
1759fcf5ef2aSThomas Huth     case 0x12:
1760fcf5ef2aSThomas Huth         vc = dest_gpr(ctx, rc);
1761fcf5ef2aSThomas Huth         va = load_gpr(ctx, ra);
1762fcf5ef2aSThomas Huth         switch (fn7) {
1763fcf5ef2aSThomas Huth         case 0x02:
1764fcf5ef2aSThomas Huth             /* MSKBL */
1765fcf5ef2aSThomas Huth             gen_msk_l(ctx, vc, va, rb, islit, lit, 0x01);
1766fcf5ef2aSThomas Huth             break;
1767fcf5ef2aSThomas Huth         case 0x06:
1768fcf5ef2aSThomas Huth             /* EXTBL */
1769fcf5ef2aSThomas Huth             gen_ext_l(ctx, vc, va, rb, islit, lit, 0x01);
1770fcf5ef2aSThomas Huth             break;
1771fcf5ef2aSThomas Huth         case 0x0B:
1772fcf5ef2aSThomas Huth             /* INSBL */
1773fcf5ef2aSThomas Huth             gen_ins_l(ctx, vc, va, rb, islit, lit, 0x01);
1774fcf5ef2aSThomas Huth             break;
1775fcf5ef2aSThomas Huth         case 0x12:
1776fcf5ef2aSThomas Huth             /* MSKWL */
1777fcf5ef2aSThomas Huth             gen_msk_l(ctx, vc, va, rb, islit, lit, 0x03);
1778fcf5ef2aSThomas Huth             break;
1779fcf5ef2aSThomas Huth         case 0x16:
1780fcf5ef2aSThomas Huth             /* EXTWL */
1781fcf5ef2aSThomas Huth             gen_ext_l(ctx, vc, va, rb, islit, lit, 0x03);
1782fcf5ef2aSThomas Huth             break;
1783fcf5ef2aSThomas Huth         case 0x1B:
1784fcf5ef2aSThomas Huth             /* INSWL */
1785fcf5ef2aSThomas Huth             gen_ins_l(ctx, vc, va, rb, islit, lit, 0x03);
1786fcf5ef2aSThomas Huth             break;
1787fcf5ef2aSThomas Huth         case 0x22:
1788fcf5ef2aSThomas Huth             /* MSKLL */
1789fcf5ef2aSThomas Huth             gen_msk_l(ctx, vc, va, rb, islit, lit, 0x0f);
1790fcf5ef2aSThomas Huth             break;
1791fcf5ef2aSThomas Huth         case 0x26:
1792fcf5ef2aSThomas Huth             /* EXTLL */
1793fcf5ef2aSThomas Huth             gen_ext_l(ctx, vc, va, rb, islit, lit, 0x0f);
1794fcf5ef2aSThomas Huth             break;
1795fcf5ef2aSThomas Huth         case 0x2B:
1796fcf5ef2aSThomas Huth             /* INSLL */
1797fcf5ef2aSThomas Huth             gen_ins_l(ctx, vc, va, rb, islit, lit, 0x0f);
1798fcf5ef2aSThomas Huth             break;
1799fcf5ef2aSThomas Huth         case 0x30:
1800fcf5ef2aSThomas Huth             /* ZAP */
1801fcf5ef2aSThomas Huth             if (islit) {
1802fcf5ef2aSThomas Huth                 gen_zapnoti(vc, va, ~lit);
1803fcf5ef2aSThomas Huth             } else {
1804fcf5ef2aSThomas Huth                 gen_helper_zap(vc, va, load_gpr(ctx, rb));
1805fcf5ef2aSThomas Huth             }
1806fcf5ef2aSThomas Huth             break;
1807fcf5ef2aSThomas Huth         case 0x31:
1808fcf5ef2aSThomas Huth             /* ZAPNOT */
1809fcf5ef2aSThomas Huth             if (islit) {
1810fcf5ef2aSThomas Huth                 gen_zapnoti(vc, va, lit);
1811fcf5ef2aSThomas Huth             } else {
1812fcf5ef2aSThomas Huth                 gen_helper_zapnot(vc, va, load_gpr(ctx, rb));
1813fcf5ef2aSThomas Huth             }
1814fcf5ef2aSThomas Huth             break;
1815fcf5ef2aSThomas Huth         case 0x32:
1816fcf5ef2aSThomas Huth             /* MSKQL */
1817fcf5ef2aSThomas Huth             gen_msk_l(ctx, vc, va, rb, islit, lit, 0xff);
1818fcf5ef2aSThomas Huth             break;
1819fcf5ef2aSThomas Huth         case 0x34:
1820fcf5ef2aSThomas Huth             /* SRL */
1821fcf5ef2aSThomas Huth             if (islit) {
1822fcf5ef2aSThomas Huth                 tcg_gen_shri_i64(vc, va, lit & 0x3f);
1823fcf5ef2aSThomas Huth             } else {
1824fcf5ef2aSThomas Huth                 tmp = tcg_temp_new();
1825fcf5ef2aSThomas Huth                 vb = load_gpr(ctx, rb);
1826fcf5ef2aSThomas Huth                 tcg_gen_andi_i64(tmp, vb, 0x3f);
1827fcf5ef2aSThomas Huth                 tcg_gen_shr_i64(vc, va, tmp);
1828fcf5ef2aSThomas Huth             }
1829fcf5ef2aSThomas Huth             break;
1830fcf5ef2aSThomas Huth         case 0x36:
1831fcf5ef2aSThomas Huth             /* EXTQL */
1832fcf5ef2aSThomas Huth             gen_ext_l(ctx, vc, va, rb, islit, lit, 0xff);
1833fcf5ef2aSThomas Huth             break;
1834fcf5ef2aSThomas Huth         case 0x39:
1835fcf5ef2aSThomas Huth             /* SLL */
1836fcf5ef2aSThomas Huth             if (islit) {
1837fcf5ef2aSThomas Huth                 tcg_gen_shli_i64(vc, va, lit & 0x3f);
1838fcf5ef2aSThomas Huth             } else {
1839fcf5ef2aSThomas Huth                 tmp = tcg_temp_new();
1840fcf5ef2aSThomas Huth                 vb = load_gpr(ctx, rb);
1841fcf5ef2aSThomas Huth                 tcg_gen_andi_i64(tmp, vb, 0x3f);
1842fcf5ef2aSThomas Huth                 tcg_gen_shl_i64(vc, va, tmp);
1843fcf5ef2aSThomas Huth             }
1844fcf5ef2aSThomas Huth             break;
1845fcf5ef2aSThomas Huth         case 0x3B:
1846fcf5ef2aSThomas Huth             /* INSQL */
1847fcf5ef2aSThomas Huth             gen_ins_l(ctx, vc, va, rb, islit, lit, 0xff);
1848fcf5ef2aSThomas Huth             break;
1849fcf5ef2aSThomas Huth         case 0x3C:
1850fcf5ef2aSThomas Huth             /* SRA */
1851fcf5ef2aSThomas Huth             if (islit) {
1852fcf5ef2aSThomas Huth                 tcg_gen_sari_i64(vc, va, lit & 0x3f);
1853fcf5ef2aSThomas Huth             } else {
1854fcf5ef2aSThomas Huth                 tmp = tcg_temp_new();
1855fcf5ef2aSThomas Huth                 vb = load_gpr(ctx, rb);
1856fcf5ef2aSThomas Huth                 tcg_gen_andi_i64(tmp, vb, 0x3f);
1857fcf5ef2aSThomas Huth                 tcg_gen_sar_i64(vc, va, tmp);
1858fcf5ef2aSThomas Huth             }
1859fcf5ef2aSThomas Huth             break;
1860fcf5ef2aSThomas Huth         case 0x52:
1861fcf5ef2aSThomas Huth             /* MSKWH */
1862fcf5ef2aSThomas Huth             gen_msk_h(ctx, vc, va, rb, islit, lit, 0x03);
1863fcf5ef2aSThomas Huth             break;
1864fcf5ef2aSThomas Huth         case 0x57:
1865fcf5ef2aSThomas Huth             /* INSWH */
1866fcf5ef2aSThomas Huth             gen_ins_h(ctx, vc, va, rb, islit, lit, 0x03);
1867fcf5ef2aSThomas Huth             break;
1868fcf5ef2aSThomas Huth         case 0x5A:
1869fcf5ef2aSThomas Huth             /* EXTWH */
1870fcf5ef2aSThomas Huth             gen_ext_h(ctx, vc, va, rb, islit, lit, 0x03);
1871fcf5ef2aSThomas Huth             break;
1872fcf5ef2aSThomas Huth         case 0x62:
1873fcf5ef2aSThomas Huth             /* MSKLH */
1874fcf5ef2aSThomas Huth             gen_msk_h(ctx, vc, va, rb, islit, lit, 0x0f);
1875fcf5ef2aSThomas Huth             break;
1876fcf5ef2aSThomas Huth         case 0x67:
1877fcf5ef2aSThomas Huth             /* INSLH */
1878fcf5ef2aSThomas Huth             gen_ins_h(ctx, vc, va, rb, islit, lit, 0x0f);
1879fcf5ef2aSThomas Huth             break;
1880fcf5ef2aSThomas Huth         case 0x6A:
1881fcf5ef2aSThomas Huth             /* EXTLH */
1882fcf5ef2aSThomas Huth             gen_ext_h(ctx, vc, va, rb, islit, lit, 0x0f);
1883fcf5ef2aSThomas Huth             break;
1884fcf5ef2aSThomas Huth         case 0x72:
1885fcf5ef2aSThomas Huth             /* MSKQH */
1886fcf5ef2aSThomas Huth             gen_msk_h(ctx, vc, va, rb, islit, lit, 0xff);
1887fcf5ef2aSThomas Huth             break;
1888fcf5ef2aSThomas Huth         case 0x77:
1889fcf5ef2aSThomas Huth             /* INSQH */
1890fcf5ef2aSThomas Huth             gen_ins_h(ctx, vc, va, rb, islit, lit, 0xff);
1891fcf5ef2aSThomas Huth             break;
1892fcf5ef2aSThomas Huth         case 0x7A:
1893fcf5ef2aSThomas Huth             /* EXTQH */
1894fcf5ef2aSThomas Huth             gen_ext_h(ctx, vc, va, rb, islit, lit, 0xff);
1895fcf5ef2aSThomas Huth             break;
1896fcf5ef2aSThomas Huth         default:
1897fcf5ef2aSThomas Huth             goto invalid_opc;
1898fcf5ef2aSThomas Huth         }
1899fcf5ef2aSThomas Huth         break;
1900fcf5ef2aSThomas Huth 
1901fcf5ef2aSThomas Huth     case 0x13:
1902fcf5ef2aSThomas Huth         vc = dest_gpr(ctx, rc);
1903fcf5ef2aSThomas Huth         vb = load_gpr_lit(ctx, rb, lit, islit);
1904fcf5ef2aSThomas Huth         va = load_gpr(ctx, ra);
1905fcf5ef2aSThomas Huth         switch (fn7) {
1906fcf5ef2aSThomas Huth         case 0x00:
1907fcf5ef2aSThomas Huth             /* MULL */
1908fcf5ef2aSThomas Huth             tcg_gen_mul_i64(vc, va, vb);
1909fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, vc);
1910fcf5ef2aSThomas Huth             break;
1911fcf5ef2aSThomas Huth         case 0x20:
1912fcf5ef2aSThomas Huth             /* MULQ */
1913fcf5ef2aSThomas Huth             tcg_gen_mul_i64(vc, va, vb);
1914fcf5ef2aSThomas Huth             break;
1915fcf5ef2aSThomas Huth         case 0x30:
1916fcf5ef2aSThomas Huth             /* UMULH */
1917fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1918fcf5ef2aSThomas Huth             tcg_gen_mulu2_i64(tmp, vc, va, vb);
1919fcf5ef2aSThomas Huth             break;
1920fcf5ef2aSThomas Huth         case 0x40:
1921fcf5ef2aSThomas Huth             /* MULL/V */
1922fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1923fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(tmp, va);
1924fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, vb);
1925fcf5ef2aSThomas Huth             tcg_gen_mul_i64(tmp, tmp, vc);
1926fcf5ef2aSThomas Huth             tcg_gen_ext32s_i64(vc, tmp);
1927ad75a51eSRichard Henderson             gen_helper_check_overflow(tcg_env, vc, tmp);
1928fcf5ef2aSThomas Huth             break;
1929fcf5ef2aSThomas Huth         case 0x60:
1930fcf5ef2aSThomas Huth             /* MULQ/V */
1931fcf5ef2aSThomas Huth             tmp = tcg_temp_new();
1932fcf5ef2aSThomas Huth             tmp2 = tcg_temp_new();
1933fcf5ef2aSThomas Huth             tcg_gen_muls2_i64(vc, tmp, va, vb);
1934fcf5ef2aSThomas Huth             tcg_gen_sari_i64(tmp2, vc, 63);
1935ad75a51eSRichard Henderson             gen_helper_check_overflow(tcg_env, tmp, tmp2);
1936fcf5ef2aSThomas Huth             break;
1937fcf5ef2aSThomas Huth         default:
1938fcf5ef2aSThomas Huth             goto invalid_opc;
1939fcf5ef2aSThomas Huth         }
1940fcf5ef2aSThomas Huth         break;
1941fcf5ef2aSThomas Huth 
1942fcf5ef2aSThomas Huth     case 0x14:
1943c6d41b36SRichard Henderson         REQUIRE_AMASK(FIX);
1944fcf5ef2aSThomas Huth         vc = dest_fpr(ctx, rc);
1945fcf5ef2aSThomas Huth         switch (fpfn) { /* fn11 & 0x3F */
1946fcf5ef2aSThomas Huth         case 0x04:
1947fcf5ef2aSThomas Huth             /* ITOFS */
1948fcf5ef2aSThomas Huth             REQUIRE_REG_31(rb);
19499d14a042SRichard Henderson             REQUIRE_FEN;
1950fcf5ef2aSThomas Huth             t32 = tcg_temp_new_i32();
1951fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
1952fcf5ef2aSThomas Huth             tcg_gen_extrl_i64_i32(t32, va);
1953fcf5ef2aSThomas Huth             gen_helper_memory_to_s(vc, t32);
1954fcf5ef2aSThomas Huth             break;
1955fcf5ef2aSThomas Huth         case 0x0A:
1956fcf5ef2aSThomas Huth             /* SQRTF */
1957fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
19589d14a042SRichard Henderson             REQUIRE_FEN;
1959fcf5ef2aSThomas Huth             vb = load_fpr(ctx, rb);
1960ad75a51eSRichard Henderson             gen_helper_sqrtf(vc, tcg_env, vb);
1961fcf5ef2aSThomas Huth             break;
1962fcf5ef2aSThomas Huth         case 0x0B:
1963fcf5ef2aSThomas Huth             /* SQRTS */
1964fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
19659d14a042SRichard Henderson             REQUIRE_FEN;
1966fcf5ef2aSThomas Huth             gen_sqrts(ctx, rb, rc, fn11);
1967fcf5ef2aSThomas Huth             break;
1968fcf5ef2aSThomas Huth         case 0x14:
1969fcf5ef2aSThomas Huth             /* ITOFF */
1970fcf5ef2aSThomas Huth             REQUIRE_REG_31(rb);
19719d14a042SRichard Henderson             REQUIRE_FEN;
1972fcf5ef2aSThomas Huth             t32 = tcg_temp_new_i32();
1973fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
1974fcf5ef2aSThomas Huth             tcg_gen_extrl_i64_i32(t32, va);
1975fcf5ef2aSThomas Huth             gen_helper_memory_to_f(vc, t32);
1976fcf5ef2aSThomas Huth             break;
1977fcf5ef2aSThomas Huth         case 0x24:
1978fcf5ef2aSThomas Huth             /* ITOFT */
1979fcf5ef2aSThomas Huth             REQUIRE_REG_31(rb);
19809d14a042SRichard Henderson             REQUIRE_FEN;
1981fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
1982fcf5ef2aSThomas Huth             tcg_gen_mov_i64(vc, va);
1983fcf5ef2aSThomas Huth             break;
1984fcf5ef2aSThomas Huth         case 0x2A:
1985fcf5ef2aSThomas Huth             /* SQRTG */
1986fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
19879d14a042SRichard Henderson             REQUIRE_FEN;
1988fcf5ef2aSThomas Huth             vb = load_fpr(ctx, rb);
1989ad75a51eSRichard Henderson             gen_helper_sqrtg(vc, tcg_env, vb);
1990fcf5ef2aSThomas Huth             break;
1991fcf5ef2aSThomas Huth         case 0x02B:
1992fcf5ef2aSThomas Huth             /* SQRTT */
1993fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
19949d14a042SRichard Henderson             REQUIRE_FEN;
1995fcf5ef2aSThomas Huth             gen_sqrtt(ctx, rb, rc, fn11);
1996fcf5ef2aSThomas Huth             break;
1997fcf5ef2aSThomas Huth         default:
1998fcf5ef2aSThomas Huth             goto invalid_opc;
1999fcf5ef2aSThomas Huth         }
2000fcf5ef2aSThomas Huth         break;
2001fcf5ef2aSThomas Huth 
2002fcf5ef2aSThomas Huth     case 0x15:
2003fcf5ef2aSThomas Huth         /* VAX floating point */
2004fcf5ef2aSThomas Huth         /* XXX: rounding mode and trap are ignored (!) */
2005fcf5ef2aSThomas Huth         vc = dest_fpr(ctx, rc);
2006fcf5ef2aSThomas Huth         vb = load_fpr(ctx, rb);
2007fcf5ef2aSThomas Huth         va = load_fpr(ctx, ra);
2008fcf5ef2aSThomas Huth         switch (fpfn) { /* fn11 & 0x3F */
2009fcf5ef2aSThomas Huth         case 0x00:
2010fcf5ef2aSThomas Huth             /* ADDF */
20119d14a042SRichard Henderson             REQUIRE_FEN;
2012ad75a51eSRichard Henderson             gen_helper_addf(vc, tcg_env, va, vb);
2013fcf5ef2aSThomas Huth             break;
2014fcf5ef2aSThomas Huth         case 0x01:
2015fcf5ef2aSThomas Huth             /* SUBF */
20169d14a042SRichard Henderson             REQUIRE_FEN;
2017ad75a51eSRichard Henderson             gen_helper_subf(vc, tcg_env, va, vb);
2018fcf5ef2aSThomas Huth             break;
2019fcf5ef2aSThomas Huth         case 0x02:
2020fcf5ef2aSThomas Huth             /* MULF */
20219d14a042SRichard Henderson             REQUIRE_FEN;
2022ad75a51eSRichard Henderson             gen_helper_mulf(vc, tcg_env, va, vb);
2023fcf5ef2aSThomas Huth             break;
2024fcf5ef2aSThomas Huth         case 0x03:
2025fcf5ef2aSThomas Huth             /* DIVF */
20269d14a042SRichard Henderson             REQUIRE_FEN;
2027ad75a51eSRichard Henderson             gen_helper_divf(vc, tcg_env, va, vb);
2028fcf5ef2aSThomas Huth             break;
2029fcf5ef2aSThomas Huth         case 0x1E:
2030fcf5ef2aSThomas Huth             /* CVTDG -- TODO */
2031fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2032fcf5ef2aSThomas Huth             goto invalid_opc;
2033fcf5ef2aSThomas Huth         case 0x20:
2034fcf5ef2aSThomas Huth             /* ADDG */
20359d14a042SRichard Henderson             REQUIRE_FEN;
2036ad75a51eSRichard Henderson             gen_helper_addg(vc, tcg_env, va, vb);
2037fcf5ef2aSThomas Huth             break;
2038fcf5ef2aSThomas Huth         case 0x21:
2039fcf5ef2aSThomas Huth             /* SUBG */
20409d14a042SRichard Henderson             REQUIRE_FEN;
2041ad75a51eSRichard Henderson             gen_helper_subg(vc, tcg_env, va, vb);
2042fcf5ef2aSThomas Huth             break;
2043fcf5ef2aSThomas Huth         case 0x22:
2044fcf5ef2aSThomas Huth             /* MULG */
20459d14a042SRichard Henderson             REQUIRE_FEN;
2046ad75a51eSRichard Henderson             gen_helper_mulg(vc, tcg_env, va, vb);
2047fcf5ef2aSThomas Huth             break;
2048fcf5ef2aSThomas Huth         case 0x23:
2049fcf5ef2aSThomas Huth             /* DIVG */
20509d14a042SRichard Henderson             REQUIRE_FEN;
2051ad75a51eSRichard Henderson             gen_helper_divg(vc, tcg_env, va, vb);
2052fcf5ef2aSThomas Huth             break;
2053fcf5ef2aSThomas Huth         case 0x25:
2054fcf5ef2aSThomas Huth             /* CMPGEQ */
20559d14a042SRichard Henderson             REQUIRE_FEN;
2056ad75a51eSRichard Henderson             gen_helper_cmpgeq(vc, tcg_env, va, vb);
2057fcf5ef2aSThomas Huth             break;
2058fcf5ef2aSThomas Huth         case 0x26:
2059fcf5ef2aSThomas Huth             /* CMPGLT */
20609d14a042SRichard Henderson             REQUIRE_FEN;
2061ad75a51eSRichard Henderson             gen_helper_cmpglt(vc, tcg_env, va, vb);
2062fcf5ef2aSThomas Huth             break;
2063fcf5ef2aSThomas Huth         case 0x27:
2064fcf5ef2aSThomas Huth             /* CMPGLE */
20659d14a042SRichard Henderson             REQUIRE_FEN;
2066ad75a51eSRichard Henderson             gen_helper_cmpgle(vc, tcg_env, va, vb);
2067fcf5ef2aSThomas Huth             break;
2068fcf5ef2aSThomas Huth         case 0x2C:
2069fcf5ef2aSThomas Huth             /* CVTGF */
2070fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
20719d14a042SRichard Henderson             REQUIRE_FEN;
2072ad75a51eSRichard Henderson             gen_helper_cvtgf(vc, tcg_env, vb);
2073fcf5ef2aSThomas Huth             break;
2074fcf5ef2aSThomas Huth         case 0x2D:
2075fcf5ef2aSThomas Huth             /* CVTGD -- TODO */
2076fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2077fcf5ef2aSThomas Huth             goto invalid_opc;
2078fcf5ef2aSThomas Huth         case 0x2F:
2079fcf5ef2aSThomas Huth             /* CVTGQ */
2080fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
20819d14a042SRichard Henderson             REQUIRE_FEN;
2082ad75a51eSRichard Henderson             gen_helper_cvtgq(vc, tcg_env, vb);
2083fcf5ef2aSThomas Huth             break;
2084fcf5ef2aSThomas Huth         case 0x3C:
2085fcf5ef2aSThomas Huth             /* CVTQF */
2086fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
20879d14a042SRichard Henderson             REQUIRE_FEN;
2088ad75a51eSRichard Henderson             gen_helper_cvtqf(vc, tcg_env, vb);
2089fcf5ef2aSThomas Huth             break;
2090fcf5ef2aSThomas Huth         case 0x3E:
2091fcf5ef2aSThomas Huth             /* CVTQG */
2092fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
20939d14a042SRichard Henderson             REQUIRE_FEN;
2094ad75a51eSRichard Henderson             gen_helper_cvtqg(vc, tcg_env, vb);
2095fcf5ef2aSThomas Huth             break;
2096fcf5ef2aSThomas Huth         default:
2097fcf5ef2aSThomas Huth             goto invalid_opc;
2098fcf5ef2aSThomas Huth         }
2099fcf5ef2aSThomas Huth         break;
2100fcf5ef2aSThomas Huth 
2101fcf5ef2aSThomas Huth     case 0x16:
2102fcf5ef2aSThomas Huth         /* IEEE floating-point */
2103fcf5ef2aSThomas Huth         switch (fpfn) { /* fn11 & 0x3F */
2104fcf5ef2aSThomas Huth         case 0x00:
2105fcf5ef2aSThomas Huth             /* ADDS */
21069d14a042SRichard Henderson             REQUIRE_FEN;
2107fcf5ef2aSThomas Huth             gen_adds(ctx, ra, rb, rc, fn11);
2108fcf5ef2aSThomas Huth             break;
2109fcf5ef2aSThomas Huth         case 0x01:
2110fcf5ef2aSThomas Huth             /* SUBS */
21119d14a042SRichard Henderson             REQUIRE_FEN;
2112fcf5ef2aSThomas Huth             gen_subs(ctx, ra, rb, rc, fn11);
2113fcf5ef2aSThomas Huth             break;
2114fcf5ef2aSThomas Huth         case 0x02:
2115fcf5ef2aSThomas Huth             /* MULS */
21169d14a042SRichard Henderson             REQUIRE_FEN;
2117fcf5ef2aSThomas Huth             gen_muls(ctx, ra, rb, rc, fn11);
2118fcf5ef2aSThomas Huth             break;
2119fcf5ef2aSThomas Huth         case 0x03:
2120fcf5ef2aSThomas Huth             /* DIVS */
21219d14a042SRichard Henderson             REQUIRE_FEN;
2122fcf5ef2aSThomas Huth             gen_divs(ctx, ra, rb, rc, fn11);
2123fcf5ef2aSThomas Huth             break;
2124fcf5ef2aSThomas Huth         case 0x20:
2125fcf5ef2aSThomas Huth             /* ADDT */
21269d14a042SRichard Henderson             REQUIRE_FEN;
2127fcf5ef2aSThomas Huth             gen_addt(ctx, ra, rb, rc, fn11);
2128fcf5ef2aSThomas Huth             break;
2129fcf5ef2aSThomas Huth         case 0x21:
2130fcf5ef2aSThomas Huth             /* SUBT */
21319d14a042SRichard Henderson             REQUIRE_FEN;
2132fcf5ef2aSThomas Huth             gen_subt(ctx, ra, rb, rc, fn11);
2133fcf5ef2aSThomas Huth             break;
2134fcf5ef2aSThomas Huth         case 0x22:
2135fcf5ef2aSThomas Huth             /* MULT */
21369d14a042SRichard Henderson             REQUIRE_FEN;
2137fcf5ef2aSThomas Huth             gen_mult(ctx, ra, rb, rc, fn11);
2138fcf5ef2aSThomas Huth             break;
2139fcf5ef2aSThomas Huth         case 0x23:
2140fcf5ef2aSThomas Huth             /* DIVT */
21419d14a042SRichard Henderson             REQUIRE_FEN;
2142fcf5ef2aSThomas Huth             gen_divt(ctx, ra, rb, rc, fn11);
2143fcf5ef2aSThomas Huth             break;
2144fcf5ef2aSThomas Huth         case 0x24:
2145fcf5ef2aSThomas Huth             /* CMPTUN */
21469d14a042SRichard Henderson             REQUIRE_FEN;
2147fcf5ef2aSThomas Huth             gen_cmptun(ctx, ra, rb, rc, fn11);
2148fcf5ef2aSThomas Huth             break;
2149fcf5ef2aSThomas Huth         case 0x25:
2150fcf5ef2aSThomas Huth             /* CMPTEQ */
21519d14a042SRichard Henderson             REQUIRE_FEN;
2152fcf5ef2aSThomas Huth             gen_cmpteq(ctx, ra, rb, rc, fn11);
2153fcf5ef2aSThomas Huth             break;
2154fcf5ef2aSThomas Huth         case 0x26:
2155fcf5ef2aSThomas Huth             /* CMPTLT */
21569d14a042SRichard Henderson             REQUIRE_FEN;
2157fcf5ef2aSThomas Huth             gen_cmptlt(ctx, ra, rb, rc, fn11);
2158fcf5ef2aSThomas Huth             break;
2159fcf5ef2aSThomas Huth         case 0x27:
2160fcf5ef2aSThomas Huth             /* CMPTLE */
21619d14a042SRichard Henderson             REQUIRE_FEN;
2162fcf5ef2aSThomas Huth             gen_cmptle(ctx, ra, rb, rc, fn11);
2163fcf5ef2aSThomas Huth             break;
2164fcf5ef2aSThomas Huth         case 0x2C:
2165fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
21669d14a042SRichard Henderson             REQUIRE_FEN;
2167fcf5ef2aSThomas Huth             if (fn11 == 0x2AC || fn11 == 0x6AC) {
2168fcf5ef2aSThomas Huth                 /* CVTST */
2169fcf5ef2aSThomas Huth                 gen_cvtst(ctx, rb, rc, fn11);
2170fcf5ef2aSThomas Huth             } else {
2171fcf5ef2aSThomas Huth                 /* CVTTS */
2172fcf5ef2aSThomas Huth                 gen_cvtts(ctx, rb, rc, fn11);
2173fcf5ef2aSThomas Huth             }
2174fcf5ef2aSThomas Huth             break;
2175fcf5ef2aSThomas Huth         case 0x2F:
2176fcf5ef2aSThomas Huth             /* CVTTQ */
2177fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
21789d14a042SRichard Henderson             REQUIRE_FEN;
2179fcf5ef2aSThomas Huth             gen_cvttq(ctx, rb, rc, fn11);
2180fcf5ef2aSThomas Huth             break;
2181fcf5ef2aSThomas Huth         case 0x3C:
2182fcf5ef2aSThomas Huth             /* CVTQS */
2183fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
21849d14a042SRichard Henderson             REQUIRE_FEN;
2185fcf5ef2aSThomas Huth             gen_cvtqs(ctx, rb, rc, fn11);
2186fcf5ef2aSThomas Huth             break;
2187fcf5ef2aSThomas Huth         case 0x3E:
2188fcf5ef2aSThomas Huth             /* CVTQT */
2189fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
21909d14a042SRichard Henderson             REQUIRE_FEN;
2191fcf5ef2aSThomas Huth             gen_cvtqt(ctx, rb, rc, fn11);
2192fcf5ef2aSThomas Huth             break;
2193fcf5ef2aSThomas Huth         default:
2194fcf5ef2aSThomas Huth             goto invalid_opc;
2195fcf5ef2aSThomas Huth         }
2196fcf5ef2aSThomas Huth         break;
2197fcf5ef2aSThomas Huth 
2198fcf5ef2aSThomas Huth     case 0x17:
2199fcf5ef2aSThomas Huth         switch (fn11) {
2200fcf5ef2aSThomas Huth         case 0x010:
2201fcf5ef2aSThomas Huth             /* CVTLQ */
2202fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
22039d14a042SRichard Henderson             REQUIRE_FEN;
2204fcf5ef2aSThomas Huth             vc = dest_fpr(ctx, rc);
2205fcf5ef2aSThomas Huth             vb = load_fpr(ctx, rb);
2206fcf5ef2aSThomas Huth             gen_cvtlq(vc, vb);
2207fcf5ef2aSThomas Huth             break;
2208fcf5ef2aSThomas Huth         case 0x020:
2209fcf5ef2aSThomas Huth             /* CPYS */
22109d14a042SRichard Henderson             REQUIRE_FEN;
2211fcf5ef2aSThomas Huth             if (rc == 31) {
2212fcf5ef2aSThomas Huth                 /* Special case CPYS as FNOP.  */
2213fcf5ef2aSThomas Huth             } else {
2214fcf5ef2aSThomas Huth                 vc = dest_fpr(ctx, rc);
2215fcf5ef2aSThomas Huth                 va = load_fpr(ctx, ra);
2216fcf5ef2aSThomas Huth                 if (ra == rb) {
2217fcf5ef2aSThomas Huth                     /* Special case CPYS as FMOV.  */
2218fcf5ef2aSThomas Huth                     tcg_gen_mov_i64(vc, va);
2219fcf5ef2aSThomas Huth                 } else {
2220fcf5ef2aSThomas Huth                     vb = load_fpr(ctx, rb);
2221fcf5ef2aSThomas Huth                     gen_cpy_mask(vc, va, vb, 0, 0x8000000000000000ULL);
2222fcf5ef2aSThomas Huth                 }
2223fcf5ef2aSThomas Huth             }
2224fcf5ef2aSThomas Huth             break;
2225fcf5ef2aSThomas Huth         case 0x021:
2226fcf5ef2aSThomas Huth             /* CPYSN */
22279d14a042SRichard Henderson             REQUIRE_FEN;
2228fcf5ef2aSThomas Huth             vc = dest_fpr(ctx, rc);
2229fcf5ef2aSThomas Huth             vb = load_fpr(ctx, rb);
2230fcf5ef2aSThomas Huth             va = load_fpr(ctx, ra);
2231fcf5ef2aSThomas Huth             gen_cpy_mask(vc, va, vb, 1, 0x8000000000000000ULL);
2232fcf5ef2aSThomas Huth             break;
2233fcf5ef2aSThomas Huth         case 0x022:
2234fcf5ef2aSThomas Huth             /* CPYSE */
22359d14a042SRichard Henderson             REQUIRE_FEN;
2236fcf5ef2aSThomas Huth             vc = dest_fpr(ctx, rc);
2237fcf5ef2aSThomas Huth             vb = load_fpr(ctx, rb);
2238fcf5ef2aSThomas Huth             va = load_fpr(ctx, ra);
2239fcf5ef2aSThomas Huth             gen_cpy_mask(vc, va, vb, 0, 0xFFF0000000000000ULL);
2240fcf5ef2aSThomas Huth             break;
2241fcf5ef2aSThomas Huth         case 0x024:
2242fcf5ef2aSThomas Huth             /* MT_FPCR */
22439d14a042SRichard Henderson             REQUIRE_FEN;
2244fcf5ef2aSThomas Huth             va = load_fpr(ctx, ra);
2245ad75a51eSRichard Henderson             gen_helper_store_fpcr(tcg_env, va);
2246fcf5ef2aSThomas Huth             if (ctx->tb_rm == QUAL_RM_D) {
2247fcf5ef2aSThomas Huth                 /* Re-do the copy of the rounding mode to fp_status
2248fcf5ef2aSThomas Huth                    the next time we use dynamic rounding.  */
2249fcf5ef2aSThomas Huth                 ctx->tb_rm = -1;
2250fcf5ef2aSThomas Huth             }
2251fcf5ef2aSThomas Huth             break;
2252fcf5ef2aSThomas Huth         case 0x025:
2253fcf5ef2aSThomas Huth             /* MF_FPCR */
22549d14a042SRichard Henderson             REQUIRE_FEN;
2255fcf5ef2aSThomas Huth             va = dest_fpr(ctx, ra);
2256ad75a51eSRichard Henderson             gen_helper_load_fpcr(va, tcg_env);
2257fcf5ef2aSThomas Huth             break;
2258fcf5ef2aSThomas Huth         case 0x02A:
2259fcf5ef2aSThomas Huth             /* FCMOVEQ */
22609d14a042SRichard Henderson             REQUIRE_FEN;
2261fcf5ef2aSThomas Huth             gen_fcmov(ctx, TCG_COND_EQ, ra, rb, rc);
2262fcf5ef2aSThomas Huth             break;
2263fcf5ef2aSThomas Huth         case 0x02B:
2264fcf5ef2aSThomas Huth             /* FCMOVNE */
22659d14a042SRichard Henderson             REQUIRE_FEN;
2266fcf5ef2aSThomas Huth             gen_fcmov(ctx, TCG_COND_NE, ra, rb, rc);
2267fcf5ef2aSThomas Huth             break;
2268fcf5ef2aSThomas Huth         case 0x02C:
2269fcf5ef2aSThomas Huth             /* FCMOVLT */
22709d14a042SRichard Henderson             REQUIRE_FEN;
2271fcf5ef2aSThomas Huth             gen_fcmov(ctx, TCG_COND_LT, ra, rb, rc);
2272fcf5ef2aSThomas Huth             break;
2273fcf5ef2aSThomas Huth         case 0x02D:
2274fcf5ef2aSThomas Huth             /* FCMOVGE */
22759d14a042SRichard Henderson             REQUIRE_FEN;
2276fcf5ef2aSThomas Huth             gen_fcmov(ctx, TCG_COND_GE, ra, rb, rc);
2277fcf5ef2aSThomas Huth             break;
2278fcf5ef2aSThomas Huth         case 0x02E:
2279fcf5ef2aSThomas Huth             /* FCMOVLE */
22809d14a042SRichard Henderson             REQUIRE_FEN;
2281fcf5ef2aSThomas Huth             gen_fcmov(ctx, TCG_COND_LE, ra, rb, rc);
2282fcf5ef2aSThomas Huth             break;
2283fcf5ef2aSThomas Huth         case 0x02F:
2284fcf5ef2aSThomas Huth             /* FCMOVGT */
22859d14a042SRichard Henderson             REQUIRE_FEN;
2286fcf5ef2aSThomas Huth             gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc);
2287fcf5ef2aSThomas Huth             break;
2288fcf5ef2aSThomas Huth         case 0x030: /* CVTQL */
2289fcf5ef2aSThomas Huth         case 0x130: /* CVTQL/V */
2290fcf5ef2aSThomas Huth         case 0x530: /* CVTQL/SV */
2291fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
22929d14a042SRichard Henderson             REQUIRE_FEN;
2293fcf5ef2aSThomas Huth             vc = dest_fpr(ctx, rc);
2294fcf5ef2aSThomas Huth             vb = load_fpr(ctx, rb);
2295ad75a51eSRichard Henderson             gen_helper_cvtql(vc, tcg_env, vb);
2296fcf5ef2aSThomas Huth             gen_fp_exc_raise(rc, fn11);
2297fcf5ef2aSThomas Huth             break;
2298fcf5ef2aSThomas Huth         default:
2299fcf5ef2aSThomas Huth             goto invalid_opc;
2300fcf5ef2aSThomas Huth         }
2301fcf5ef2aSThomas Huth         break;
2302fcf5ef2aSThomas Huth 
2303fcf5ef2aSThomas Huth     case 0x18:
2304fcf5ef2aSThomas Huth         switch ((uint16_t)disp16) {
2305fcf5ef2aSThomas Huth         case 0x0000:
2306fcf5ef2aSThomas Huth             /* TRAPB */
2307fcf5ef2aSThomas Huth             /* No-op.  */
2308fcf5ef2aSThomas Huth             break;
2309fcf5ef2aSThomas Huth         case 0x0400:
2310fcf5ef2aSThomas Huth             /* EXCB */
2311fcf5ef2aSThomas Huth             /* No-op.  */
2312fcf5ef2aSThomas Huth             break;
2313fcf5ef2aSThomas Huth         case 0x4000:
2314fcf5ef2aSThomas Huth             /* MB */
2315fcf5ef2aSThomas Huth             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
2316fcf5ef2aSThomas Huth             break;
2317fcf5ef2aSThomas Huth         case 0x4400:
2318fcf5ef2aSThomas Huth             /* WMB */
2319fcf5ef2aSThomas Huth             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
2320fcf5ef2aSThomas Huth             break;
2321fcf5ef2aSThomas Huth         case 0x8000:
2322fcf5ef2aSThomas Huth             /* FETCH */
2323fcf5ef2aSThomas Huth             /* No-op */
2324fcf5ef2aSThomas Huth             break;
2325fcf5ef2aSThomas Huth         case 0xA000:
2326fcf5ef2aSThomas Huth             /* FETCH_M */
2327fcf5ef2aSThomas Huth             /* No-op */
2328fcf5ef2aSThomas Huth             break;
2329fcf5ef2aSThomas Huth         case 0xC000:
2330fcf5ef2aSThomas Huth             /* RPCC */
2331fcf5ef2aSThomas Huth             va = dest_gpr(ctx, ra);
2332dfd1b812SRichard Henderson             if (translator_io_start(&ctx->base)) {
23333de811c6SRichard Henderson                 ret = DISAS_PC_STALE;
2334fcf5ef2aSThomas Huth             }
2335ad75a51eSRichard Henderson             gen_helper_load_pcc(va, tcg_env);
2336fcf5ef2aSThomas Huth             break;
2337fcf5ef2aSThomas Huth         case 0xE000:
2338fcf5ef2aSThomas Huth             /* RC */
2339fcf5ef2aSThomas Huth             gen_rx(ctx, ra, 0);
2340fcf5ef2aSThomas Huth             break;
2341fcf5ef2aSThomas Huth         case 0xE800:
2342fcf5ef2aSThomas Huth             /* ECB */
2343fcf5ef2aSThomas Huth             break;
2344fcf5ef2aSThomas Huth         case 0xF000:
2345fcf5ef2aSThomas Huth             /* RS */
2346fcf5ef2aSThomas Huth             gen_rx(ctx, ra, 1);
2347fcf5ef2aSThomas Huth             break;
2348fcf5ef2aSThomas Huth         case 0xF800:
2349fcf5ef2aSThomas Huth             /* WH64 */
2350fcf5ef2aSThomas Huth             /* No-op */
2351fcf5ef2aSThomas Huth             break;
2352fcf5ef2aSThomas Huth         case 0xFC00:
2353fcf5ef2aSThomas Huth             /* WH64EN */
2354fcf5ef2aSThomas Huth             /* No-op */
2355fcf5ef2aSThomas Huth             break;
2356fcf5ef2aSThomas Huth         default:
2357fcf5ef2aSThomas Huth             goto invalid_opc;
2358fcf5ef2aSThomas Huth         }
2359fcf5ef2aSThomas Huth         break;
2360fcf5ef2aSThomas Huth 
2361fcf5ef2aSThomas Huth     case 0x19:
2362fcf5ef2aSThomas Huth         /* HW_MFPR (PALcode) */
2363fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
2364bcd2625dSRichard Henderson         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2365fcf5ef2aSThomas Huth         va = dest_gpr(ctx, ra);
2366fcf5ef2aSThomas Huth         ret = gen_mfpr(ctx, va, insn & 0xffff);
2367fcf5ef2aSThomas Huth         break;
2368fcf5ef2aSThomas Huth #else
2369fcf5ef2aSThomas Huth         goto invalid_opc;
2370fcf5ef2aSThomas Huth #endif
2371fcf5ef2aSThomas Huth 
2372fcf5ef2aSThomas Huth     case 0x1A:
2373fcf5ef2aSThomas Huth         /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
2374fcf5ef2aSThomas Huth            prediction stack action, which of course we don't implement.  */
2375fcf5ef2aSThomas Huth         vb = load_gpr(ctx, rb);
2376fcf5ef2aSThomas Huth         tcg_gen_andi_i64(cpu_pc, vb, ~3);
2377fcf5ef2aSThomas Huth         if (ra != 31) {
2378c5f80657SRichard Henderson             tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
2379fcf5ef2aSThomas Huth         }
23803de811c6SRichard Henderson         ret = DISAS_PC_UPDATED;
2381fcf5ef2aSThomas Huth         break;
2382fcf5ef2aSThomas Huth 
2383fcf5ef2aSThomas Huth     case 0x1B:
2384fcf5ef2aSThomas Huth         /* HW_LD (PALcode) */
2385fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
2386bcd2625dSRichard Henderson         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2387fcf5ef2aSThomas Huth         {
2388fcf5ef2aSThomas Huth             TCGv addr = tcg_temp_new();
2389fcf5ef2aSThomas Huth             vb = load_gpr(ctx, rb);
2390fcf5ef2aSThomas Huth             va = dest_gpr(ctx, ra);
2391fcf5ef2aSThomas Huth 
2392fcf5ef2aSThomas Huth             tcg_gen_addi_i64(addr, vb, disp12);
2393fcf5ef2aSThomas Huth             switch ((insn >> 12) & 0xF) {
2394fcf5ef2aSThomas Huth             case 0x0:
2395fcf5ef2aSThomas Huth                 /* Longword physical access (hw_ldl/p) */
239633948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL | MO_ALIGN);
2397fcf5ef2aSThomas Huth                 break;
2398fcf5ef2aSThomas Huth             case 0x1:
2399fcf5ef2aSThomas Huth                 /* Quadword physical access (hw_ldq/p) */
240033948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ | MO_ALIGN);
2401fcf5ef2aSThomas Huth                 break;
2402fcf5ef2aSThomas Huth             case 0x2:
2403fcf5ef2aSThomas Huth                 /* Longword physical access with lock (hw_ldl_l/p) */
240433948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL | MO_ALIGN);
24055ffcb334SRichard Henderson                 tcg_gen_mov_i64(cpu_lock_addr, addr);
24065ffcb334SRichard Henderson                 tcg_gen_mov_i64(cpu_lock_value, va);
2407fcf5ef2aSThomas Huth                 break;
2408fcf5ef2aSThomas Huth             case 0x3:
2409fcf5ef2aSThomas Huth                 /* Quadword physical access with lock (hw_ldq_l/p) */
241033948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ | MO_ALIGN);
24115ffcb334SRichard Henderson                 tcg_gen_mov_i64(cpu_lock_addr, addr);
24125ffcb334SRichard Henderson                 tcg_gen_mov_i64(cpu_lock_value, va);
2413fcf5ef2aSThomas Huth                 break;
2414fcf5ef2aSThomas Huth             case 0x4:
2415fcf5ef2aSThomas Huth                 /* Longword virtual PTE fetch (hw_ldl/v) */
2416fcf5ef2aSThomas Huth                 goto invalid_opc;
2417fcf5ef2aSThomas Huth             case 0x5:
2418fcf5ef2aSThomas Huth                 /* Quadword virtual PTE fetch (hw_ldq/v) */
2419fcf5ef2aSThomas Huth                 goto invalid_opc;
2420fcf5ef2aSThomas Huth                 break;
2421fcf5ef2aSThomas Huth             case 0x6:
2422fcf5ef2aSThomas Huth                 /* Invalid */
2423fcf5ef2aSThomas Huth                 goto invalid_opc;
2424fcf5ef2aSThomas Huth             case 0x7:
2425fcf5ef2aSThomas Huth                 /* Invaliid */
2426fcf5ef2aSThomas Huth                 goto invalid_opc;
2427fcf5ef2aSThomas Huth             case 0x8:
2428fcf5ef2aSThomas Huth                 /* Longword virtual access (hw_ldl) */
2429fcf5ef2aSThomas Huth                 goto invalid_opc;
2430fcf5ef2aSThomas Huth             case 0x9:
2431fcf5ef2aSThomas Huth                 /* Quadword virtual access (hw_ldq) */
2432fcf5ef2aSThomas Huth                 goto invalid_opc;
2433fcf5ef2aSThomas Huth             case 0xA:
2434fcf5ef2aSThomas Huth                 /* Longword virtual access with protection check (hw_ldl/w) */
243533948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX,
243633948b68SRichard Henderson                                     MO_LESL | MO_ALIGN);
2437fcf5ef2aSThomas Huth                 break;
2438fcf5ef2aSThomas Huth             case 0xB:
2439fcf5ef2aSThomas Huth                 /* Quadword virtual access with protection check (hw_ldq/w) */
244033948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX,
244133948b68SRichard Henderson                                     MO_LEUQ | MO_ALIGN);
2442fcf5ef2aSThomas Huth                 break;
2443fcf5ef2aSThomas Huth             case 0xC:
2444fcf5ef2aSThomas Huth                 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2445fcf5ef2aSThomas Huth                 goto invalid_opc;
2446fcf5ef2aSThomas Huth             case 0xD:
2447fcf5ef2aSThomas Huth                 /* Quadword virtual access with alt access mode (hw_ldq/a) */
2448fcf5ef2aSThomas Huth                 goto invalid_opc;
2449fcf5ef2aSThomas Huth             case 0xE:
2450fcf5ef2aSThomas Huth                 /* Longword virtual access with alternate access mode and
2451fcf5ef2aSThomas Huth                    protection checks (hw_ldl/wa) */
245233948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX,
245333948b68SRichard Henderson                                     MO_LESL | MO_ALIGN);
2454fcf5ef2aSThomas Huth                 break;
2455fcf5ef2aSThomas Huth             case 0xF:
2456fcf5ef2aSThomas Huth                 /* Quadword virtual access with alternate access mode and
2457fcf5ef2aSThomas Huth                    protection checks (hw_ldq/wa) */
245833948b68SRichard Henderson                 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX,
245933948b68SRichard Henderson                                     MO_LEUQ | MO_ALIGN);
2460fcf5ef2aSThomas Huth                 break;
2461fcf5ef2aSThomas Huth             }
2462fcf5ef2aSThomas Huth             break;
2463fcf5ef2aSThomas Huth         }
2464fcf5ef2aSThomas Huth #else
2465fcf5ef2aSThomas Huth         goto invalid_opc;
2466fcf5ef2aSThomas Huth #endif
2467fcf5ef2aSThomas Huth 
2468fcf5ef2aSThomas Huth     case 0x1C:
2469fcf5ef2aSThomas Huth         vc = dest_gpr(ctx, rc);
2470fcf5ef2aSThomas Huth         if (fn7 == 0x70) {
2471fcf5ef2aSThomas Huth             /* FTOIT */
2472c6d41b36SRichard Henderson             REQUIRE_AMASK(FIX);
2473fcf5ef2aSThomas Huth             REQUIRE_REG_31(rb);
2474fcf5ef2aSThomas Huth             va = load_fpr(ctx, ra);
2475fcf5ef2aSThomas Huth             tcg_gen_mov_i64(vc, va);
2476fcf5ef2aSThomas Huth             break;
2477fcf5ef2aSThomas Huth         } else if (fn7 == 0x78) {
2478fcf5ef2aSThomas Huth             /* FTOIS */
2479c6d41b36SRichard Henderson             REQUIRE_AMASK(FIX);
2480fcf5ef2aSThomas Huth             REQUIRE_REG_31(rb);
2481fcf5ef2aSThomas Huth             t32 = tcg_temp_new_i32();
2482fcf5ef2aSThomas Huth             va = load_fpr(ctx, ra);
2483fcf5ef2aSThomas Huth             gen_helper_s_to_memory(t32, va);
2484fcf5ef2aSThomas Huth             tcg_gen_ext_i32_i64(vc, t32);
2485fcf5ef2aSThomas Huth             break;
2486fcf5ef2aSThomas Huth         }
2487fcf5ef2aSThomas Huth 
2488fcf5ef2aSThomas Huth         vb = load_gpr_lit(ctx, rb, lit, islit);
2489fcf5ef2aSThomas Huth         switch (fn7) {
2490fcf5ef2aSThomas Huth         case 0x00:
2491fcf5ef2aSThomas Huth             /* SEXTB */
2492c6d41b36SRichard Henderson             REQUIRE_AMASK(BWX);
2493fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2494fcf5ef2aSThomas Huth             tcg_gen_ext8s_i64(vc, vb);
2495fcf5ef2aSThomas Huth             break;
2496fcf5ef2aSThomas Huth         case 0x01:
2497fcf5ef2aSThomas Huth             /* SEXTW */
2498c6d41b36SRichard Henderson             REQUIRE_AMASK(BWX);
2499fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2500fcf5ef2aSThomas Huth             tcg_gen_ext16s_i64(vc, vb);
2501fcf5ef2aSThomas Huth             break;
2502fcf5ef2aSThomas Huth         case 0x30:
2503fcf5ef2aSThomas Huth             /* CTPOP */
2504c6d41b36SRichard Henderson             REQUIRE_AMASK(CIX);
2505fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2506fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2507de26a584SRichard Henderson             tcg_gen_ctpop_i64(vc, vb);
2508fcf5ef2aSThomas Huth             break;
2509fcf5ef2aSThomas Huth         case 0x31:
2510fcf5ef2aSThomas Huth             /* PERR */
2511c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2512fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2513fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2514fcf5ef2aSThomas Huth             gen_helper_perr(vc, va, vb);
2515fcf5ef2aSThomas Huth             break;
2516fcf5ef2aSThomas Huth         case 0x32:
2517fcf5ef2aSThomas Huth             /* CTLZ */
2518c6d41b36SRichard Henderson             REQUIRE_AMASK(CIX);
2519fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2520fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2521881549daSRichard Henderson             tcg_gen_clzi_i64(vc, vb, 64);
2522fcf5ef2aSThomas Huth             break;
2523fcf5ef2aSThomas Huth         case 0x33:
2524fcf5ef2aSThomas Huth             /* CTTZ */
2525c6d41b36SRichard Henderson             REQUIRE_AMASK(CIX);
2526fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2527fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2528881549daSRichard Henderson             tcg_gen_ctzi_i64(vc, vb, 64);
2529fcf5ef2aSThomas Huth             break;
2530fcf5ef2aSThomas Huth         case 0x34:
2531fcf5ef2aSThomas Huth             /* UNPKBW */
2532c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2533fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2534fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2535fcf5ef2aSThomas Huth             gen_helper_unpkbw(vc, vb);
2536fcf5ef2aSThomas Huth             break;
2537fcf5ef2aSThomas Huth         case 0x35:
2538fcf5ef2aSThomas Huth             /* UNPKBL */
2539c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2540fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2541fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2542fcf5ef2aSThomas Huth             gen_helper_unpkbl(vc, vb);
2543fcf5ef2aSThomas Huth             break;
2544fcf5ef2aSThomas Huth         case 0x36:
2545fcf5ef2aSThomas Huth             /* PKWB */
2546c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2547fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2548fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2549fcf5ef2aSThomas Huth             gen_helper_pkwb(vc, vb);
2550fcf5ef2aSThomas Huth             break;
2551fcf5ef2aSThomas Huth         case 0x37:
2552fcf5ef2aSThomas Huth             /* PKLB */
2553c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2554fcf5ef2aSThomas Huth             REQUIRE_REG_31(ra);
2555fcf5ef2aSThomas Huth             REQUIRE_NO_LIT;
2556fcf5ef2aSThomas Huth             gen_helper_pklb(vc, vb);
2557fcf5ef2aSThomas Huth             break;
2558fcf5ef2aSThomas Huth         case 0x38:
2559fcf5ef2aSThomas Huth             /* MINSB8 */
2560c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2561fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2562fcf5ef2aSThomas Huth             gen_helper_minsb8(vc, va, vb);
2563fcf5ef2aSThomas Huth             break;
2564fcf5ef2aSThomas Huth         case 0x39:
2565fcf5ef2aSThomas Huth             /* MINSW4 */
2566c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2567fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2568fcf5ef2aSThomas Huth             gen_helper_minsw4(vc, va, vb);
2569fcf5ef2aSThomas Huth             break;
2570fcf5ef2aSThomas Huth         case 0x3A:
2571fcf5ef2aSThomas Huth             /* MINUB8 */
2572c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2573fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2574fcf5ef2aSThomas Huth             gen_helper_minub8(vc, va, vb);
2575fcf5ef2aSThomas Huth             break;
2576fcf5ef2aSThomas Huth         case 0x3B:
2577fcf5ef2aSThomas Huth             /* MINUW4 */
2578c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2579fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2580fcf5ef2aSThomas Huth             gen_helper_minuw4(vc, va, vb);
2581fcf5ef2aSThomas Huth             break;
2582fcf5ef2aSThomas Huth         case 0x3C:
2583fcf5ef2aSThomas Huth             /* MAXUB8 */
2584c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2585fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2586fcf5ef2aSThomas Huth             gen_helper_maxub8(vc, va, vb);
2587fcf5ef2aSThomas Huth             break;
2588fcf5ef2aSThomas Huth         case 0x3D:
2589fcf5ef2aSThomas Huth             /* MAXUW4 */
2590c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2591fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2592fcf5ef2aSThomas Huth             gen_helper_maxuw4(vc, va, vb);
2593fcf5ef2aSThomas Huth             break;
2594fcf5ef2aSThomas Huth         case 0x3E:
2595fcf5ef2aSThomas Huth             /* MAXSB8 */
2596c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2597fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2598fcf5ef2aSThomas Huth             gen_helper_maxsb8(vc, va, vb);
2599fcf5ef2aSThomas Huth             break;
2600fcf5ef2aSThomas Huth         case 0x3F:
2601fcf5ef2aSThomas Huth             /* MAXSW4 */
2602c6d41b36SRichard Henderson             REQUIRE_AMASK(MVI);
2603fcf5ef2aSThomas Huth             va = load_gpr(ctx, ra);
2604fcf5ef2aSThomas Huth             gen_helper_maxsw4(vc, va, vb);
2605fcf5ef2aSThomas Huth             break;
2606fcf5ef2aSThomas Huth         default:
2607fcf5ef2aSThomas Huth             goto invalid_opc;
2608fcf5ef2aSThomas Huth         }
2609fcf5ef2aSThomas Huth         break;
2610fcf5ef2aSThomas Huth 
2611fcf5ef2aSThomas Huth     case 0x1D:
2612fcf5ef2aSThomas Huth         /* HW_MTPR (PALcode) */
2613fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
2614bcd2625dSRichard Henderson         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2615fcf5ef2aSThomas Huth         vb = load_gpr(ctx, rb);
2616fcf5ef2aSThomas Huth         ret = gen_mtpr(ctx, vb, insn & 0xffff);
2617fcf5ef2aSThomas Huth         break;
2618fcf5ef2aSThomas Huth #else
2619fcf5ef2aSThomas Huth         goto invalid_opc;
2620fcf5ef2aSThomas Huth #endif
2621fcf5ef2aSThomas Huth 
2622fcf5ef2aSThomas Huth     case 0x1E:
2623fcf5ef2aSThomas Huth         /* HW_RET (PALcode) */
2624fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
2625bcd2625dSRichard Henderson         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2626fcf5ef2aSThomas Huth         if (rb == 31) {
2627fcf5ef2aSThomas Huth             /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
2628fcf5ef2aSThomas Huth                address from EXC_ADDR.  This turns out to be useful for our
2629fcf5ef2aSThomas Huth                emulation PALcode, so continue to accept it.  */
26303e646c3aSRichard Henderson             vb = dest_sink(ctx);
2631ad75a51eSRichard Henderson             tcg_gen_ld_i64(vb, tcg_env, offsetof(CPUAlphaState, exc_addr));
2632fcf5ef2aSThomas Huth         } else {
2633fcf5ef2aSThomas Huth             vb = load_gpr(ctx, rb);
2634fcf5ef2aSThomas Huth         }
2635bcd2625dSRichard Henderson         tcg_gen_movi_i64(cpu_lock_addr, -1);
2636904bd855SRichard Henderson         st_flag_byte(load_zero(ctx), ENV_FLAG_RX_SHIFT);
2637fcf5ef2aSThomas Huth         tmp = tcg_temp_new();
2638fcf5ef2aSThomas Huth         tcg_gen_andi_i64(tmp, vb, 1);
2639bcd2625dSRichard Henderson         st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
2640fcf5ef2aSThomas Huth         tcg_gen_andi_i64(cpu_pc, vb, ~3);
264154e1d4edSRichard Henderson         /* Allow interrupts to be recognized right away.  */
26423de811c6SRichard Henderson         ret = DISAS_PC_UPDATED_NOCHAIN;
2643fcf5ef2aSThomas Huth         break;
2644fcf5ef2aSThomas Huth #else
2645fcf5ef2aSThomas Huth         goto invalid_opc;
2646fcf5ef2aSThomas Huth #endif
2647fcf5ef2aSThomas Huth 
2648fcf5ef2aSThomas Huth     case 0x1F:
2649fcf5ef2aSThomas Huth         /* HW_ST (PALcode) */
2650fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
2651bcd2625dSRichard Henderson         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2652fcf5ef2aSThomas Huth         {
2653fcf5ef2aSThomas Huth             switch ((insn >> 12) & 0xF) {
2654fcf5ef2aSThomas Huth             case 0x0:
2655fcf5ef2aSThomas Huth                 /* Longword physical access */
2656fcf5ef2aSThomas Huth                 va = load_gpr(ctx, ra);
2657fcf5ef2aSThomas Huth                 vb = load_gpr(ctx, rb);
2658fcf5ef2aSThomas Huth                 tmp = tcg_temp_new();
2659fcf5ef2aSThomas Huth                 tcg_gen_addi_i64(tmp, vb, disp12);
266033948b68SRichard Henderson                 tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL | MO_ALIGN);
2661fcf5ef2aSThomas Huth                 break;
2662fcf5ef2aSThomas Huth             case 0x1:
2663fcf5ef2aSThomas Huth                 /* Quadword physical access */
2664fcf5ef2aSThomas Huth                 va = load_gpr(ctx, ra);
2665fcf5ef2aSThomas Huth                 vb = load_gpr(ctx, rb);
2666fcf5ef2aSThomas Huth                 tmp = tcg_temp_new();
2667fcf5ef2aSThomas Huth                 tcg_gen_addi_i64(tmp, vb, disp12);
266833948b68SRichard Henderson                 tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEUQ | MO_ALIGN);
2669fcf5ef2aSThomas Huth                 break;
2670fcf5ef2aSThomas Huth             case 0x2:
2671fcf5ef2aSThomas Huth                 /* Longword physical access with lock */
2672fcf5ef2aSThomas Huth                 ret = gen_store_conditional(ctx, ra, rb, disp12,
267333948b68SRichard Henderson                                             MMU_PHYS_IDX, MO_LESL | MO_ALIGN);
2674fcf5ef2aSThomas Huth                 break;
2675fcf5ef2aSThomas Huth             case 0x3:
2676fcf5ef2aSThomas Huth                 /* Quadword physical access with lock */
2677fcf5ef2aSThomas Huth                 ret = gen_store_conditional(ctx, ra, rb, disp12,
267833948b68SRichard Henderson                                             MMU_PHYS_IDX, MO_LEUQ | MO_ALIGN);
2679fcf5ef2aSThomas Huth                 break;
2680fcf5ef2aSThomas Huth             case 0x4:
2681fcf5ef2aSThomas Huth                 /* Longword virtual access */
2682fcf5ef2aSThomas Huth                 goto invalid_opc;
2683fcf5ef2aSThomas Huth             case 0x5:
2684fcf5ef2aSThomas Huth                 /* Quadword virtual access */
2685fcf5ef2aSThomas Huth                 goto invalid_opc;
2686fcf5ef2aSThomas Huth             case 0x6:
2687fcf5ef2aSThomas Huth                 /* Invalid */
2688fcf5ef2aSThomas Huth                 goto invalid_opc;
2689fcf5ef2aSThomas Huth             case 0x7:
2690fcf5ef2aSThomas Huth                 /* Invalid */
2691fcf5ef2aSThomas Huth                 goto invalid_opc;
2692fcf5ef2aSThomas Huth             case 0x8:
2693fcf5ef2aSThomas Huth                 /* Invalid */
2694fcf5ef2aSThomas Huth                 goto invalid_opc;
2695fcf5ef2aSThomas Huth             case 0x9:
2696fcf5ef2aSThomas Huth                 /* Invalid */
2697fcf5ef2aSThomas Huth                 goto invalid_opc;
2698fcf5ef2aSThomas Huth             case 0xA:
2699fcf5ef2aSThomas Huth                 /* Invalid */
2700fcf5ef2aSThomas Huth                 goto invalid_opc;
2701fcf5ef2aSThomas Huth             case 0xB:
2702fcf5ef2aSThomas Huth                 /* Invalid */
2703fcf5ef2aSThomas Huth                 goto invalid_opc;
2704fcf5ef2aSThomas Huth             case 0xC:
2705fcf5ef2aSThomas Huth                 /* Longword virtual access with alternate access mode */
2706fcf5ef2aSThomas Huth                 goto invalid_opc;
2707fcf5ef2aSThomas Huth             case 0xD:
2708fcf5ef2aSThomas Huth                 /* Quadword virtual access with alternate access mode */
2709fcf5ef2aSThomas Huth                 goto invalid_opc;
2710fcf5ef2aSThomas Huth             case 0xE:
2711fcf5ef2aSThomas Huth                 /* Invalid */
2712fcf5ef2aSThomas Huth                 goto invalid_opc;
2713fcf5ef2aSThomas Huth             case 0xF:
2714fcf5ef2aSThomas Huth                 /* Invalid */
2715fcf5ef2aSThomas Huth                 goto invalid_opc;
2716fcf5ef2aSThomas Huth             }
2717fcf5ef2aSThomas Huth             break;
2718fcf5ef2aSThomas Huth         }
2719fcf5ef2aSThomas Huth #else
2720fcf5ef2aSThomas Huth         goto invalid_opc;
2721fcf5ef2aSThomas Huth #endif
2722fcf5ef2aSThomas Huth     case 0x20:
2723fcf5ef2aSThomas Huth         /* LDF */
27249d14a042SRichard Henderson         REQUIRE_FEN;
272545263531SRichard Henderson         gen_load_fp(ctx, ra, rb, disp16, gen_ldf);
2726fcf5ef2aSThomas Huth         break;
2727fcf5ef2aSThomas Huth     case 0x21:
2728fcf5ef2aSThomas Huth         /* LDG */
27299d14a042SRichard Henderson         REQUIRE_FEN;
273045263531SRichard Henderson         gen_load_fp(ctx, ra, rb, disp16, gen_ldg);
2731fcf5ef2aSThomas Huth         break;
2732fcf5ef2aSThomas Huth     case 0x22:
2733fcf5ef2aSThomas Huth         /* LDS */
27349d14a042SRichard Henderson         REQUIRE_FEN;
273545263531SRichard Henderson         gen_load_fp(ctx, ra, rb, disp16, gen_lds);
2736fcf5ef2aSThomas Huth         break;
2737fcf5ef2aSThomas Huth     case 0x23:
2738fcf5ef2aSThomas Huth         /* LDT */
27399d14a042SRichard Henderson         REQUIRE_FEN;
274045263531SRichard Henderson         gen_load_fp(ctx, ra, rb, disp16, gen_ldt);
2741fcf5ef2aSThomas Huth         break;
2742fcf5ef2aSThomas Huth     case 0x24:
2743fcf5ef2aSThomas Huth         /* STF */
27449d14a042SRichard Henderson         REQUIRE_FEN;
274545263531SRichard Henderson         gen_store_fp(ctx, ra, rb, disp16, gen_stf);
2746fcf5ef2aSThomas Huth         break;
2747fcf5ef2aSThomas Huth     case 0x25:
2748fcf5ef2aSThomas Huth         /* STG */
27499d14a042SRichard Henderson         REQUIRE_FEN;
275045263531SRichard Henderson         gen_store_fp(ctx, ra, rb, disp16, gen_stg);
2751fcf5ef2aSThomas Huth         break;
2752fcf5ef2aSThomas Huth     case 0x26:
2753fcf5ef2aSThomas Huth         /* STS */
27549d14a042SRichard Henderson         REQUIRE_FEN;
275545263531SRichard Henderson         gen_store_fp(ctx, ra, rb, disp16, gen_sts);
2756fcf5ef2aSThomas Huth         break;
2757fcf5ef2aSThomas Huth     case 0x27:
2758fcf5ef2aSThomas Huth         /* STT */
27599d14a042SRichard Henderson         REQUIRE_FEN;
276045263531SRichard Henderson         gen_store_fp(ctx, ra, rb, disp16, gen_stt);
2761fcf5ef2aSThomas Huth         break;
2762fcf5ef2aSThomas Huth     case 0x28:
2763fcf5ef2aSThomas Huth         /* LDL */
27645ffcb334SRichard Henderson         gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 0);
2765fcf5ef2aSThomas Huth         break;
2766fcf5ef2aSThomas Huth     case 0x29:
2767fcf5ef2aSThomas Huth         /* LDQ */
2768fc313c64SFrédéric Pétrot         gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 0);
2769fcf5ef2aSThomas Huth         break;
2770fcf5ef2aSThomas Huth     case 0x2A:
2771fcf5ef2aSThomas Huth         /* LDL_L */
277233948b68SRichard Henderson         gen_load_int(ctx, ra, rb, disp16, MO_LESL | MO_ALIGN, 0, 1);
2773fcf5ef2aSThomas Huth         break;
2774fcf5ef2aSThomas Huth     case 0x2B:
2775fcf5ef2aSThomas Huth         /* LDQ_L */
277633948b68SRichard Henderson         gen_load_int(ctx, ra, rb, disp16, MO_LEUQ | MO_ALIGN, 0, 1);
2777fcf5ef2aSThomas Huth         break;
2778fcf5ef2aSThomas Huth     case 0x2C:
2779fcf5ef2aSThomas Huth         /* STL */
27805ffcb334SRichard Henderson         gen_store_int(ctx, ra, rb, disp16, MO_LEUL, 0);
2781fcf5ef2aSThomas Huth         break;
2782fcf5ef2aSThomas Huth     case 0x2D:
2783fcf5ef2aSThomas Huth         /* STQ */
2784fc313c64SFrédéric Pétrot         gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 0);
2785fcf5ef2aSThomas Huth         break;
2786fcf5ef2aSThomas Huth     case 0x2E:
2787fcf5ef2aSThomas Huth         /* STL_C */
2788fcf5ef2aSThomas Huth         ret = gen_store_conditional(ctx, ra, rb, disp16,
278933948b68SRichard Henderson                                     ctx->mem_idx, MO_LESL | MO_ALIGN);
2790fcf5ef2aSThomas Huth         break;
2791fcf5ef2aSThomas Huth     case 0x2F:
2792fcf5ef2aSThomas Huth         /* STQ_C */
2793fcf5ef2aSThomas Huth         ret = gen_store_conditional(ctx, ra, rb, disp16,
279433948b68SRichard Henderson                                     ctx->mem_idx, MO_LEUQ | MO_ALIGN);
2795fcf5ef2aSThomas Huth         break;
2796fcf5ef2aSThomas Huth     case 0x30:
2797fcf5ef2aSThomas Huth         /* BR */
2798fcf5ef2aSThomas Huth         ret = gen_bdirect(ctx, ra, disp21);
2799fcf5ef2aSThomas Huth         break;
2800fcf5ef2aSThomas Huth     case 0x31: /* FBEQ */
28019d14a042SRichard Henderson         REQUIRE_FEN;
2802fcf5ef2aSThomas Huth         ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
2803fcf5ef2aSThomas Huth         break;
2804fcf5ef2aSThomas Huth     case 0x32: /* FBLT */
28059d14a042SRichard Henderson         REQUIRE_FEN;
2806fcf5ef2aSThomas Huth         ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
2807fcf5ef2aSThomas Huth         break;
2808fcf5ef2aSThomas Huth     case 0x33: /* FBLE */
28099d14a042SRichard Henderson         REQUIRE_FEN;
2810fcf5ef2aSThomas Huth         ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
2811fcf5ef2aSThomas Huth         break;
2812fcf5ef2aSThomas Huth     case 0x34:
2813fcf5ef2aSThomas Huth         /* BSR */
2814fcf5ef2aSThomas Huth         ret = gen_bdirect(ctx, ra, disp21);
2815fcf5ef2aSThomas Huth         break;
2816fcf5ef2aSThomas Huth     case 0x35: /* FBNE */
28179d14a042SRichard Henderson         REQUIRE_FEN;
2818fcf5ef2aSThomas Huth         ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
2819fcf5ef2aSThomas Huth         break;
2820fcf5ef2aSThomas Huth     case 0x36: /* FBGE */
28219d14a042SRichard Henderson         REQUIRE_FEN;
2822fcf5ef2aSThomas Huth         ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
2823fcf5ef2aSThomas Huth         break;
2824fcf5ef2aSThomas Huth     case 0x37: /* FBGT */
28259d14a042SRichard Henderson         REQUIRE_FEN;
2826fcf5ef2aSThomas Huth         ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
2827fcf5ef2aSThomas Huth         break;
2828fcf5ef2aSThomas Huth     case 0x38:
2829fcf5ef2aSThomas Huth         /* BLBC */
2830fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
2831fcf5ef2aSThomas Huth         break;
2832fcf5ef2aSThomas Huth     case 0x39:
2833fcf5ef2aSThomas Huth         /* BEQ */
2834fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
2835fcf5ef2aSThomas Huth         break;
2836fcf5ef2aSThomas Huth     case 0x3A:
2837fcf5ef2aSThomas Huth         /* BLT */
2838fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
2839fcf5ef2aSThomas Huth         break;
2840fcf5ef2aSThomas Huth     case 0x3B:
2841fcf5ef2aSThomas Huth         /* BLE */
2842fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
2843fcf5ef2aSThomas Huth         break;
2844fcf5ef2aSThomas Huth     case 0x3C:
2845fcf5ef2aSThomas Huth         /* BLBS */
2846fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
2847fcf5ef2aSThomas Huth         break;
2848fcf5ef2aSThomas Huth     case 0x3D:
2849fcf5ef2aSThomas Huth         /* BNE */
2850fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
2851fcf5ef2aSThomas Huth         break;
2852fcf5ef2aSThomas Huth     case 0x3E:
2853fcf5ef2aSThomas Huth         /* BGE */
2854fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
2855fcf5ef2aSThomas Huth         break;
2856fcf5ef2aSThomas Huth     case 0x3F:
2857fcf5ef2aSThomas Huth         /* BGT */
2858fcf5ef2aSThomas Huth         ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
2859fcf5ef2aSThomas Huth         break;
2860fcf5ef2aSThomas Huth     invalid_opc:
2861fcf5ef2aSThomas Huth         ret = gen_invalid(ctx);
2862fcf5ef2aSThomas Huth         break;
28639d14a042SRichard Henderson     raise_fen:
28649d14a042SRichard Henderson         ret = gen_excp(ctx, EXCP_FEN, 0);
28659d14a042SRichard Henderson         break;
2866fcf5ef2aSThomas Huth     }
2867fcf5ef2aSThomas Huth 
2868fcf5ef2aSThomas Huth     return ret;
2869fcf5ef2aSThomas Huth }
2870fcf5ef2aSThomas Huth 
alpha_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cpu)2871b542683dSEmilio G. Cota static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
2872fcf5ef2aSThomas Huth {
287399a92b94SRichard Henderson     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2874*b77af26eSRichard Henderson     CPUAlphaState *env = cpu_env(cpu);
28753fd3442aSRichard Henderson     int64_t bound;
2876fcf5ef2aSThomas Huth 
287799a92b94SRichard Henderson     ctx->tbflags = ctx->base.tb->flags;
287899a92b94SRichard Henderson     ctx->mem_idx = cpu_mmu_index(env, false);
287999a92b94SRichard Henderson     ctx->implver = env->implver;
288099a92b94SRichard Henderson     ctx->amask = env->amask;
2881fcf5ef2aSThomas Huth 
2882fcf5ef2aSThomas Huth #ifdef CONFIG_USER_ONLY
288399a92b94SRichard Henderson     ctx->ir = cpu_std_ir;
2884fed14246SRichard Henderson     ctx->unalign = (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
2885fcf5ef2aSThomas Huth #else
288699a92b94SRichard Henderson     ctx->palbr = env->palbr;
288799a92b94SRichard Henderson     ctx->ir = (ctx->tbflags & ENV_FLAG_PAL_MODE ? cpu_pal_ir : cpu_std_ir);
2888fcf5ef2aSThomas Huth #endif
2889fcf5ef2aSThomas Huth 
2890fcf5ef2aSThomas Huth     /* ??? Every TB begins with unset rounding mode, to be initialized on
2891fcf5ef2aSThomas Huth        the first fp insn of the TB.  Alternately we could define a proper
2892fcf5ef2aSThomas Huth        default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
2893fcf5ef2aSThomas Huth        to reset the FP_STATUS to that default at the end of any TB that
28948b81968cSMichael Tokarev        changes the default.  We could even (gasp) dynamically figure out
2895fcf5ef2aSThomas Huth        what default would be most efficient given the running program.  */
289699a92b94SRichard Henderson     ctx->tb_rm = -1;
2897fcf5ef2aSThomas Huth     /* Similarly for flush-to-zero.  */
289899a92b94SRichard Henderson     ctx->tb_ftz = -1;
2899fcf5ef2aSThomas Huth 
2900f764718dSRichard Henderson     ctx->zero = NULL;
2901f764718dSRichard Henderson     ctx->sink = NULL;
2902fcf5ef2aSThomas Huth 
290399a92b94SRichard Henderson     /* Bound the number of insns to execute to those left on the page.  */
29043fd3442aSRichard Henderson     bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
2905b542683dSEmilio G. Cota     ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2906fcf5ef2aSThomas Huth }
2907fcf5ef2aSThomas Huth 
alpha_tr_tb_start(DisasContextBase * db,CPUState * cpu)290899a92b94SRichard Henderson static void alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu)
290999a92b94SRichard Henderson {
291099a92b94SRichard Henderson }
29118aa5c65fSRichard Henderson 
alpha_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)291299a92b94SRichard Henderson static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
291399a92b94SRichard Henderson {
291499a92b94SRichard Henderson     tcg_gen_insn_start(dcbase->pc_next);
291599a92b94SRichard Henderson }
2916fcf5ef2aSThomas Huth 
alpha_tr_translate_insn(DisasContextBase * dcbase,CPUState * cpu)291799a92b94SRichard Henderson static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
291899a92b94SRichard Henderson {
291999a92b94SRichard Henderson     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2920*b77af26eSRichard Henderson     CPUAlphaState *env = cpu_env(cpu);
29214e116893SIlya Leoshkevich     uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);
2922fcf5ef2aSThomas Huth 
292399a92b94SRichard Henderson     ctx->base.pc_next += 4;
292499a92b94SRichard Henderson     ctx->base.is_jmp = translate_one(ctx, insn);
292599a92b94SRichard Henderson 
292699a92b94SRichard Henderson     free_context_temps(ctx);
2927fcf5ef2aSThomas Huth }
2928fcf5ef2aSThomas Huth 
alpha_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)292999a92b94SRichard Henderson static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
293099a92b94SRichard Henderson {
293199a92b94SRichard Henderson     DisasContext *ctx = container_of(dcbase, DisasContext, base);
293299a92b94SRichard Henderson 
293399a92b94SRichard Henderson     switch (ctx->base.is_jmp) {
29343de811c6SRichard Henderson     case DISAS_NORETURN:
2935fcf5ef2aSThomas Huth         break;
29363de811c6SRichard Henderson     case DISAS_TOO_MANY:
293799a92b94SRichard Henderson         if (use_goto_tb(ctx, ctx->base.pc_next)) {
29382d826cdcSRichard Henderson             tcg_gen_goto_tb(0);
293999a92b94SRichard Henderson             tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
294007ea28b4SRichard Henderson             tcg_gen_exit_tb(ctx->base.tb, 0);
29412d826cdcSRichard Henderson         }
29422d826cdcSRichard Henderson         /* FALLTHRU */
29433de811c6SRichard Henderson     case DISAS_PC_STALE:
294499a92b94SRichard Henderson         tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
2945fcf5ef2aSThomas Huth         /* FALLTHRU */
29463de811c6SRichard Henderson     case DISAS_PC_UPDATED:
29477f11636dSEmilio G. Cota         tcg_gen_lookup_and_goto_ptr();
294854e1d4edSRichard Henderson         break;
29493de811c6SRichard Henderson     case DISAS_PC_UPDATED_NOCHAIN:
295007ea28b4SRichard Henderson         tcg_gen_exit_tb(NULL, 0);
2951fcf5ef2aSThomas Huth         break;
2952fcf5ef2aSThomas Huth     default:
29532d826cdcSRichard Henderson         g_assert_not_reached();
2954fcf5ef2aSThomas Huth     }
2955fcf5ef2aSThomas Huth }
295699a92b94SRichard Henderson 
alpha_tr_disas_log(const DisasContextBase * dcbase,CPUState * cpu,FILE * logfile)29578eb806a7SRichard Henderson static void alpha_tr_disas_log(const DisasContextBase *dcbase,
29588eb806a7SRichard Henderson                                CPUState *cpu, FILE *logfile)
295999a92b94SRichard Henderson {
29608eb806a7SRichard Henderson     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
29618eb806a7SRichard Henderson     target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
296299a92b94SRichard Henderson }
296399a92b94SRichard Henderson 
296499a92b94SRichard Henderson static const TranslatorOps alpha_tr_ops = {
296599a92b94SRichard Henderson     .init_disas_context = alpha_tr_init_disas_context,
296699a92b94SRichard Henderson     .tb_start           = alpha_tr_tb_start,
296799a92b94SRichard Henderson     .insn_start         = alpha_tr_insn_start,
296899a92b94SRichard Henderson     .translate_insn     = alpha_tr_translate_insn,
296999a92b94SRichard Henderson     .tb_stop            = alpha_tr_tb_stop,
297099a92b94SRichard Henderson     .disas_log          = alpha_tr_disas_log,
297199a92b94SRichard Henderson };
297299a92b94SRichard Henderson 
gen_intermediate_code(CPUState * cpu,TranslationBlock * tb,int * max_insns,target_ulong pc,void * host_pc)2973597f9b2dSRichard Henderson void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
2974306c8721SRichard Henderson                            target_ulong pc, void *host_pc)
297599a92b94SRichard Henderson {
297699a92b94SRichard Henderson     DisasContext dc;
2977306c8721SRichard Henderson     translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
2978fcf5ef2aSThomas Huth }
2979