Statistics
| Branch: | Revision:

root / target-unicore32 / translate.c @ 6ce2d77a

History | View | Annotate | Download (56.9 kB)

1 6e64da3c Guan Xuetao
/*
2 6e64da3c Guan Xuetao
 *  UniCore32 translation
3 6e64da3c Guan Xuetao
 *
4 6e64da3c Guan Xuetao
 * Copyright (C) 2010-2011 GUAN Xue-tao
5 6e64da3c Guan Xuetao
 *
6 6e64da3c Guan Xuetao
 * This program is free software; you can redistribute it and/or modify
7 6e64da3c Guan Xuetao
 * it under the terms of the GNU General Public License version 2 as
8 6e64da3c Guan Xuetao
 * published by the Free Software Foundation.
9 6e64da3c Guan Xuetao
 */
10 6e64da3c Guan Xuetao
#include <stdarg.h>
11 6e64da3c Guan Xuetao
#include <stdlib.h>
12 6e64da3c Guan Xuetao
#include <stdio.h>
13 6e64da3c Guan Xuetao
#include <string.h>
14 6e64da3c Guan Xuetao
#include <inttypes.h>
15 6e64da3c Guan Xuetao
16 6e64da3c Guan Xuetao
#include "cpu.h"
17 6e64da3c Guan Xuetao
#include "disas.h"
18 6e64da3c Guan Xuetao
#include "tcg-op.h"
19 6e64da3c Guan Xuetao
#include "qemu-log.h"
20 6e64da3c Guan Xuetao
21 6e64da3c Guan Xuetao
#include "helper.h"
22 6e64da3c Guan Xuetao
#define GEN_HELPER 1
23 6e64da3c Guan Xuetao
#include "helper.h"
24 6e64da3c Guan Xuetao
25 6e64da3c Guan Xuetao
/* internal defines */
26 6e64da3c Guan Xuetao
typedef struct DisasContext {
27 6e64da3c Guan Xuetao
    target_ulong pc;
28 6e64da3c Guan Xuetao
    int is_jmp;
29 6e64da3c Guan Xuetao
    /* Nonzero if this instruction has been conditionally skipped.  */
30 6e64da3c Guan Xuetao
    int condjmp;
31 6e64da3c Guan Xuetao
    /* The label that will be jumped to when the instruction is skipped.  */
32 6e64da3c Guan Xuetao
    int condlabel;
33 6e64da3c Guan Xuetao
    struct TranslationBlock *tb;
34 6e64da3c Guan Xuetao
    int singlestep_enabled;
35 6e64da3c Guan Xuetao
} DisasContext;
36 6e64da3c Guan Xuetao
37 6e64da3c Guan Xuetao
#define IS_USER(s) 1
38 6e64da3c Guan Xuetao
39 6e64da3c Guan Xuetao
/* These instructions trap after executing, so defer them until after the
40 6e64da3c Guan Xuetao
   conditional executions state has been updated.  */
41 6e64da3c Guan Xuetao
#define DISAS_SYSCALL 5
42 6e64da3c Guan Xuetao
43 6e64da3c Guan Xuetao
static TCGv_ptr cpu_env;
44 6e64da3c Guan Xuetao
static TCGv_i32 cpu_R[32];
45 6e64da3c Guan Xuetao
46 6e64da3c Guan Xuetao
/* FIXME:  These should be removed.  */
47 6e64da3c Guan Xuetao
static TCGv cpu_F0s, cpu_F1s;
48 6e64da3c Guan Xuetao
static TCGv_i64 cpu_F0d, cpu_F1d;
49 6e64da3c Guan Xuetao
50 6e64da3c Guan Xuetao
#include "gen-icount.h"
51 6e64da3c Guan Xuetao
52 6e64da3c Guan Xuetao
static const char *regnames[] = {
53 6e64da3c Guan Xuetao
      "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
54 6e64da3c Guan Xuetao
      "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
55 6e64da3c Guan Xuetao
      "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
56 6e64da3c Guan Xuetao
      "r24", "r25", "r26", "r27", "r28", "r29", "r30", "pc" };
57 6e64da3c Guan Xuetao
58 6e64da3c Guan Xuetao
/* initialize TCG globals.  */
59 6e64da3c Guan Xuetao
void uc32_translate_init(void)
60 6e64da3c Guan Xuetao
{
61 6e64da3c Guan Xuetao
    int i;
62 6e64da3c Guan Xuetao
63 6e64da3c Guan Xuetao
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
64 6e64da3c Guan Xuetao
65 6e64da3c Guan Xuetao
    for (i = 0; i < 32; i++) {
66 6e64da3c Guan Xuetao
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
67 6e64da3c Guan Xuetao
                                offsetof(CPUState, regs[i]), regnames[i]);
68 6e64da3c Guan Xuetao
    }
69 6e64da3c Guan Xuetao
70 6e64da3c Guan Xuetao
#define GEN_HELPER 2
71 6e64da3c Guan Xuetao
#include "helper.h"
72 6e64da3c Guan Xuetao
}
73 6e64da3c Guan Xuetao
74 6e64da3c Guan Xuetao
static int num_temps;
75 6e64da3c Guan Xuetao
76 6e64da3c Guan Xuetao
/* Allocate a temporary variable.  */
77 6e64da3c Guan Xuetao
static TCGv_i32 new_tmp(void)
78 6e64da3c Guan Xuetao
{
79 6e64da3c Guan Xuetao
    num_temps++;
80 6e64da3c Guan Xuetao
    return tcg_temp_new_i32();
81 6e64da3c Guan Xuetao
}
82 6e64da3c Guan Xuetao
83 6e64da3c Guan Xuetao
/* Release a temporary variable.  */
84 6e64da3c Guan Xuetao
static void dead_tmp(TCGv tmp)
85 6e64da3c Guan Xuetao
{
86 6e64da3c Guan Xuetao
    tcg_temp_free(tmp);
87 6e64da3c Guan Xuetao
    num_temps--;
88 6e64da3c Guan Xuetao
}
89 6e64da3c Guan Xuetao
90 6e64da3c Guan Xuetao
static inline TCGv load_cpu_offset(int offset)
91 6e64da3c Guan Xuetao
{
92 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
93 6e64da3c Guan Xuetao
    tcg_gen_ld_i32(tmp, cpu_env, offset);
94 6e64da3c Guan Xuetao
    return tmp;
95 6e64da3c Guan Xuetao
}
96 6e64da3c Guan Xuetao
97 6e64da3c Guan Xuetao
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
98 6e64da3c Guan Xuetao
99 6e64da3c Guan Xuetao
static inline void store_cpu_offset(TCGv var, int offset)
100 6e64da3c Guan Xuetao
{
101 6e64da3c Guan Xuetao
    tcg_gen_st_i32(var, cpu_env, offset);
102 6e64da3c Guan Xuetao
    dead_tmp(var);
103 6e64da3c Guan Xuetao
}
104 6e64da3c Guan Xuetao
105 6e64da3c Guan Xuetao
#define store_cpu_field(var, name) \
106 6e64da3c Guan Xuetao
    store_cpu_offset(var, offsetof(CPUState, name))
107 6e64da3c Guan Xuetao
108 6e64da3c Guan Xuetao
/* Set a variable to the value of a CPU register.  */
109 6e64da3c Guan Xuetao
static void load_reg_var(DisasContext *s, TCGv var, int reg)
110 6e64da3c Guan Xuetao
{
111 6e64da3c Guan Xuetao
    if (reg == 31) {
112 6e64da3c Guan Xuetao
        uint32_t addr;
113 6e64da3c Guan Xuetao
        /* normaly, since we updated PC */
114 6e64da3c Guan Xuetao
        addr = (long)s->pc;
115 6e64da3c Guan Xuetao
        tcg_gen_movi_i32(var, addr);
116 6e64da3c Guan Xuetao
    } else {
117 6e64da3c Guan Xuetao
        tcg_gen_mov_i32(var, cpu_R[reg]);
118 6e64da3c Guan Xuetao
    }
119 6e64da3c Guan Xuetao
}
120 6e64da3c Guan Xuetao
121 6e64da3c Guan Xuetao
/* Create a new temporary and set it to the value of a CPU register.  */
122 6e64da3c Guan Xuetao
static inline TCGv load_reg(DisasContext *s, int reg)
123 6e64da3c Guan Xuetao
{
124 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
125 6e64da3c Guan Xuetao
    load_reg_var(s, tmp, reg);
126 6e64da3c Guan Xuetao
    return tmp;
127 6e64da3c Guan Xuetao
}
128 6e64da3c Guan Xuetao
129 6e64da3c Guan Xuetao
/* Set a CPU register.  The source must be a temporary and will be
130 6e64da3c Guan Xuetao
   marked as dead.  */
131 6e64da3c Guan Xuetao
static void store_reg(DisasContext *s, int reg, TCGv var)
132 6e64da3c Guan Xuetao
{
133 6e64da3c Guan Xuetao
    if (reg == 31) {
134 6e64da3c Guan Xuetao
        tcg_gen_andi_i32(var, var, ~3);
135 6e64da3c Guan Xuetao
        s->is_jmp = DISAS_JUMP;
136 6e64da3c Guan Xuetao
    }
137 6e64da3c Guan Xuetao
    tcg_gen_mov_i32(cpu_R[reg], var);
138 6e64da3c Guan Xuetao
    dead_tmp(var);
139 6e64da3c Guan Xuetao
}
140 6e64da3c Guan Xuetao
141 6e64da3c Guan Xuetao
/* Value extensions.  */
142 6e64da3c Guan Xuetao
#define gen_uxtb(var)           tcg_gen_ext8u_i32(var, var)
143 6e64da3c Guan Xuetao
#define gen_uxth(var)           tcg_gen_ext16u_i32(var, var)
144 6e64da3c Guan Xuetao
#define gen_sxtb(var)           tcg_gen_ext8s_i32(var, var)
145 6e64da3c Guan Xuetao
#define gen_sxth(var)           tcg_gen_ext16s_i32(var, var)
146 6e64da3c Guan Xuetao
147 6e64da3c Guan Xuetao
#define UCOP_REG_M              (((insn) >>  0) & 0x1f)
148 6e64da3c Guan Xuetao
#define UCOP_REG_N              (((insn) >> 19) & 0x1f)
149 6e64da3c Guan Xuetao
#define UCOP_REG_D              (((insn) >> 14) & 0x1f)
150 6e64da3c Guan Xuetao
#define UCOP_REG_S              (((insn) >>  9) & 0x1f)
151 6e64da3c Guan Xuetao
#define UCOP_REG_LO             (((insn) >> 14) & 0x1f)
152 6e64da3c Guan Xuetao
#define UCOP_REG_HI             (((insn) >>  9) & 0x1f)
153 6e64da3c Guan Xuetao
#define UCOP_SH_OP              (((insn) >>  6) & 0x03)
154 6e64da3c Guan Xuetao
#define UCOP_SH_IM              (((insn) >>  9) & 0x1f)
155 6e64da3c Guan Xuetao
#define UCOP_OPCODES            (((insn) >> 25) & 0x0f)
156 6e64da3c Guan Xuetao
#define UCOP_IMM_9              (((insn) >>  0) & 0x1ff)
157 6e64da3c Guan Xuetao
#define UCOP_IMM10              (((insn) >>  0) & 0x3ff)
158 6e64da3c Guan Xuetao
#define UCOP_IMM14              (((insn) >>  0) & 0x3fff)
159 6e64da3c Guan Xuetao
#define UCOP_COND               (((insn) >> 25) & 0x0f)
160 6e64da3c Guan Xuetao
#define UCOP_CMOV_COND          (((insn) >> 19) & 0x0f)
161 6e64da3c Guan Xuetao
#define UCOP_CPNUM              (((insn) >> 10) & 0x0f)
162 6e64da3c Guan Xuetao
#define UCOP_UCF64_FMT          (((insn) >> 24) & 0x03)
163 6e64da3c Guan Xuetao
#define UCOP_UCF64_FUNC         (((insn) >>  6) & 0x0f)
164 6e64da3c Guan Xuetao
#define UCOP_UCF64_COND         (((insn) >>  6) & 0x0f)
165 6e64da3c Guan Xuetao
166 6e64da3c Guan Xuetao
#define UCOP_SET(i)             ((insn) & (1 << (i)))
167 6e64da3c Guan Xuetao
#define UCOP_SET_P              UCOP_SET(28)
168 6e64da3c Guan Xuetao
#define UCOP_SET_U              UCOP_SET(27)
169 6e64da3c Guan Xuetao
#define UCOP_SET_B              UCOP_SET(26)
170 6e64da3c Guan Xuetao
#define UCOP_SET_W              UCOP_SET(25)
171 6e64da3c Guan Xuetao
#define UCOP_SET_L              UCOP_SET(24)
172 6e64da3c Guan Xuetao
#define UCOP_SET_S              UCOP_SET(24)
173 6e64da3c Guan Xuetao
174 6e64da3c Guan Xuetao
#define ILLEGAL         cpu_abort(env,                                  \
175 6e64da3c Guan Xuetao
                        "Illegal UniCore32 instruction %x at line %d!", \
176 6e64da3c Guan Xuetao
                        insn, __LINE__)
177 6e64da3c Guan Xuetao
178 6e64da3c Guan Xuetao
static inline void gen_set_asr(TCGv var, uint32_t mask)
179 6e64da3c Guan Xuetao
{
180 6e64da3c Guan Xuetao
    TCGv tmp_mask = tcg_const_i32(mask);
181 6e64da3c Guan Xuetao
    gen_helper_asr_write(var, tmp_mask);
182 6e64da3c Guan Xuetao
    tcg_temp_free_i32(tmp_mask);
183 6e64da3c Guan Xuetao
}
184 6e64da3c Guan Xuetao
/* Set NZCV flags from the high 4 bits of var.  */
185 6e64da3c Guan Xuetao
#define gen_set_nzcv(var) gen_set_asr(var, ASR_NZCV)
186 6e64da3c Guan Xuetao
187 6e64da3c Guan Xuetao
static void gen_exception(int excp)
188 6e64da3c Guan Xuetao
{
189 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
190 6e64da3c Guan Xuetao
    tcg_gen_movi_i32(tmp, excp);
191 6e64da3c Guan Xuetao
    gen_helper_exception(tmp);
192 6e64da3c Guan Xuetao
    dead_tmp(tmp);
193 6e64da3c Guan Xuetao
}
194 6e64da3c Guan Xuetao
195 6e64da3c Guan Xuetao
/* FIXME: Most targets have native widening multiplication.
196 6e64da3c Guan Xuetao
   It would be good to use that instead of a full wide multiply.  */
197 6e64da3c Guan Xuetao
/* 32x32->64 multiply.  Marks inputs as dead.  */
198 6e64da3c Guan Xuetao
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
199 6e64da3c Guan Xuetao
{
200 6e64da3c Guan Xuetao
    TCGv_i64 tmp1 = tcg_temp_new_i64();
201 6e64da3c Guan Xuetao
    TCGv_i64 tmp2 = tcg_temp_new_i64();
202 6e64da3c Guan Xuetao
203 6e64da3c Guan Xuetao
    tcg_gen_extu_i32_i64(tmp1, a);
204 6e64da3c Guan Xuetao
    dead_tmp(a);
205 6e64da3c Guan Xuetao
    tcg_gen_extu_i32_i64(tmp2, b);
206 6e64da3c Guan Xuetao
    dead_tmp(b);
207 6e64da3c Guan Xuetao
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
208 6e64da3c Guan Xuetao
    tcg_temp_free_i64(tmp2);
209 6e64da3c Guan Xuetao
    return tmp1;
210 6e64da3c Guan Xuetao
}
211 6e64da3c Guan Xuetao
212 6e64da3c Guan Xuetao
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
213 6e64da3c Guan Xuetao
{
214 6e64da3c Guan Xuetao
    TCGv_i64 tmp1 = tcg_temp_new_i64();
215 6e64da3c Guan Xuetao
    TCGv_i64 tmp2 = tcg_temp_new_i64();
216 6e64da3c Guan Xuetao
217 6e64da3c Guan Xuetao
    tcg_gen_ext_i32_i64(tmp1, a);
218 6e64da3c Guan Xuetao
    dead_tmp(a);
219 6e64da3c Guan Xuetao
    tcg_gen_ext_i32_i64(tmp2, b);
220 6e64da3c Guan Xuetao
    dead_tmp(b);
221 6e64da3c Guan Xuetao
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
222 6e64da3c Guan Xuetao
    tcg_temp_free_i64(tmp2);
223 6e64da3c Guan Xuetao
    return tmp1;
224 6e64da3c Guan Xuetao
}
225 6e64da3c Guan Xuetao
226 6e64da3c Guan Xuetao
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
227 6e64da3c Guan Xuetao
228 6e64da3c Guan Xuetao
/* Set CF to the top bit of var.  */
229 6e64da3c Guan Xuetao
static void gen_set_CF_bit31(TCGv var)
230 6e64da3c Guan Xuetao
{
231 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
232 6e64da3c Guan Xuetao
    tcg_gen_shri_i32(tmp, var, 31);
233 6e64da3c Guan Xuetao
    gen_set_CF(tmp);
234 6e64da3c Guan Xuetao
    dead_tmp(tmp);
235 6e64da3c Guan Xuetao
}
236 6e64da3c Guan Xuetao
237 6e64da3c Guan Xuetao
/* Set N and Z flags from var.  */
238 6e64da3c Guan Xuetao
static inline void gen_logic_CC(TCGv var)
239 6e64da3c Guan Xuetao
{
240 6e64da3c Guan Xuetao
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
241 6e64da3c Guan Xuetao
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
242 6e64da3c Guan Xuetao
}
243 6e64da3c Guan Xuetao
244 6e64da3c Guan Xuetao
/* dest = T0 + T1 + CF. */
245 6e64da3c Guan Xuetao
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
246 6e64da3c Guan Xuetao
{
247 6e64da3c Guan Xuetao
    TCGv tmp;
248 6e64da3c Guan Xuetao
    tcg_gen_add_i32(dest, t0, t1);
249 6e64da3c Guan Xuetao
    tmp = load_cpu_field(CF);
250 6e64da3c Guan Xuetao
    tcg_gen_add_i32(dest, dest, tmp);
251 6e64da3c Guan Xuetao
    dead_tmp(tmp);
252 6e64da3c Guan Xuetao
}
253 6e64da3c Guan Xuetao
254 6e64da3c Guan Xuetao
/* dest = T0 - T1 + CF - 1.  */
255 6e64da3c Guan Xuetao
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
256 6e64da3c Guan Xuetao
{
257 6e64da3c Guan Xuetao
    TCGv tmp;
258 6e64da3c Guan Xuetao
    tcg_gen_sub_i32(dest, t0, t1);
259 6e64da3c Guan Xuetao
    tmp = load_cpu_field(CF);
260 6e64da3c Guan Xuetao
    tcg_gen_add_i32(dest, dest, tmp);
261 6e64da3c Guan Xuetao
    tcg_gen_subi_i32(dest, dest, 1);
262 6e64da3c Guan Xuetao
    dead_tmp(tmp);
263 6e64da3c Guan Xuetao
}
264 6e64da3c Guan Xuetao
265 6e64da3c Guan Xuetao
static void shifter_out_im(TCGv var, int shift)
266 6e64da3c Guan Xuetao
{
267 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
268 6e64da3c Guan Xuetao
    if (shift == 0) {
269 6e64da3c Guan Xuetao
        tcg_gen_andi_i32(tmp, var, 1);
270 6e64da3c Guan Xuetao
    } else {
271 6e64da3c Guan Xuetao
        tcg_gen_shri_i32(tmp, var, shift);
272 6e64da3c Guan Xuetao
        if (shift != 31) {
273 6e64da3c Guan Xuetao
            tcg_gen_andi_i32(tmp, tmp, 1);
274 6e64da3c Guan Xuetao
        }
275 6e64da3c Guan Xuetao
    }
276 6e64da3c Guan Xuetao
    gen_set_CF(tmp);
277 6e64da3c Guan Xuetao
    dead_tmp(tmp);
278 6e64da3c Guan Xuetao
}
279 6e64da3c Guan Xuetao
280 6e64da3c Guan Xuetao
/* Shift by immediate.  Includes special handling for shift == 0.  */
281 6e64da3c Guan Xuetao
static inline void gen_uc32_shift_im(TCGv var, int shiftop, int shift,
282 6e64da3c Guan Xuetao
        int flags)
283 6e64da3c Guan Xuetao
{
284 6e64da3c Guan Xuetao
    switch (shiftop) {
285 6e64da3c Guan Xuetao
    case 0: /* LSL */
286 6e64da3c Guan Xuetao
        if (shift != 0) {
287 6e64da3c Guan Xuetao
            if (flags) {
288 6e64da3c Guan Xuetao
                shifter_out_im(var, 32 - shift);
289 6e64da3c Guan Xuetao
            }
290 6e64da3c Guan Xuetao
            tcg_gen_shli_i32(var, var, shift);
291 6e64da3c Guan Xuetao
        }
292 6e64da3c Guan Xuetao
        break;
293 6e64da3c Guan Xuetao
    case 1: /* LSR */
294 6e64da3c Guan Xuetao
        if (shift == 0) {
295 6e64da3c Guan Xuetao
            if (flags) {
296 6e64da3c Guan Xuetao
                tcg_gen_shri_i32(var, var, 31);
297 6e64da3c Guan Xuetao
                gen_set_CF(var);
298 6e64da3c Guan Xuetao
            }
299 6e64da3c Guan Xuetao
            tcg_gen_movi_i32(var, 0);
300 6e64da3c Guan Xuetao
        } else {
301 6e64da3c Guan Xuetao
            if (flags) {
302 6e64da3c Guan Xuetao
                shifter_out_im(var, shift - 1);
303 6e64da3c Guan Xuetao
            }
304 6e64da3c Guan Xuetao
            tcg_gen_shri_i32(var, var, shift);
305 6e64da3c Guan Xuetao
        }
306 6e64da3c Guan Xuetao
        break;
307 6e64da3c Guan Xuetao
    case 2: /* ASR */
308 6e64da3c Guan Xuetao
        if (shift == 0) {
309 6e64da3c Guan Xuetao
            shift = 32;
310 6e64da3c Guan Xuetao
        }
311 6e64da3c Guan Xuetao
        if (flags) {
312 6e64da3c Guan Xuetao
            shifter_out_im(var, shift - 1);
313 6e64da3c Guan Xuetao
        }
314 6e64da3c Guan Xuetao
        if (shift == 32) {
315 6e64da3c Guan Xuetao
            shift = 31;
316 6e64da3c Guan Xuetao
        }
317 6e64da3c Guan Xuetao
        tcg_gen_sari_i32(var, var, shift);
318 6e64da3c Guan Xuetao
        break;
319 6e64da3c Guan Xuetao
    case 3: /* ROR/RRX */
320 6e64da3c Guan Xuetao
        if (shift != 0) {
321 6e64da3c Guan Xuetao
            if (flags) {
322 6e64da3c Guan Xuetao
                shifter_out_im(var, shift - 1);
323 6e64da3c Guan Xuetao
            }
324 6e64da3c Guan Xuetao
            tcg_gen_rotri_i32(var, var, shift); break;
325 6e64da3c Guan Xuetao
        } else {
326 6e64da3c Guan Xuetao
            TCGv tmp = load_cpu_field(CF);
327 6e64da3c Guan Xuetao
            if (flags) {
328 6e64da3c Guan Xuetao
                shifter_out_im(var, 0);
329 6e64da3c Guan Xuetao
            }
330 6e64da3c Guan Xuetao
            tcg_gen_shri_i32(var, var, 1);
331 6e64da3c Guan Xuetao
            tcg_gen_shli_i32(tmp, tmp, 31);
332 6e64da3c Guan Xuetao
            tcg_gen_or_i32(var, var, tmp);
333 6e64da3c Guan Xuetao
            dead_tmp(tmp);
334 6e64da3c Guan Xuetao
        }
335 6e64da3c Guan Xuetao
    }
336 6e64da3c Guan Xuetao
};
337 6e64da3c Guan Xuetao
338 6e64da3c Guan Xuetao
static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
339 6e64da3c Guan Xuetao
                                     TCGv shift, int flags)
340 6e64da3c Guan Xuetao
{
341 6e64da3c Guan Xuetao
    if (flags) {
342 6e64da3c Guan Xuetao
        switch (shiftop) {
343 6e64da3c Guan Xuetao
        case 0:
344 6e64da3c Guan Xuetao
            gen_helper_shl_cc(var, var, shift);
345 6e64da3c Guan Xuetao
            break;
346 6e64da3c Guan Xuetao
        case 1:
347 6e64da3c Guan Xuetao
            gen_helper_shr_cc(var, var, shift);
348 6e64da3c Guan Xuetao
            break;
349 6e64da3c Guan Xuetao
        case 2:
350 6e64da3c Guan Xuetao
            gen_helper_sar_cc(var, var, shift);
351 6e64da3c Guan Xuetao
            break;
352 6e64da3c Guan Xuetao
        case 3:
353 6e64da3c Guan Xuetao
            gen_helper_ror_cc(var, var, shift);
354 6e64da3c Guan Xuetao
            break;
355 6e64da3c Guan Xuetao
        }
356 6e64da3c Guan Xuetao
    } else {
357 6e64da3c Guan Xuetao
        switch (shiftop) {
358 6e64da3c Guan Xuetao
        case 0:
359 6e64da3c Guan Xuetao
            gen_helper_shl(var, var, shift);
360 6e64da3c Guan Xuetao
            break;
361 6e64da3c Guan Xuetao
        case 1:
362 6e64da3c Guan Xuetao
            gen_helper_shr(var, var, shift);
363 6e64da3c Guan Xuetao
            break;
364 6e64da3c Guan Xuetao
        case 2:
365 6e64da3c Guan Xuetao
            gen_helper_sar(var, var, shift);
366 6e64da3c Guan Xuetao
            break;
367 6e64da3c Guan Xuetao
        case 3:
368 6e64da3c Guan Xuetao
            tcg_gen_andi_i32(shift, shift, 0x1f);
369 6e64da3c Guan Xuetao
            tcg_gen_rotr_i32(var, var, shift);
370 6e64da3c Guan Xuetao
            break;
371 6e64da3c Guan Xuetao
        }
372 6e64da3c Guan Xuetao
    }
373 6e64da3c Guan Xuetao
    dead_tmp(shift);
374 6e64da3c Guan Xuetao
}
375 6e64da3c Guan Xuetao
376 6e64da3c Guan Xuetao
static void gen_test_cc(int cc, int label)
377 6e64da3c Guan Xuetao
{
378 6e64da3c Guan Xuetao
    TCGv tmp;
379 6e64da3c Guan Xuetao
    TCGv tmp2;
380 6e64da3c Guan Xuetao
    int inv;
381 6e64da3c Guan Xuetao
382 6e64da3c Guan Xuetao
    switch (cc) {
383 6e64da3c Guan Xuetao
    case 0: /* eq: Z */
384 6e64da3c Guan Xuetao
        tmp = load_cpu_field(ZF);
385 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
386 6e64da3c Guan Xuetao
        break;
387 6e64da3c Guan Xuetao
    case 1: /* ne: !Z */
388 6e64da3c Guan Xuetao
        tmp = load_cpu_field(ZF);
389 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
390 6e64da3c Guan Xuetao
        break;
391 6e64da3c Guan Xuetao
    case 2: /* cs: C */
392 6e64da3c Guan Xuetao
        tmp = load_cpu_field(CF);
393 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
394 6e64da3c Guan Xuetao
        break;
395 6e64da3c Guan Xuetao
    case 3: /* cc: !C */
396 6e64da3c Guan Xuetao
        tmp = load_cpu_field(CF);
397 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
398 6e64da3c Guan Xuetao
        break;
399 6e64da3c Guan Xuetao
    case 4: /* mi: N */
400 6e64da3c Guan Xuetao
        tmp = load_cpu_field(NF);
401 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
402 6e64da3c Guan Xuetao
        break;
403 6e64da3c Guan Xuetao
    case 5: /* pl: !N */
404 6e64da3c Guan Xuetao
        tmp = load_cpu_field(NF);
405 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
406 6e64da3c Guan Xuetao
        break;
407 6e64da3c Guan Xuetao
    case 6: /* vs: V */
408 6e64da3c Guan Xuetao
        tmp = load_cpu_field(VF);
409 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
410 6e64da3c Guan Xuetao
        break;
411 6e64da3c Guan Xuetao
    case 7: /* vc: !V */
412 6e64da3c Guan Xuetao
        tmp = load_cpu_field(VF);
413 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
414 6e64da3c Guan Xuetao
        break;
415 6e64da3c Guan Xuetao
    case 8: /* hi: C && !Z */
416 6e64da3c Guan Xuetao
        inv = gen_new_label();
417 6e64da3c Guan Xuetao
        tmp = load_cpu_field(CF);
418 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
419 6e64da3c Guan Xuetao
        dead_tmp(tmp);
420 6e64da3c Guan Xuetao
        tmp = load_cpu_field(ZF);
421 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
422 6e64da3c Guan Xuetao
        gen_set_label(inv);
423 6e64da3c Guan Xuetao
        break;
424 6e64da3c Guan Xuetao
    case 9: /* ls: !C || Z */
425 6e64da3c Guan Xuetao
        tmp = load_cpu_field(CF);
426 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
427 6e64da3c Guan Xuetao
        dead_tmp(tmp);
428 6e64da3c Guan Xuetao
        tmp = load_cpu_field(ZF);
429 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
430 6e64da3c Guan Xuetao
        break;
431 6e64da3c Guan Xuetao
    case 10: /* ge: N == V -> N ^ V == 0 */
432 6e64da3c Guan Xuetao
        tmp = load_cpu_field(VF);
433 6e64da3c Guan Xuetao
        tmp2 = load_cpu_field(NF);
434 6e64da3c Guan Xuetao
        tcg_gen_xor_i32(tmp, tmp, tmp2);
435 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
436 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
437 6e64da3c Guan Xuetao
        break;
438 6e64da3c Guan Xuetao
    case 11: /* lt: N != V -> N ^ V != 0 */
439 6e64da3c Guan Xuetao
        tmp = load_cpu_field(VF);
440 6e64da3c Guan Xuetao
        tmp2 = load_cpu_field(NF);
441 6e64da3c Guan Xuetao
        tcg_gen_xor_i32(tmp, tmp, tmp2);
442 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
443 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
444 6e64da3c Guan Xuetao
        break;
445 6e64da3c Guan Xuetao
    case 12: /* gt: !Z && N == V */
446 6e64da3c Guan Xuetao
        inv = gen_new_label();
447 6e64da3c Guan Xuetao
        tmp = load_cpu_field(ZF);
448 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
449 6e64da3c Guan Xuetao
        dead_tmp(tmp);
450 6e64da3c Guan Xuetao
        tmp = load_cpu_field(VF);
451 6e64da3c Guan Xuetao
        tmp2 = load_cpu_field(NF);
452 6e64da3c Guan Xuetao
        tcg_gen_xor_i32(tmp, tmp, tmp2);
453 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
454 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
455 6e64da3c Guan Xuetao
        gen_set_label(inv);
456 6e64da3c Guan Xuetao
        break;
457 6e64da3c Guan Xuetao
    case 13: /* le: Z || N != V */
458 6e64da3c Guan Xuetao
        tmp = load_cpu_field(ZF);
459 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
460 6e64da3c Guan Xuetao
        dead_tmp(tmp);
461 6e64da3c Guan Xuetao
        tmp = load_cpu_field(VF);
462 6e64da3c Guan Xuetao
        tmp2 = load_cpu_field(NF);
463 6e64da3c Guan Xuetao
        tcg_gen_xor_i32(tmp, tmp, tmp2);
464 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
465 6e64da3c Guan Xuetao
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
466 6e64da3c Guan Xuetao
        break;
467 6e64da3c Guan Xuetao
    default:
468 6e64da3c Guan Xuetao
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
469 6e64da3c Guan Xuetao
        abort();
470 6e64da3c Guan Xuetao
    }
471 6e64da3c Guan Xuetao
    dead_tmp(tmp);
472 6e64da3c Guan Xuetao
}
473 6e64da3c Guan Xuetao
474 6e64da3c Guan Xuetao
static const uint8_t table_logic_cc[16] = {
475 6e64da3c Guan Xuetao
    1, /* and */    1, /* xor */    0, /* sub */    0, /* rsb */
476 6e64da3c Guan Xuetao
    0, /* add */    0, /* adc */    0, /* sbc */    0, /* rsc */
477 6e64da3c Guan Xuetao
    1, /* andl */   1, /* xorl */   0, /* cmp */    0, /* cmn */
478 6e64da3c Guan Xuetao
    1, /* orr */    1, /* mov */    1, /* bic */    1, /* mvn */
479 6e64da3c Guan Xuetao
};
480 6e64da3c Guan Xuetao
481 6e64da3c Guan Xuetao
/* Set PC state from an immediate address.  */
482 6e64da3c Guan Xuetao
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
483 6e64da3c Guan Xuetao
{
484 6e64da3c Guan Xuetao
    s->is_jmp = DISAS_UPDATE;
485 6e64da3c Guan Xuetao
    tcg_gen_movi_i32(cpu_R[31], addr & ~3);
486 6e64da3c Guan Xuetao
}
487 6e64da3c Guan Xuetao
488 6e64da3c Guan Xuetao
/* Set PC state from var.  var is marked as dead.  */
489 6e64da3c Guan Xuetao
static inline void gen_bx(DisasContext *s, TCGv var)
490 6e64da3c Guan Xuetao
{
491 6e64da3c Guan Xuetao
    s->is_jmp = DISAS_UPDATE;
492 6e64da3c Guan Xuetao
    tcg_gen_andi_i32(cpu_R[31], var, ~3);
493 6e64da3c Guan Xuetao
    dead_tmp(var);
494 6e64da3c Guan Xuetao
}
495 6e64da3c Guan Xuetao
496 6e64da3c Guan Xuetao
static inline void store_reg_bx(DisasContext *s, int reg, TCGv var)
497 6e64da3c Guan Xuetao
{
498 6e64da3c Guan Xuetao
    store_reg(s, reg, var);
499 6e64da3c Guan Xuetao
}
500 6e64da3c Guan Xuetao
501 6e64da3c Guan Xuetao
static inline TCGv gen_ld8s(TCGv addr, int index)
502 6e64da3c Guan Xuetao
{
503 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
504 6e64da3c Guan Xuetao
    tcg_gen_qemu_ld8s(tmp, addr, index);
505 6e64da3c Guan Xuetao
    return tmp;
506 6e64da3c Guan Xuetao
}
507 6e64da3c Guan Xuetao
508 6e64da3c Guan Xuetao
static inline TCGv gen_ld8u(TCGv addr, int index)
509 6e64da3c Guan Xuetao
{
510 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
511 6e64da3c Guan Xuetao
    tcg_gen_qemu_ld8u(tmp, addr, index);
512 6e64da3c Guan Xuetao
    return tmp;
513 6e64da3c Guan Xuetao
}
514 6e64da3c Guan Xuetao
515 6e64da3c Guan Xuetao
static inline TCGv gen_ld16s(TCGv addr, int index)
516 6e64da3c Guan Xuetao
{
517 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
518 6e64da3c Guan Xuetao
    tcg_gen_qemu_ld16s(tmp, addr, index);
519 6e64da3c Guan Xuetao
    return tmp;
520 6e64da3c Guan Xuetao
}
521 6e64da3c Guan Xuetao
522 6e64da3c Guan Xuetao
static inline TCGv gen_ld16u(TCGv addr, int index)
523 6e64da3c Guan Xuetao
{
524 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
525 6e64da3c Guan Xuetao
    tcg_gen_qemu_ld16u(tmp, addr, index);
526 6e64da3c Guan Xuetao
    return tmp;
527 6e64da3c Guan Xuetao
}
528 6e64da3c Guan Xuetao
529 6e64da3c Guan Xuetao
static inline TCGv gen_ld32(TCGv addr, int index)
530 6e64da3c Guan Xuetao
{
531 6e64da3c Guan Xuetao
    TCGv tmp = new_tmp();
532 6e64da3c Guan Xuetao
    tcg_gen_qemu_ld32u(tmp, addr, index);
533 6e64da3c Guan Xuetao
    return tmp;
534 6e64da3c Guan Xuetao
}
535 6e64da3c Guan Xuetao
536 6e64da3c Guan Xuetao
static inline TCGv_i64 gen_ld64(TCGv addr, int index)
537 6e64da3c Guan Xuetao
{
538 6e64da3c Guan Xuetao
    TCGv_i64 tmp = tcg_temp_new_i64();
539 6e64da3c Guan Xuetao
    tcg_gen_qemu_ld64(tmp, addr, index);
540 6e64da3c Guan Xuetao
    return tmp;
541 6e64da3c Guan Xuetao
}
542 6e64da3c Guan Xuetao
543 6e64da3c Guan Xuetao
static inline void gen_st8(TCGv val, TCGv addr, int index)
544 6e64da3c Guan Xuetao
{
545 6e64da3c Guan Xuetao
    tcg_gen_qemu_st8(val, addr, index);
546 6e64da3c Guan Xuetao
    dead_tmp(val);
547 6e64da3c Guan Xuetao
}
548 6e64da3c Guan Xuetao
549 6e64da3c Guan Xuetao
static inline void gen_st16(TCGv val, TCGv addr, int index)
550 6e64da3c Guan Xuetao
{
551 6e64da3c Guan Xuetao
    tcg_gen_qemu_st16(val, addr, index);
552 6e64da3c Guan Xuetao
    dead_tmp(val);
553 6e64da3c Guan Xuetao
}
554 6e64da3c Guan Xuetao
555 6e64da3c Guan Xuetao
static inline void gen_st32(TCGv val, TCGv addr, int index)
556 6e64da3c Guan Xuetao
{
557 6e64da3c Guan Xuetao
    tcg_gen_qemu_st32(val, addr, index);
558 6e64da3c Guan Xuetao
    dead_tmp(val);
559 6e64da3c Guan Xuetao
}
560 6e64da3c Guan Xuetao
561 6e64da3c Guan Xuetao
static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
562 6e64da3c Guan Xuetao
{
563 6e64da3c Guan Xuetao
    tcg_gen_qemu_st64(val, addr, index);
564 6e64da3c Guan Xuetao
    tcg_temp_free_i64(val);
565 6e64da3c Guan Xuetao
}
566 6e64da3c Guan Xuetao
567 6e64da3c Guan Xuetao
static inline void gen_set_pc_im(uint32_t val)
568 6e64da3c Guan Xuetao
{
569 6e64da3c Guan Xuetao
    tcg_gen_movi_i32(cpu_R[31], val);
570 6e64da3c Guan Xuetao
}
571 6e64da3c Guan Xuetao
572 6e64da3c Guan Xuetao
/* Force a TB lookup after an instruction that changes the CPU state.  */
573 6e64da3c Guan Xuetao
static inline void gen_lookup_tb(DisasContext *s)
574 6e64da3c Guan Xuetao
{
575 6e64da3c Guan Xuetao
    tcg_gen_movi_i32(cpu_R[31], s->pc & ~1);
576 6e64da3c Guan Xuetao
    s->is_jmp = DISAS_UPDATE;
577 6e64da3c Guan Xuetao
}
578 6e64da3c Guan Xuetao
579 6e64da3c Guan Xuetao
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
580 6e64da3c Guan Xuetao
        TCGv var)
581 6e64da3c Guan Xuetao
{
582 6e64da3c Guan Xuetao
    int val;
583 6e64da3c Guan Xuetao
    TCGv offset;
584 6e64da3c Guan Xuetao
585 6e64da3c Guan Xuetao
    if (UCOP_SET(29)) {
586 6e64da3c Guan Xuetao
        /* immediate */
587 6e64da3c Guan Xuetao
        val = UCOP_IMM14;
588 6e64da3c Guan Xuetao
        if (!UCOP_SET_U) {
589 6e64da3c Guan Xuetao
            val = -val;
590 6e64da3c Guan Xuetao
        }
591 6e64da3c Guan Xuetao
        if (val != 0) {
592 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(var, var, val);
593 6e64da3c Guan Xuetao
        }
594 6e64da3c Guan Xuetao
    } else {
595 6e64da3c Guan Xuetao
        /* shift/register */
596 6e64da3c Guan Xuetao
        offset = load_reg(s, UCOP_REG_M);
597 6e64da3c Guan Xuetao
        gen_uc32_shift_im(offset, UCOP_SH_OP, UCOP_SH_IM, 0);
598 6e64da3c Guan Xuetao
        if (!UCOP_SET_U) {
599 6e64da3c Guan Xuetao
            tcg_gen_sub_i32(var, var, offset);
600 6e64da3c Guan Xuetao
        } else {
601 6e64da3c Guan Xuetao
            tcg_gen_add_i32(var, var, offset);
602 6e64da3c Guan Xuetao
        }
603 6e64da3c Guan Xuetao
        dead_tmp(offset);
604 6e64da3c Guan Xuetao
    }
605 6e64da3c Guan Xuetao
}
606 6e64da3c Guan Xuetao
607 6e64da3c Guan Xuetao
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
608 6e64da3c Guan Xuetao
        TCGv var)
609 6e64da3c Guan Xuetao
{
610 6e64da3c Guan Xuetao
    int val;
611 6e64da3c Guan Xuetao
    TCGv offset;
612 6e64da3c Guan Xuetao
613 6e64da3c Guan Xuetao
    if (UCOP_SET(26)) {
614 6e64da3c Guan Xuetao
        /* immediate */
615 6e64da3c Guan Xuetao
        val = (insn & 0x1f) | ((insn >> 4) & 0x3e0);
616 6e64da3c Guan Xuetao
        if (!UCOP_SET_U) {
617 6e64da3c Guan Xuetao
            val = -val;
618 6e64da3c Guan Xuetao
        }
619 6e64da3c Guan Xuetao
        if (val != 0) {
620 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(var, var, val);
621 6e64da3c Guan Xuetao
        }
622 6e64da3c Guan Xuetao
    } else {
623 6e64da3c Guan Xuetao
        /* register */
624 6e64da3c Guan Xuetao
        offset = load_reg(s, UCOP_REG_M);
625 6e64da3c Guan Xuetao
        if (!UCOP_SET_U) {
626 6e64da3c Guan Xuetao
            tcg_gen_sub_i32(var, var, offset);
627 6e64da3c Guan Xuetao
        } else {
628 6e64da3c Guan Xuetao
            tcg_gen_add_i32(var, var, offset);
629 6e64da3c Guan Xuetao
        }
630 6e64da3c Guan Xuetao
        dead_tmp(offset);
631 6e64da3c Guan Xuetao
    }
632 6e64da3c Guan Xuetao
}
633 6e64da3c Guan Xuetao
634 6e64da3c Guan Xuetao
static inline long ucf64_reg_offset(int reg)
635 6e64da3c Guan Xuetao
{
636 6e64da3c Guan Xuetao
    if (reg & 1) {
637 6e64da3c Guan Xuetao
        return offsetof(CPUState, ucf64.regs[reg >> 1])
638 6e64da3c Guan Xuetao
          + offsetof(CPU_DoubleU, l.upper);
639 6e64da3c Guan Xuetao
    } else {
640 6e64da3c Guan Xuetao
        return offsetof(CPUState, ucf64.regs[reg >> 1])
641 6e64da3c Guan Xuetao
          + offsetof(CPU_DoubleU, l.lower);
642 6e64da3c Guan Xuetao
    }
643 6e64da3c Guan Xuetao
}
644 6e64da3c Guan Xuetao
645 6e64da3c Guan Xuetao
#define ucf64_gen_ld32(reg)      load_cpu_offset(ucf64_reg_offset(reg))
646 6e64da3c Guan Xuetao
#define ucf64_gen_st32(var, reg) store_cpu_offset(var, ucf64_reg_offset(reg))
647 6e64da3c Guan Xuetao
648 6e64da3c Guan Xuetao
/* UniCore-F64 single load/store I_offset */
649 6e64da3c Guan Xuetao
static void do_ucf64_ldst_i(CPUState *env, DisasContext *s, uint32_t insn)
650 6e64da3c Guan Xuetao
{
651 6e64da3c Guan Xuetao
    int offset;
652 6e64da3c Guan Xuetao
    TCGv tmp;
653 6e64da3c Guan Xuetao
    TCGv addr;
654 6e64da3c Guan Xuetao
655 6e64da3c Guan Xuetao
    addr = load_reg(s, UCOP_REG_N);
656 6e64da3c Guan Xuetao
    if (!UCOP_SET_P && !UCOP_SET_W) {
657 6e64da3c Guan Xuetao
        ILLEGAL;
658 6e64da3c Guan Xuetao
    }
659 6e64da3c Guan Xuetao
660 6e64da3c Guan Xuetao
    if (UCOP_SET_P) {
661 6e64da3c Guan Xuetao
        offset = UCOP_IMM10 << 2;
662 6e64da3c Guan Xuetao
        if (!UCOP_SET_U) {
663 6e64da3c Guan Xuetao
            offset = -offset;
664 6e64da3c Guan Xuetao
        }
665 6e64da3c Guan Xuetao
        if (offset != 0) {
666 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, offset);
667 6e64da3c Guan Xuetao
        }
668 6e64da3c Guan Xuetao
    }
669 6e64da3c Guan Xuetao
670 6e64da3c Guan Xuetao
    if (UCOP_SET_L) { /* load */
671 6e64da3c Guan Xuetao
        tmp = gen_ld32(addr, IS_USER(s));
672 6e64da3c Guan Xuetao
        ucf64_gen_st32(tmp, UCOP_REG_D);
673 6e64da3c Guan Xuetao
    } else { /* store */
674 6e64da3c Guan Xuetao
        tmp = ucf64_gen_ld32(UCOP_REG_D);
675 6e64da3c Guan Xuetao
        gen_st32(tmp, addr, IS_USER(s));
676 6e64da3c Guan Xuetao
    }
677 6e64da3c Guan Xuetao
678 6e64da3c Guan Xuetao
    if (!UCOP_SET_P) {
679 6e64da3c Guan Xuetao
        offset = UCOP_IMM10 << 2;
680 6e64da3c Guan Xuetao
        if (!UCOP_SET_U) {
681 6e64da3c Guan Xuetao
            offset = -offset;
682 6e64da3c Guan Xuetao
        }
683 6e64da3c Guan Xuetao
        if (offset != 0) {
684 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, offset);
685 6e64da3c Guan Xuetao
        }
686 6e64da3c Guan Xuetao
    }
687 6e64da3c Guan Xuetao
    if (UCOP_SET_W) {
688 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, addr);
689 6e64da3c Guan Xuetao
    } else {
690 6e64da3c Guan Xuetao
        dead_tmp(addr);
691 6e64da3c Guan Xuetao
    }
692 6e64da3c Guan Xuetao
}
693 6e64da3c Guan Xuetao
694 6e64da3c Guan Xuetao
/* UniCore-F64 load/store multiple words */
695 6e64da3c Guan Xuetao
static void do_ucf64_ldst_m(CPUState *env, DisasContext *s, uint32_t insn)
696 6e64da3c Guan Xuetao
{
697 6e64da3c Guan Xuetao
    unsigned int i;
698 6e64da3c Guan Xuetao
    int j, n, freg;
699 6e64da3c Guan Xuetao
    TCGv tmp;
700 6e64da3c Guan Xuetao
    TCGv addr;
701 6e64da3c Guan Xuetao
702 6e64da3c Guan Xuetao
    if (UCOP_REG_D != 0) {
703 6e64da3c Guan Xuetao
        ILLEGAL;
704 6e64da3c Guan Xuetao
    }
705 6e64da3c Guan Xuetao
    if (UCOP_REG_N == 31) {
706 6e64da3c Guan Xuetao
        ILLEGAL;
707 6e64da3c Guan Xuetao
    }
708 6e64da3c Guan Xuetao
    if ((insn << 24) == 0) {
709 6e64da3c Guan Xuetao
        ILLEGAL;
710 6e64da3c Guan Xuetao
    }
711 6e64da3c Guan Xuetao
712 6e64da3c Guan Xuetao
    addr = load_reg(s, UCOP_REG_N);
713 6e64da3c Guan Xuetao
714 6e64da3c Guan Xuetao
    n = 0;
715 6e64da3c Guan Xuetao
    for (i = 0; i < 8; i++) {
716 6e64da3c Guan Xuetao
        if (UCOP_SET(i)) {
717 6e64da3c Guan Xuetao
            n++;
718 6e64da3c Guan Xuetao
        }
719 6e64da3c Guan Xuetao
    }
720 6e64da3c Guan Xuetao
721 6e64da3c Guan Xuetao
    if (UCOP_SET_U) {
722 6e64da3c Guan Xuetao
        if (UCOP_SET_P) { /* pre increment */
723 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, 4);
724 6e64da3c Guan Xuetao
        } /* unnecessary to do anything when post increment */
725 6e64da3c Guan Xuetao
    } else {
726 6e64da3c Guan Xuetao
        if (UCOP_SET_P) { /* pre decrement */
727 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, -(n * 4));
728 6e64da3c Guan Xuetao
        } else { /* post decrement */
729 6e64da3c Guan Xuetao
            if (n != 1) {
730 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
731 6e64da3c Guan Xuetao
            }
732 6e64da3c Guan Xuetao
        }
733 6e64da3c Guan Xuetao
    }
734 6e64da3c Guan Xuetao
735 6e64da3c Guan Xuetao
    freg = ((insn >> 8) & 3) << 3; /* freg should be 0, 8, 16, 24 */
736 6e64da3c Guan Xuetao
737 6e64da3c Guan Xuetao
    for (i = 0, j = 0; i < 8; i++, freg++) {
738 6e64da3c Guan Xuetao
        if (!UCOP_SET(i)) {
739 6e64da3c Guan Xuetao
            continue;
740 6e64da3c Guan Xuetao
        }
741 6e64da3c Guan Xuetao
742 6e64da3c Guan Xuetao
        if (UCOP_SET_L) { /* load */
743 6e64da3c Guan Xuetao
            tmp = gen_ld32(addr, IS_USER(s));
744 6e64da3c Guan Xuetao
            ucf64_gen_st32(tmp, freg);
745 6e64da3c Guan Xuetao
        } else { /* store */
746 6e64da3c Guan Xuetao
            tmp = ucf64_gen_ld32(freg);
747 6e64da3c Guan Xuetao
            gen_st32(tmp, addr, IS_USER(s));
748 6e64da3c Guan Xuetao
        }
749 6e64da3c Guan Xuetao
750 6e64da3c Guan Xuetao
        j++;
751 6e64da3c Guan Xuetao
        /* unnecessary to add after the last transfer */
752 6e64da3c Guan Xuetao
        if (j != n) {
753 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, 4);
754 6e64da3c Guan Xuetao
        }
755 6e64da3c Guan Xuetao
    }
756 6e64da3c Guan Xuetao
757 6e64da3c Guan Xuetao
    if (UCOP_SET_W) { /* write back */
758 6e64da3c Guan Xuetao
        if (UCOP_SET_U) {
759 6e64da3c Guan Xuetao
            if (!UCOP_SET_P) { /* post increment */
760 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, 4);
761 6e64da3c Guan Xuetao
            } /* unnecessary to do anything when pre increment */
762 6e64da3c Guan Xuetao
        } else {
763 6e64da3c Guan Xuetao
            if (UCOP_SET_P) {
764 6e64da3c Guan Xuetao
                /* pre decrement */
765 6e64da3c Guan Xuetao
                if (n != 1) {
766 6e64da3c Guan Xuetao
                    tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
767 6e64da3c Guan Xuetao
                }
768 6e64da3c Guan Xuetao
            } else {
769 6e64da3c Guan Xuetao
                /* post decrement */
770 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, -(n * 4));
771 6e64da3c Guan Xuetao
            }
772 6e64da3c Guan Xuetao
        }
773 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, addr);
774 6e64da3c Guan Xuetao
    } else {
775 6e64da3c Guan Xuetao
        dead_tmp(addr);
776 6e64da3c Guan Xuetao
    }
777 6e64da3c Guan Xuetao
}
778 6e64da3c Guan Xuetao
779 6e64da3c Guan Xuetao
/* UniCore-F64 mrc/mcr */
780 6e64da3c Guan Xuetao
static void do_ucf64_trans(CPUState *env, DisasContext *s, uint32_t insn)
781 6e64da3c Guan Xuetao
{
782 6e64da3c Guan Xuetao
    TCGv tmp;
783 6e64da3c Guan Xuetao
784 6e64da3c Guan Xuetao
    if ((insn & 0xfe0003ff) == 0xe2000000) {
785 6e64da3c Guan Xuetao
        /* control register */
786 6e64da3c Guan Xuetao
        if ((UCOP_REG_N != UC32_UCF64_FPSCR) || (UCOP_REG_D == 31)) {
787 6e64da3c Guan Xuetao
            ILLEGAL;
788 6e64da3c Guan Xuetao
        }
789 6e64da3c Guan Xuetao
        if (UCOP_SET(24)) {
790 6e64da3c Guan Xuetao
            /* CFF */
791 6e64da3c Guan Xuetao
            tmp = new_tmp();
792 6e64da3c Guan Xuetao
            gen_helper_ucf64_get_fpscr(tmp, cpu_env);
793 6e64da3c Guan Xuetao
            store_reg(s, UCOP_REG_D, tmp);
794 6e64da3c Guan Xuetao
        } else {
795 6e64da3c Guan Xuetao
            /* CTF */
796 6e64da3c Guan Xuetao
            tmp = load_reg(s, UCOP_REG_D);
797 6e64da3c Guan Xuetao
            gen_helper_ucf64_set_fpscr(cpu_env, tmp);
798 6e64da3c Guan Xuetao
            dead_tmp(tmp);
799 6e64da3c Guan Xuetao
            gen_lookup_tb(s);
800 6e64da3c Guan Xuetao
        }
801 6e64da3c Guan Xuetao
        return;
802 6e64da3c Guan Xuetao
    }
803 6e64da3c Guan Xuetao
    if ((insn & 0xfe0003ff) == 0xe0000000) {
804 6e64da3c Guan Xuetao
        /* general register */
805 6e64da3c Guan Xuetao
        if (UCOP_REG_D == 31) {
806 6e64da3c Guan Xuetao
            ILLEGAL;
807 6e64da3c Guan Xuetao
        }
808 6e64da3c Guan Xuetao
        if (UCOP_SET(24)) { /* MFF */
809 6e64da3c Guan Xuetao
            tmp = ucf64_gen_ld32(UCOP_REG_N);
810 6e64da3c Guan Xuetao
            store_reg(s, UCOP_REG_D, tmp);
811 6e64da3c Guan Xuetao
        } else { /* MTF */
812 6e64da3c Guan Xuetao
            tmp = load_reg(s, UCOP_REG_D);
813 6e64da3c Guan Xuetao
            ucf64_gen_st32(tmp, UCOP_REG_N);
814 6e64da3c Guan Xuetao
        }
815 6e64da3c Guan Xuetao
        return;
816 6e64da3c Guan Xuetao
    }
817 6e64da3c Guan Xuetao
    if ((insn & 0xfb000000) == 0xe9000000) {
818 6e64da3c Guan Xuetao
        /* MFFC */
819 6e64da3c Guan Xuetao
        if (UCOP_REG_D != 31) {
820 6e64da3c Guan Xuetao
            ILLEGAL;
821 6e64da3c Guan Xuetao
        }
822 6e64da3c Guan Xuetao
        if (UCOP_UCF64_COND & 0x8) {
823 6e64da3c Guan Xuetao
            ILLEGAL;
824 6e64da3c Guan Xuetao
        }
825 6e64da3c Guan Xuetao
826 6e64da3c Guan Xuetao
        tmp = new_tmp();
827 6e64da3c Guan Xuetao
        tcg_gen_movi_i32(tmp, UCOP_UCF64_COND);
828 6e64da3c Guan Xuetao
        if (UCOP_SET(26)) {
829 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
830 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
831 6e64da3c Guan Xuetao
            gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, tmp, cpu_env);
832 6e64da3c Guan Xuetao
        } else {
833 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
834 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
835 6e64da3c Guan Xuetao
            gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, tmp, cpu_env);
836 6e64da3c Guan Xuetao
        }
837 6e64da3c Guan Xuetao
        dead_tmp(tmp);
838 6e64da3c Guan Xuetao
        return;
839 6e64da3c Guan Xuetao
    }
840 6e64da3c Guan Xuetao
    ILLEGAL;
841 6e64da3c Guan Xuetao
}
842 6e64da3c Guan Xuetao
843 6e64da3c Guan Xuetao
/* UniCore-F64 convert instructions */
844 6e64da3c Guan Xuetao
static void do_ucf64_fcvt(CPUState *env, DisasContext *s, uint32_t insn)
845 6e64da3c Guan Xuetao
{
846 6e64da3c Guan Xuetao
    if (UCOP_UCF64_FMT == 3) {
847 6e64da3c Guan Xuetao
        ILLEGAL;
848 6e64da3c Guan Xuetao
    }
849 6e64da3c Guan Xuetao
    if (UCOP_REG_N != 0) {
850 6e64da3c Guan Xuetao
        ILLEGAL;
851 6e64da3c Guan Xuetao
    }
852 6e64da3c Guan Xuetao
    switch (UCOP_UCF64_FUNC) {
853 6e64da3c Guan Xuetao
    case 0: /* cvt.s */
854 6e64da3c Guan Xuetao
        switch (UCOP_UCF64_FMT) {
855 6e64da3c Guan Xuetao
        case 1 /* d */:
856 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
857 6e64da3c Guan Xuetao
            gen_helper_ucf64_df2sf(cpu_F0s, cpu_F0d, cpu_env);
858 6e64da3c Guan Xuetao
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
859 6e64da3c Guan Xuetao
            break;
860 6e64da3c Guan Xuetao
        case 2 /* w */:
861 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
862 6e64da3c Guan Xuetao
            gen_helper_ucf64_si2sf(cpu_F0s, cpu_F0s, cpu_env);
863 6e64da3c Guan Xuetao
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
864 6e64da3c Guan Xuetao
            break;
865 6e64da3c Guan Xuetao
        default /* s */:
866 6e64da3c Guan Xuetao
            ILLEGAL;
867 6e64da3c Guan Xuetao
            break;
868 6e64da3c Guan Xuetao
        }
869 6e64da3c Guan Xuetao
        break;
870 6e64da3c Guan Xuetao
    case 1: /* cvt.d */
871 6e64da3c Guan Xuetao
        switch (UCOP_UCF64_FMT) {
872 6e64da3c Guan Xuetao
        case 0 /* s */:
873 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
874 6e64da3c Guan Xuetao
            gen_helper_ucf64_sf2df(cpu_F0d, cpu_F0s, cpu_env);
875 6e64da3c Guan Xuetao
            tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
876 6e64da3c Guan Xuetao
            break;
877 6e64da3c Guan Xuetao
        case 2 /* w */:
878 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
879 6e64da3c Guan Xuetao
            gen_helper_ucf64_si2df(cpu_F0d, cpu_F0s, cpu_env);
880 6e64da3c Guan Xuetao
            tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
881 6e64da3c Guan Xuetao
            break;
882 6e64da3c Guan Xuetao
        default /* d */:
883 6e64da3c Guan Xuetao
            ILLEGAL;
884 6e64da3c Guan Xuetao
            break;
885 6e64da3c Guan Xuetao
        }
886 6e64da3c Guan Xuetao
        break;
887 6e64da3c Guan Xuetao
    case 4: /* cvt.w */
888 6e64da3c Guan Xuetao
        switch (UCOP_UCF64_FMT) {
889 6e64da3c Guan Xuetao
        case 0 /* s */:
890 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
891 6e64da3c Guan Xuetao
            gen_helper_ucf64_sf2si(cpu_F0s, cpu_F0s, cpu_env);
892 6e64da3c Guan Xuetao
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
893 6e64da3c Guan Xuetao
            break;
894 6e64da3c Guan Xuetao
        case 1 /* d */:
895 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
896 6e64da3c Guan Xuetao
            gen_helper_ucf64_df2si(cpu_F0s, cpu_F0d, cpu_env);
897 6e64da3c Guan Xuetao
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
898 6e64da3c Guan Xuetao
            break;
899 6e64da3c Guan Xuetao
    default /* w */:
900 6e64da3c Guan Xuetao
            ILLEGAL;
901 6e64da3c Guan Xuetao
            break;
902 6e64da3c Guan Xuetao
        }
903 6e64da3c Guan Xuetao
        break;
904 6e64da3c Guan Xuetao
    default:
905 6e64da3c Guan Xuetao
        ILLEGAL;
906 6e64da3c Guan Xuetao
    }
907 6e64da3c Guan Xuetao
}
908 6e64da3c Guan Xuetao
909 6e64da3c Guan Xuetao
/* UniCore-F64 compare instructions */
910 6e64da3c Guan Xuetao
static void do_ucf64_fcmp(CPUState *env, DisasContext *s, uint32_t insn)
911 6e64da3c Guan Xuetao
{
912 6e64da3c Guan Xuetao
    if (UCOP_SET(25)) {
913 6e64da3c Guan Xuetao
        ILLEGAL;
914 6e64da3c Guan Xuetao
    }
915 6e64da3c Guan Xuetao
    if (UCOP_REG_D != 0) {
916 6e64da3c Guan Xuetao
        ILLEGAL;
917 6e64da3c Guan Xuetao
    }
918 6e64da3c Guan Xuetao
919 6e64da3c Guan Xuetao
    ILLEGAL; /* TODO */
920 6e64da3c Guan Xuetao
    if (UCOP_SET(24)) {
921 6e64da3c Guan Xuetao
        tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
922 6e64da3c Guan Xuetao
        tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
923 6e64da3c Guan Xuetao
        /* gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, cpu_env); */
924 6e64da3c Guan Xuetao
    } else {
925 6e64da3c Guan Xuetao
        tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
926 6e64da3c Guan Xuetao
        tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
927 6e64da3c Guan Xuetao
        /* gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, cpu_env); */
928 6e64da3c Guan Xuetao
    }
929 6e64da3c Guan Xuetao
}
930 6e64da3c Guan Xuetao
931 6e64da3c Guan Xuetao
#define gen_helper_ucf64_movs(x, y)      do { } while (0)
932 6e64da3c Guan Xuetao
#define gen_helper_ucf64_movd(x, y)      do { } while (0)
933 6e64da3c Guan Xuetao
934 6e64da3c Guan Xuetao
#define UCF64_OP1(name)    do {                           \
935 6e64da3c Guan Xuetao
        if (UCOP_REG_N != 0) {                            \
936 6e64da3c Guan Xuetao
            ILLEGAL;                                      \
937 6e64da3c Guan Xuetao
        }                                                 \
938 6e64da3c Guan Xuetao
        switch (UCOP_UCF64_FMT) {                         \
939 6e64da3c Guan Xuetao
        case 0 /* s */:                                   \
940 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
941 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_M)); \
942 6e64da3c Guan Xuetao
            gen_helper_ucf64_##name##s(cpu_F0s, cpu_F0s); \
943 6e64da3c Guan Xuetao
            tcg_gen_st_i32(cpu_F0s, cpu_env,              \
944 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_D)); \
945 6e64da3c Guan Xuetao
            break;                                        \
946 6e64da3c Guan Xuetao
        case 1 /* d */:                                   \
947 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
948 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_M)); \
949 6e64da3c Guan Xuetao
            gen_helper_ucf64_##name##d(cpu_F0d, cpu_F0d); \
950 6e64da3c Guan Xuetao
            tcg_gen_st_i64(cpu_F0d, cpu_env,              \
951 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_D)); \
952 6e64da3c Guan Xuetao
            break;                                        \
953 6e64da3c Guan Xuetao
        case 2 /* w */:                                   \
954 6e64da3c Guan Xuetao
            ILLEGAL;                                      \
955 6e64da3c Guan Xuetao
            break;                                        \
956 6e64da3c Guan Xuetao
        }                                                 \
957 6e64da3c Guan Xuetao
    } while (0)
958 6e64da3c Guan Xuetao
959 6e64da3c Guan Xuetao
#define UCF64_OP2(name)    do {                           \
960 6e64da3c Guan Xuetao
        switch (UCOP_UCF64_FMT) {                         \
961 6e64da3c Guan Xuetao
        case 0 /* s */:                                   \
962 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
963 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_N)); \
964 6e64da3c Guan Xuetao
            tcg_gen_ld_i32(cpu_F1s, cpu_env,              \
965 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_M)); \
966 6e64da3c Guan Xuetao
            gen_helper_ucf64_##name##s(cpu_F0s,           \
967 6e64da3c Guan Xuetao
                           cpu_F0s, cpu_F1s, cpu_env);    \
968 6e64da3c Guan Xuetao
            tcg_gen_st_i32(cpu_F0s, cpu_env,              \
969 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_D)); \
970 6e64da3c Guan Xuetao
            break;                                        \
971 6e64da3c Guan Xuetao
        case 1 /* d */:                                   \
972 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
973 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_N)); \
974 6e64da3c Guan Xuetao
            tcg_gen_ld_i64(cpu_F1d, cpu_env,              \
975 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_M)); \
976 6e64da3c Guan Xuetao
            gen_helper_ucf64_##name##d(cpu_F0d,           \
977 6e64da3c Guan Xuetao
                           cpu_F0d, cpu_F1d, cpu_env);    \
978 6e64da3c Guan Xuetao
            tcg_gen_st_i64(cpu_F0d, cpu_env,              \
979 6e64da3c Guan Xuetao
                           ucf64_reg_offset(UCOP_REG_D)); \
980 6e64da3c Guan Xuetao
            break;                                        \
981 6e64da3c Guan Xuetao
        case 2 /* w */:                                   \
982 6e64da3c Guan Xuetao
            ILLEGAL;                                      \
983 6e64da3c Guan Xuetao
            break;                                        \
984 6e64da3c Guan Xuetao
        }                                                 \
985 6e64da3c Guan Xuetao
    } while (0)
986 6e64da3c Guan Xuetao
987 6e64da3c Guan Xuetao
/* UniCore-F64 data processing */
988 6e64da3c Guan Xuetao
static void do_ucf64_datap(CPUState *env, DisasContext *s, uint32_t insn)
989 6e64da3c Guan Xuetao
{
990 6e64da3c Guan Xuetao
    if (UCOP_UCF64_FMT == 3) {
991 6e64da3c Guan Xuetao
        ILLEGAL;
992 6e64da3c Guan Xuetao
    }
993 6e64da3c Guan Xuetao
    switch (UCOP_UCF64_FUNC) {
994 6e64da3c Guan Xuetao
    case 0: /* add */
995 6e64da3c Guan Xuetao
        UCF64_OP2(add);
996 6e64da3c Guan Xuetao
        break;
997 6e64da3c Guan Xuetao
    case 1: /* sub */
998 6e64da3c Guan Xuetao
        UCF64_OP2(sub);
999 6e64da3c Guan Xuetao
        break;
1000 6e64da3c Guan Xuetao
    case 2: /* mul */
1001 6e64da3c Guan Xuetao
        UCF64_OP2(mul);
1002 6e64da3c Guan Xuetao
        break;
1003 6e64da3c Guan Xuetao
    case 4: /* div */
1004 6e64da3c Guan Xuetao
        UCF64_OP2(div);
1005 6e64da3c Guan Xuetao
        break;
1006 6e64da3c Guan Xuetao
    case 5: /* abs */
1007 6e64da3c Guan Xuetao
        UCF64_OP1(abs);
1008 6e64da3c Guan Xuetao
        break;
1009 6e64da3c Guan Xuetao
    case 6: /* mov */
1010 6e64da3c Guan Xuetao
        UCF64_OP1(mov);
1011 6e64da3c Guan Xuetao
        break;
1012 6e64da3c Guan Xuetao
    case 7: /* neg */
1013 6e64da3c Guan Xuetao
        UCF64_OP1(neg);
1014 6e64da3c Guan Xuetao
        break;
1015 6e64da3c Guan Xuetao
    default:
1016 6e64da3c Guan Xuetao
        ILLEGAL;
1017 6e64da3c Guan Xuetao
    }
1018 6e64da3c Guan Xuetao
}
1019 6e64da3c Guan Xuetao
1020 6e64da3c Guan Xuetao
/* Disassemble an F64 instruction */
1021 6e64da3c Guan Xuetao
static void disas_ucf64_insn(CPUState *env, DisasContext *s, uint32_t insn)
1022 6e64da3c Guan Xuetao
{
1023 6e64da3c Guan Xuetao
    if (!UCOP_SET(29)) {
1024 6e64da3c Guan Xuetao
        if (UCOP_SET(26)) {
1025 6e64da3c Guan Xuetao
            do_ucf64_ldst_m(env, s, insn);
1026 6e64da3c Guan Xuetao
        } else {
1027 6e64da3c Guan Xuetao
            do_ucf64_ldst_i(env, s, insn);
1028 6e64da3c Guan Xuetao
        }
1029 6e64da3c Guan Xuetao
    } else {
1030 6e64da3c Guan Xuetao
        if (UCOP_SET(5)) {
1031 6e64da3c Guan Xuetao
            switch ((insn >> 26) & 0x3) {
1032 6e64da3c Guan Xuetao
            case 0:
1033 6e64da3c Guan Xuetao
                do_ucf64_datap(env, s, insn);
1034 6e64da3c Guan Xuetao
                break;
1035 6e64da3c Guan Xuetao
            case 1:
1036 6e64da3c Guan Xuetao
                ILLEGAL;
1037 6e64da3c Guan Xuetao
                break;
1038 6e64da3c Guan Xuetao
            case 2:
1039 6e64da3c Guan Xuetao
                do_ucf64_fcvt(env, s, insn);
1040 6e64da3c Guan Xuetao
                break;
1041 6e64da3c Guan Xuetao
            case 3:
1042 6e64da3c Guan Xuetao
                do_ucf64_fcmp(env, s, insn);
1043 6e64da3c Guan Xuetao
                break;
1044 6e64da3c Guan Xuetao
            }
1045 6e64da3c Guan Xuetao
        } else {
1046 6e64da3c Guan Xuetao
            do_ucf64_trans(env, s, insn);
1047 6e64da3c Guan Xuetao
        }
1048 6e64da3c Guan Xuetao
    }
1049 6e64da3c Guan Xuetao
}
1050 6e64da3c Guan Xuetao
1051 6e64da3c Guan Xuetao
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
1052 6e64da3c Guan Xuetao
{
1053 6e64da3c Guan Xuetao
    TranslationBlock *tb;
1054 6e64da3c Guan Xuetao
1055 6e64da3c Guan Xuetao
    tb = s->tb;
1056 6e64da3c Guan Xuetao
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1057 6e64da3c Guan Xuetao
        tcg_gen_goto_tb(n);
1058 6e64da3c Guan Xuetao
        gen_set_pc_im(dest);
1059 3feaca9e Stefan Weil
        tcg_gen_exit_tb((tcg_target_long)tb + n);
1060 6e64da3c Guan Xuetao
    } else {
1061 6e64da3c Guan Xuetao
        gen_set_pc_im(dest);
1062 6e64da3c Guan Xuetao
        tcg_gen_exit_tb(0);
1063 6e64da3c Guan Xuetao
    }
1064 6e64da3c Guan Xuetao
}
1065 6e64da3c Guan Xuetao
1066 6e64da3c Guan Xuetao
static inline void gen_jmp(DisasContext *s, uint32_t dest)
1067 6e64da3c Guan Xuetao
{
1068 6e64da3c Guan Xuetao
    if (unlikely(s->singlestep_enabled)) {
1069 6e64da3c Guan Xuetao
        /* An indirect jump so that we still trigger the debug exception.  */
1070 6e64da3c Guan Xuetao
        gen_bx_im(s, dest);
1071 6e64da3c Guan Xuetao
    } else {
1072 6e64da3c Guan Xuetao
        gen_goto_tb(s, 0, dest);
1073 6e64da3c Guan Xuetao
        s->is_jmp = DISAS_TB_JUMP;
1074 6e64da3c Guan Xuetao
    }
1075 6e64da3c Guan Xuetao
}
1076 6e64da3c Guan Xuetao
1077 6e64da3c Guan Xuetao
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
1078 6e64da3c Guan Xuetao
{
1079 6e64da3c Guan Xuetao
    if (x) {
1080 6e64da3c Guan Xuetao
        tcg_gen_sari_i32(t0, t0, 16);
1081 6e64da3c Guan Xuetao
    } else {
1082 6e64da3c Guan Xuetao
        gen_sxth(t0);
1083 6e64da3c Guan Xuetao
    }
1084 6e64da3c Guan Xuetao
    if (y) {
1085 6e64da3c Guan Xuetao
        tcg_gen_sari_i32(t1, t1, 16);
1086 6e64da3c Guan Xuetao
    } else {
1087 6e64da3c Guan Xuetao
        gen_sxth(t1);
1088 6e64da3c Guan Xuetao
    }
1089 6e64da3c Guan Xuetao
    tcg_gen_mul_i32(t0, t0, t1);
1090 6e64da3c Guan Xuetao
}
1091 6e64da3c Guan Xuetao
1092 6e64da3c Guan Xuetao
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
1093 6e64da3c Guan Xuetao
static int gen_set_psr(DisasContext *s, uint32_t mask, int bsr, TCGv t0)
1094 6e64da3c Guan Xuetao
{
1095 6e64da3c Guan Xuetao
    TCGv tmp;
1096 6e64da3c Guan Xuetao
    if (bsr) {
1097 6e64da3c Guan Xuetao
        /* ??? This is also undefined in system mode.  */
1098 6e64da3c Guan Xuetao
        if (IS_USER(s)) {
1099 6e64da3c Guan Xuetao
            return 1;
1100 6e64da3c Guan Xuetao
        }
1101 6e64da3c Guan Xuetao
1102 6e64da3c Guan Xuetao
        tmp = load_cpu_field(bsr);
1103 6e64da3c Guan Xuetao
        tcg_gen_andi_i32(tmp, tmp, ~mask);
1104 6e64da3c Guan Xuetao
        tcg_gen_andi_i32(t0, t0, mask);
1105 6e64da3c Guan Xuetao
        tcg_gen_or_i32(tmp, tmp, t0);
1106 6e64da3c Guan Xuetao
        store_cpu_field(tmp, bsr);
1107 6e64da3c Guan Xuetao
    } else {
1108 6e64da3c Guan Xuetao
        gen_set_asr(t0, mask);
1109 6e64da3c Guan Xuetao
    }
1110 6e64da3c Guan Xuetao
    dead_tmp(t0);
1111 6e64da3c Guan Xuetao
    gen_lookup_tb(s);
1112 6e64da3c Guan Xuetao
    return 0;
1113 6e64da3c Guan Xuetao
}
1114 6e64da3c Guan Xuetao
1115 6e64da3c Guan Xuetao
/* Generate an old-style exception return. Marks pc as dead. */
1116 6e64da3c Guan Xuetao
static void gen_exception_return(DisasContext *s, TCGv pc)
1117 6e64da3c Guan Xuetao
{
1118 6e64da3c Guan Xuetao
    TCGv tmp;
1119 6e64da3c Guan Xuetao
    store_reg(s, 31, pc);
1120 6e64da3c Guan Xuetao
    tmp = load_cpu_field(bsr);
1121 6e64da3c Guan Xuetao
    gen_set_asr(tmp, 0xffffffff);
1122 6e64da3c Guan Xuetao
    dead_tmp(tmp);
1123 6e64da3c Guan Xuetao
    s->is_jmp = DISAS_UPDATE;
1124 6e64da3c Guan Xuetao
}
1125 6e64da3c Guan Xuetao
1126 6e64da3c Guan Xuetao
static void disas_coproc_insn(CPUState *env, DisasContext *s, uint32_t insn)
1127 6e64da3c Guan Xuetao
{
1128 6e64da3c Guan Xuetao
    switch (UCOP_CPNUM) {
1129 6e64da3c Guan Xuetao
    case 2:
1130 6e64da3c Guan Xuetao
        disas_ucf64_insn(env, s, insn);
1131 6e64da3c Guan Xuetao
        break;
1132 6e64da3c Guan Xuetao
    default:
1133 6e64da3c Guan Xuetao
        /* Unknown coprocessor. */
1134 6e64da3c Guan Xuetao
        cpu_abort(env, "Unknown coprocessor!");
1135 6e64da3c Guan Xuetao
    }
1136 6e64da3c Guan Xuetao
}
1137 6e64da3c Guan Xuetao
1138 6e64da3c Guan Xuetao
1139 6e64da3c Guan Xuetao
/* Store a 64-bit value to a register pair.  Clobbers val.  */
1140 6e64da3c Guan Xuetao
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
1141 6e64da3c Guan Xuetao
{
1142 6e64da3c Guan Xuetao
    TCGv tmp;
1143 6e64da3c Guan Xuetao
    tmp = new_tmp();
1144 6e64da3c Guan Xuetao
    tcg_gen_trunc_i64_i32(tmp, val);
1145 6e64da3c Guan Xuetao
    store_reg(s, rlow, tmp);
1146 6e64da3c Guan Xuetao
    tmp = new_tmp();
1147 6e64da3c Guan Xuetao
    tcg_gen_shri_i64(val, val, 32);
1148 6e64da3c Guan Xuetao
    tcg_gen_trunc_i64_i32(tmp, val);
1149 6e64da3c Guan Xuetao
    store_reg(s, rhigh, tmp);
1150 6e64da3c Guan Xuetao
}
1151 6e64da3c Guan Xuetao
1152 6e64da3c Guan Xuetao
/* load and add a 64-bit value from a register pair.  */
1153 6e64da3c Guan Xuetao
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
1154 6e64da3c Guan Xuetao
{
1155 6e64da3c Guan Xuetao
    TCGv_i64 tmp;
1156 6e64da3c Guan Xuetao
    TCGv tmpl;
1157 6e64da3c Guan Xuetao
    TCGv tmph;
1158 6e64da3c Guan Xuetao
1159 6e64da3c Guan Xuetao
    /* Load 64-bit value rd:rn.  */
1160 6e64da3c Guan Xuetao
    tmpl = load_reg(s, rlow);
1161 6e64da3c Guan Xuetao
    tmph = load_reg(s, rhigh);
1162 6e64da3c Guan Xuetao
    tmp = tcg_temp_new_i64();
1163 6e64da3c Guan Xuetao
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
1164 6e64da3c Guan Xuetao
    dead_tmp(tmpl);
1165 6e64da3c Guan Xuetao
    dead_tmp(tmph);
1166 6e64da3c Guan Xuetao
    tcg_gen_add_i64(val, val, tmp);
1167 6e64da3c Guan Xuetao
    tcg_temp_free_i64(tmp);
1168 6e64da3c Guan Xuetao
}
1169 6e64da3c Guan Xuetao
1170 6e64da3c Guan Xuetao
/* data processing instructions */
1171 6e64da3c Guan Xuetao
static void do_datap(CPUState *env, DisasContext *s, uint32_t insn)
1172 6e64da3c Guan Xuetao
{
1173 6e64da3c Guan Xuetao
    TCGv tmp;
1174 6e64da3c Guan Xuetao
    TCGv tmp2;
1175 6e64da3c Guan Xuetao
    int logic_cc;
1176 6e64da3c Guan Xuetao
1177 6e64da3c Guan Xuetao
    if (UCOP_OPCODES == 0x0f || UCOP_OPCODES == 0x0d) {
1178 6e64da3c Guan Xuetao
        if (UCOP_SET(23)) { /* CMOV instructions */
1179 6e64da3c Guan Xuetao
            if ((UCOP_CMOV_COND == 0xe) || (UCOP_CMOV_COND == 0xf)) {
1180 6e64da3c Guan Xuetao
                ILLEGAL;
1181 6e64da3c Guan Xuetao
            }
1182 6e64da3c Guan Xuetao
            /* if not always execute, we generate a conditional jump to
1183 6e64da3c Guan Xuetao
               next instruction */
1184 6e64da3c Guan Xuetao
            s->condlabel = gen_new_label();
1185 6e64da3c Guan Xuetao
            gen_test_cc(UCOP_CMOV_COND ^ 1, s->condlabel);
1186 6e64da3c Guan Xuetao
            s->condjmp = 1;
1187 6e64da3c Guan Xuetao
        }
1188 6e64da3c Guan Xuetao
    }
1189 6e64da3c Guan Xuetao
1190 6e64da3c Guan Xuetao
    logic_cc = table_logic_cc[UCOP_OPCODES] & (UCOP_SET_S >> 24);
1191 6e64da3c Guan Xuetao
1192 6e64da3c Guan Xuetao
    if (UCOP_SET(29)) {
1193 6e64da3c Guan Xuetao
        unsigned int val;
1194 6e64da3c Guan Xuetao
        /* immediate operand */
1195 6e64da3c Guan Xuetao
        val = UCOP_IMM_9;
1196 6e64da3c Guan Xuetao
        if (UCOP_SH_IM) {
1197 6e64da3c Guan Xuetao
            val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
1198 6e64da3c Guan Xuetao
        }
1199 6e64da3c Guan Xuetao
        tmp2 = new_tmp();
1200 6e64da3c Guan Xuetao
        tcg_gen_movi_i32(tmp2, val);
1201 6e64da3c Guan Xuetao
        if (logic_cc && UCOP_SH_IM) {
1202 6e64da3c Guan Xuetao
            gen_set_CF_bit31(tmp2);
1203 6e64da3c Guan Xuetao
        }
1204 6e64da3c Guan Xuetao
   } else {
1205 6e64da3c Guan Xuetao
        /* register */
1206 6e64da3c Guan Xuetao
        tmp2 = load_reg(s, UCOP_REG_M);
1207 6e64da3c Guan Xuetao
        if (UCOP_SET(5)) {
1208 6e64da3c Guan Xuetao
            tmp = load_reg(s, UCOP_REG_S);
1209 6e64da3c Guan Xuetao
            gen_uc32_shift_reg(tmp2, UCOP_SH_OP, tmp, logic_cc);
1210 6e64da3c Guan Xuetao
        } else {
1211 6e64da3c Guan Xuetao
            gen_uc32_shift_im(tmp2, UCOP_SH_OP, UCOP_SH_IM, logic_cc);
1212 6e64da3c Guan Xuetao
        }
1213 6e64da3c Guan Xuetao
    }
1214 6e64da3c Guan Xuetao
1215 6e64da3c Guan Xuetao
    if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
1216 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_N);
1217 6e64da3c Guan Xuetao
    } else {
1218 6e64da3c Guan Xuetao
        TCGV_UNUSED(tmp);
1219 6e64da3c Guan Xuetao
    }
1220 6e64da3c Guan Xuetao
1221 6e64da3c Guan Xuetao
    switch (UCOP_OPCODES) {
1222 6e64da3c Guan Xuetao
    case 0x00:
1223 6e64da3c Guan Xuetao
        tcg_gen_and_i32(tmp, tmp, tmp2);
1224 6e64da3c Guan Xuetao
        if (logic_cc) {
1225 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1226 6e64da3c Guan Xuetao
        }
1227 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1228 6e64da3c Guan Xuetao
        break;
1229 6e64da3c Guan Xuetao
    case 0x01:
1230 6e64da3c Guan Xuetao
        tcg_gen_xor_i32(tmp, tmp, tmp2);
1231 6e64da3c Guan Xuetao
        if (logic_cc) {
1232 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1233 6e64da3c Guan Xuetao
        }
1234 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1235 6e64da3c Guan Xuetao
        break;
1236 6e64da3c Guan Xuetao
    case 0x02:
1237 6e64da3c Guan Xuetao
        if (UCOP_SET_S && UCOP_REG_D == 31) {
1238 6e64da3c Guan Xuetao
            /* SUBS r31, ... is used for exception return.  */
1239 6e64da3c Guan Xuetao
            if (IS_USER(s)) {
1240 6e64da3c Guan Xuetao
                ILLEGAL;
1241 6e64da3c Guan Xuetao
            }
1242 6e64da3c Guan Xuetao
            gen_helper_sub_cc(tmp, tmp, tmp2);
1243 6e64da3c Guan Xuetao
            gen_exception_return(s, tmp);
1244 6e64da3c Guan Xuetao
        } else {
1245 6e64da3c Guan Xuetao
            if (UCOP_SET_S) {
1246 6e64da3c Guan Xuetao
                gen_helper_sub_cc(tmp, tmp, tmp2);
1247 6e64da3c Guan Xuetao
            } else {
1248 6e64da3c Guan Xuetao
                tcg_gen_sub_i32(tmp, tmp, tmp2);
1249 6e64da3c Guan Xuetao
            }
1250 6e64da3c Guan Xuetao
            store_reg_bx(s, UCOP_REG_D, tmp);
1251 6e64da3c Guan Xuetao
        }
1252 6e64da3c Guan Xuetao
        break;
1253 6e64da3c Guan Xuetao
    case 0x03:
1254 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1255 6e64da3c Guan Xuetao
            gen_helper_sub_cc(tmp, tmp2, tmp);
1256 6e64da3c Guan Xuetao
        } else {
1257 6e64da3c Guan Xuetao
            tcg_gen_sub_i32(tmp, tmp2, tmp);
1258 6e64da3c Guan Xuetao
        }
1259 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1260 6e64da3c Guan Xuetao
        break;
1261 6e64da3c Guan Xuetao
    case 0x04:
1262 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1263 6e64da3c Guan Xuetao
            gen_helper_add_cc(tmp, tmp, tmp2);
1264 6e64da3c Guan Xuetao
        } else {
1265 6e64da3c Guan Xuetao
            tcg_gen_add_i32(tmp, tmp, tmp2);
1266 6e64da3c Guan Xuetao
        }
1267 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1268 6e64da3c Guan Xuetao
        break;
1269 6e64da3c Guan Xuetao
    case 0x05:
1270 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1271 6e64da3c Guan Xuetao
            gen_helper_adc_cc(tmp, tmp, tmp2);
1272 6e64da3c Guan Xuetao
        } else {
1273 6e64da3c Guan Xuetao
            gen_add_carry(tmp, tmp, tmp2);
1274 6e64da3c Guan Xuetao
        }
1275 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1276 6e64da3c Guan Xuetao
        break;
1277 6e64da3c Guan Xuetao
    case 0x06:
1278 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1279 6e64da3c Guan Xuetao
            gen_helper_sbc_cc(tmp, tmp, tmp2);
1280 6e64da3c Guan Xuetao
        } else {
1281 6e64da3c Guan Xuetao
            gen_sub_carry(tmp, tmp, tmp2);
1282 6e64da3c Guan Xuetao
        }
1283 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1284 6e64da3c Guan Xuetao
        break;
1285 6e64da3c Guan Xuetao
    case 0x07:
1286 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1287 6e64da3c Guan Xuetao
            gen_helper_sbc_cc(tmp, tmp2, tmp);
1288 6e64da3c Guan Xuetao
        } else {
1289 6e64da3c Guan Xuetao
            gen_sub_carry(tmp, tmp2, tmp);
1290 6e64da3c Guan Xuetao
        }
1291 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1292 6e64da3c Guan Xuetao
        break;
1293 6e64da3c Guan Xuetao
    case 0x08:
1294 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1295 6e64da3c Guan Xuetao
            tcg_gen_and_i32(tmp, tmp, tmp2);
1296 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1297 6e64da3c Guan Xuetao
        }
1298 6e64da3c Guan Xuetao
        dead_tmp(tmp);
1299 6e64da3c Guan Xuetao
        break;
1300 6e64da3c Guan Xuetao
    case 0x09:
1301 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1302 6e64da3c Guan Xuetao
            tcg_gen_xor_i32(tmp, tmp, tmp2);
1303 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1304 6e64da3c Guan Xuetao
        }
1305 6e64da3c Guan Xuetao
        dead_tmp(tmp);
1306 6e64da3c Guan Xuetao
        break;
1307 6e64da3c Guan Xuetao
    case 0x0a:
1308 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1309 6e64da3c Guan Xuetao
            gen_helper_sub_cc(tmp, tmp, tmp2);
1310 6e64da3c Guan Xuetao
        }
1311 6e64da3c Guan Xuetao
        dead_tmp(tmp);
1312 6e64da3c Guan Xuetao
        break;
1313 6e64da3c Guan Xuetao
    case 0x0b:
1314 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1315 6e64da3c Guan Xuetao
            gen_helper_add_cc(tmp, tmp, tmp2);
1316 6e64da3c Guan Xuetao
        }
1317 6e64da3c Guan Xuetao
        dead_tmp(tmp);
1318 6e64da3c Guan Xuetao
        break;
1319 6e64da3c Guan Xuetao
    case 0x0c:
1320 6e64da3c Guan Xuetao
        tcg_gen_or_i32(tmp, tmp, tmp2);
1321 6e64da3c Guan Xuetao
        if (logic_cc) {
1322 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1323 6e64da3c Guan Xuetao
        }
1324 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1325 6e64da3c Guan Xuetao
        break;
1326 6e64da3c Guan Xuetao
    case 0x0d:
1327 6e64da3c Guan Xuetao
        if (logic_cc && UCOP_REG_D == 31) {
1328 6e64da3c Guan Xuetao
            /* MOVS r31, ... is used for exception return.  */
1329 6e64da3c Guan Xuetao
            if (IS_USER(s)) {
1330 6e64da3c Guan Xuetao
                ILLEGAL;
1331 6e64da3c Guan Xuetao
            }
1332 6e64da3c Guan Xuetao
            gen_exception_return(s, tmp2);
1333 6e64da3c Guan Xuetao
        } else {
1334 6e64da3c Guan Xuetao
            if (logic_cc) {
1335 6e64da3c Guan Xuetao
                gen_logic_CC(tmp2);
1336 6e64da3c Guan Xuetao
            }
1337 6e64da3c Guan Xuetao
            store_reg_bx(s, UCOP_REG_D, tmp2);
1338 6e64da3c Guan Xuetao
        }
1339 6e64da3c Guan Xuetao
        break;
1340 6e64da3c Guan Xuetao
    case 0x0e:
1341 6e64da3c Guan Xuetao
        tcg_gen_andc_i32(tmp, tmp, tmp2);
1342 6e64da3c Guan Xuetao
        if (logic_cc) {
1343 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1344 6e64da3c Guan Xuetao
        }
1345 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp);
1346 6e64da3c Guan Xuetao
        break;
1347 6e64da3c Guan Xuetao
    default:
1348 6e64da3c Guan Xuetao
    case 0x0f:
1349 6e64da3c Guan Xuetao
        tcg_gen_not_i32(tmp2, tmp2);
1350 6e64da3c Guan Xuetao
        if (logic_cc) {
1351 6e64da3c Guan Xuetao
            gen_logic_CC(tmp2);
1352 6e64da3c Guan Xuetao
        }
1353 6e64da3c Guan Xuetao
        store_reg_bx(s, UCOP_REG_D, tmp2);
1354 6e64da3c Guan Xuetao
        break;
1355 6e64da3c Guan Xuetao
    }
1356 6e64da3c Guan Xuetao
    if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
1357 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
1358 6e64da3c Guan Xuetao
    }
1359 6e64da3c Guan Xuetao
}
1360 6e64da3c Guan Xuetao
1361 6e64da3c Guan Xuetao
/* multiply */
1362 6e64da3c Guan Xuetao
static void do_mult(CPUState *env, DisasContext *s, uint32_t insn)
1363 6e64da3c Guan Xuetao
{
1364 6e64da3c Guan Xuetao
    TCGv tmp;
1365 6e64da3c Guan Xuetao
    TCGv tmp2;
1366 6e64da3c Guan Xuetao
    TCGv_i64 tmp64;
1367 6e64da3c Guan Xuetao
1368 6e64da3c Guan Xuetao
    if (UCOP_SET(27)) {
1369 6e64da3c Guan Xuetao
        /* 64 bit mul */
1370 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_M);
1371 6e64da3c Guan Xuetao
        tmp2 = load_reg(s, UCOP_REG_N);
1372 6e64da3c Guan Xuetao
        if (UCOP_SET(26)) {
1373 6e64da3c Guan Xuetao
            tmp64 = gen_muls_i64_i32(tmp, tmp2);
1374 6e64da3c Guan Xuetao
        } else {
1375 6e64da3c Guan Xuetao
            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
1376 6e64da3c Guan Xuetao
        }
1377 6e64da3c Guan Xuetao
        if (UCOP_SET(25)) { /* mult accumulate */
1378 6e64da3c Guan Xuetao
            gen_addq(s, tmp64, UCOP_REG_LO, UCOP_REG_HI);
1379 6e64da3c Guan Xuetao
        }
1380 6e64da3c Guan Xuetao
        gen_storeq_reg(s, UCOP_REG_LO, UCOP_REG_HI, tmp64);
1381 6e64da3c Guan Xuetao
        tcg_temp_free_i64(tmp64);
1382 6e64da3c Guan Xuetao
    } else {
1383 6e64da3c Guan Xuetao
        /* 32 bit mul */
1384 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_M);
1385 6e64da3c Guan Xuetao
        tmp2 = load_reg(s, UCOP_REG_N);
1386 6e64da3c Guan Xuetao
        tcg_gen_mul_i32(tmp, tmp, tmp2);
1387 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
1388 6e64da3c Guan Xuetao
        if (UCOP_SET(25)) {
1389 6e64da3c Guan Xuetao
            /* Add */
1390 6e64da3c Guan Xuetao
            tmp2 = load_reg(s, UCOP_REG_S);
1391 6e64da3c Guan Xuetao
            tcg_gen_add_i32(tmp, tmp, tmp2);
1392 6e64da3c Guan Xuetao
            dead_tmp(tmp2);
1393 6e64da3c Guan Xuetao
        }
1394 6e64da3c Guan Xuetao
        if (UCOP_SET_S) {
1395 6e64da3c Guan Xuetao
            gen_logic_CC(tmp);
1396 6e64da3c Guan Xuetao
        }
1397 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_D, tmp);
1398 6e64da3c Guan Xuetao
    }
1399 6e64da3c Guan Xuetao
}
1400 6e64da3c Guan Xuetao
1401 6e64da3c Guan Xuetao
/* miscellaneous instructions */
1402 6e64da3c Guan Xuetao
static void do_misc(CPUState *env, DisasContext *s, uint32_t insn)
1403 6e64da3c Guan Xuetao
{
1404 6e64da3c Guan Xuetao
    unsigned int val;
1405 6e64da3c Guan Xuetao
    TCGv tmp;
1406 6e64da3c Guan Xuetao
1407 6e64da3c Guan Xuetao
    if ((insn & 0xffffffe0) == 0x10ffc120) {
1408 6e64da3c Guan Xuetao
        /* Trivial implementation equivalent to bx.  */
1409 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_M);
1410 6e64da3c Guan Xuetao
        gen_bx(s, tmp);
1411 6e64da3c Guan Xuetao
        return;
1412 6e64da3c Guan Xuetao
    }
1413 6e64da3c Guan Xuetao
1414 6e64da3c Guan Xuetao
    if ((insn & 0xfbffc000) == 0x30ffc000) {
1415 6e64da3c Guan Xuetao
        /* PSR = immediate */
1416 6e64da3c Guan Xuetao
        val = UCOP_IMM_9;
1417 6e64da3c Guan Xuetao
        if (UCOP_SH_IM) {
1418 6e64da3c Guan Xuetao
            val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
1419 6e64da3c Guan Xuetao
        }
1420 6e64da3c Guan Xuetao
        tmp = new_tmp();
1421 6e64da3c Guan Xuetao
        tcg_gen_movi_i32(tmp, val);
1422 6e64da3c Guan Xuetao
        if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
1423 6e64da3c Guan Xuetao
            ILLEGAL;
1424 6e64da3c Guan Xuetao
        }
1425 6e64da3c Guan Xuetao
        return;
1426 6e64da3c Guan Xuetao
    }
1427 6e64da3c Guan Xuetao
1428 6e64da3c Guan Xuetao
    if ((insn & 0xfbffffe0) == 0x12ffc020) {
1429 6e64da3c Guan Xuetao
        /* PSR.flag = reg */
1430 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_M);
1431 6e64da3c Guan Xuetao
        if (gen_set_psr(s, ASR_NZCV, UCOP_SET_B, tmp)) {
1432 6e64da3c Guan Xuetao
            ILLEGAL;
1433 6e64da3c Guan Xuetao
        }
1434 6e64da3c Guan Xuetao
        return;
1435 6e64da3c Guan Xuetao
    }
1436 6e64da3c Guan Xuetao
1437 6e64da3c Guan Xuetao
    if ((insn & 0xfbffffe0) == 0x10ffc020) {
1438 6e64da3c Guan Xuetao
        /* PSR = reg */
1439 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_M);
1440 6e64da3c Guan Xuetao
        if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
1441 6e64da3c Guan Xuetao
            ILLEGAL;
1442 6e64da3c Guan Xuetao
        }
1443 6e64da3c Guan Xuetao
        return;
1444 6e64da3c Guan Xuetao
    }
1445 6e64da3c Guan Xuetao
1446 6e64da3c Guan Xuetao
    if ((insn & 0xfbf83fff) == 0x10f80000) {
1447 6e64da3c Guan Xuetao
        /* reg = PSR */
1448 6e64da3c Guan Xuetao
        if (UCOP_SET_B) {
1449 6e64da3c Guan Xuetao
            if (IS_USER(s)) {
1450 6e64da3c Guan Xuetao
                ILLEGAL;
1451 6e64da3c Guan Xuetao
            }
1452 6e64da3c Guan Xuetao
            tmp = load_cpu_field(bsr);
1453 6e64da3c Guan Xuetao
        } else {
1454 6e64da3c Guan Xuetao
            tmp = new_tmp();
1455 6e64da3c Guan Xuetao
            gen_helper_asr_read(tmp);
1456 6e64da3c Guan Xuetao
        }
1457 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_D, tmp);
1458 6e64da3c Guan Xuetao
        return;
1459 6e64da3c Guan Xuetao
    }
1460 6e64da3c Guan Xuetao
1461 6e64da3c Guan Xuetao
    if ((insn & 0xfbf83fe0) == 0x12f80120) {
1462 6e64da3c Guan Xuetao
        /* clz */
1463 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_M);
1464 6e64da3c Guan Xuetao
        if (UCOP_SET(26)) {
1465 6e64da3c Guan Xuetao
            gen_helper_clo(tmp, tmp);
1466 6e64da3c Guan Xuetao
        } else {
1467 6e64da3c Guan Xuetao
            gen_helper_clz(tmp, tmp);
1468 6e64da3c Guan Xuetao
        }
1469 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_D, tmp);
1470 6e64da3c Guan Xuetao
        return;
1471 6e64da3c Guan Xuetao
    }
1472 6e64da3c Guan Xuetao
1473 6e64da3c Guan Xuetao
    /* otherwise */
1474 6e64da3c Guan Xuetao
    ILLEGAL;
1475 6e64da3c Guan Xuetao
}
1476 6e64da3c Guan Xuetao
1477 6e64da3c Guan Xuetao
/* load/store I_offset and R_offset */
1478 6e64da3c Guan Xuetao
static void do_ldst_ir(CPUState *env, DisasContext *s, uint32_t insn)
1479 6e64da3c Guan Xuetao
{
1480 6e64da3c Guan Xuetao
    unsigned int i;
1481 6e64da3c Guan Xuetao
    TCGv tmp;
1482 6e64da3c Guan Xuetao
    TCGv tmp2;
1483 6e64da3c Guan Xuetao
1484 6e64da3c Guan Xuetao
    tmp2 = load_reg(s, UCOP_REG_N);
1485 6e64da3c Guan Xuetao
    i = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
1486 6e64da3c Guan Xuetao
1487 6e64da3c Guan Xuetao
    /* immediate */
1488 6e64da3c Guan Xuetao
    if (UCOP_SET_P) {
1489 6e64da3c Guan Xuetao
        gen_add_data_offset(s, insn, tmp2);
1490 6e64da3c Guan Xuetao
    }
1491 6e64da3c Guan Xuetao
1492 6e64da3c Guan Xuetao
    if (UCOP_SET_L) {
1493 6e64da3c Guan Xuetao
        /* load */
1494 6e64da3c Guan Xuetao
        if (UCOP_SET_B) {
1495 6e64da3c Guan Xuetao
            tmp = gen_ld8u(tmp2, i);
1496 6e64da3c Guan Xuetao
        } else {
1497 6e64da3c Guan Xuetao
            tmp = gen_ld32(tmp2, i);
1498 6e64da3c Guan Xuetao
        }
1499 6e64da3c Guan Xuetao
    } else {
1500 6e64da3c Guan Xuetao
        /* store */
1501 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_D);
1502 6e64da3c Guan Xuetao
        if (UCOP_SET_B) {
1503 6e64da3c Guan Xuetao
            gen_st8(tmp, tmp2, i);
1504 6e64da3c Guan Xuetao
        } else {
1505 6e64da3c Guan Xuetao
            gen_st32(tmp, tmp2, i);
1506 6e64da3c Guan Xuetao
        }
1507 6e64da3c Guan Xuetao
    }
1508 6e64da3c Guan Xuetao
    if (!UCOP_SET_P) {
1509 6e64da3c Guan Xuetao
        gen_add_data_offset(s, insn, tmp2);
1510 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, tmp2);
1511 6e64da3c Guan Xuetao
    } else if (UCOP_SET_W) {
1512 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, tmp2);
1513 6e64da3c Guan Xuetao
    } else {
1514 6e64da3c Guan Xuetao
        dead_tmp(tmp2);
1515 6e64da3c Guan Xuetao
    }
1516 6e64da3c Guan Xuetao
    if (UCOP_SET_L) {
1517 6e64da3c Guan Xuetao
        /* Complete the load.  */
1518 6e64da3c Guan Xuetao
        if (UCOP_REG_D == 31) {
1519 6e64da3c Guan Xuetao
            gen_bx(s, tmp);
1520 6e64da3c Guan Xuetao
        } else {
1521 6e64da3c Guan Xuetao
            store_reg(s, UCOP_REG_D, tmp);
1522 6e64da3c Guan Xuetao
        }
1523 6e64da3c Guan Xuetao
    }
1524 6e64da3c Guan Xuetao
}
1525 6e64da3c Guan Xuetao
1526 6e64da3c Guan Xuetao
/* SWP instruction */
1527 6e64da3c Guan Xuetao
static void do_swap(CPUState *env, DisasContext *s, uint32_t insn)
1528 6e64da3c Guan Xuetao
{
1529 6e64da3c Guan Xuetao
    TCGv addr;
1530 6e64da3c Guan Xuetao
    TCGv tmp;
1531 6e64da3c Guan Xuetao
    TCGv tmp2;
1532 6e64da3c Guan Xuetao
1533 6e64da3c Guan Xuetao
    if ((insn & 0xff003fe0) != 0x40000120) {
1534 6e64da3c Guan Xuetao
        ILLEGAL;
1535 6e64da3c Guan Xuetao
    }
1536 6e64da3c Guan Xuetao
1537 6e64da3c Guan Xuetao
    /* ??? This is not really atomic.  However we know
1538 6e64da3c Guan Xuetao
       we never have multiple CPUs running in parallel,
1539 6e64da3c Guan Xuetao
       so it is good enough.  */
1540 6e64da3c Guan Xuetao
    addr = load_reg(s, UCOP_REG_N);
1541 6e64da3c Guan Xuetao
    tmp = load_reg(s, UCOP_REG_M);
1542 6e64da3c Guan Xuetao
    if (UCOP_SET_B) {
1543 6e64da3c Guan Xuetao
        tmp2 = gen_ld8u(addr, IS_USER(s));
1544 6e64da3c Guan Xuetao
        gen_st8(tmp, addr, IS_USER(s));
1545 6e64da3c Guan Xuetao
    } else {
1546 6e64da3c Guan Xuetao
        tmp2 = gen_ld32(addr, IS_USER(s));
1547 6e64da3c Guan Xuetao
        gen_st32(tmp, addr, IS_USER(s));
1548 6e64da3c Guan Xuetao
    }
1549 6e64da3c Guan Xuetao
    dead_tmp(addr);
1550 6e64da3c Guan Xuetao
    store_reg(s, UCOP_REG_D, tmp2);
1551 6e64da3c Guan Xuetao
}
1552 6e64da3c Guan Xuetao
1553 6e64da3c Guan Xuetao
/* load/store hw/sb */
1554 6e64da3c Guan Xuetao
static void do_ldst_hwsb(CPUState *env, DisasContext *s, uint32_t insn)
1555 6e64da3c Guan Xuetao
{
1556 6e64da3c Guan Xuetao
    TCGv addr;
1557 6e64da3c Guan Xuetao
    TCGv tmp;
1558 6e64da3c Guan Xuetao
1559 6e64da3c Guan Xuetao
    if (UCOP_SH_OP == 0) {
1560 6e64da3c Guan Xuetao
        do_swap(env, s, insn);
1561 6e64da3c Guan Xuetao
        return;
1562 6e64da3c Guan Xuetao
    }
1563 6e64da3c Guan Xuetao
1564 6e64da3c Guan Xuetao
    addr = load_reg(s, UCOP_REG_N);
1565 6e64da3c Guan Xuetao
    if (UCOP_SET_P) {
1566 6e64da3c Guan Xuetao
        gen_add_datah_offset(s, insn, addr);
1567 6e64da3c Guan Xuetao
    }
1568 6e64da3c Guan Xuetao
1569 6e64da3c Guan Xuetao
    if (UCOP_SET_L) { /* load */
1570 6e64da3c Guan Xuetao
        switch (UCOP_SH_OP) {
1571 6e64da3c Guan Xuetao
        case 1:
1572 6e64da3c Guan Xuetao
            tmp = gen_ld16u(addr, IS_USER(s));
1573 6e64da3c Guan Xuetao
            break;
1574 6e64da3c Guan Xuetao
        case 2:
1575 6e64da3c Guan Xuetao
            tmp = gen_ld8s(addr, IS_USER(s));
1576 6e64da3c Guan Xuetao
            break;
1577 6e64da3c Guan Xuetao
        default: /* see do_swap */
1578 6e64da3c Guan Xuetao
        case 3:
1579 6e64da3c Guan Xuetao
            tmp = gen_ld16s(addr, IS_USER(s));
1580 6e64da3c Guan Xuetao
            break;
1581 6e64da3c Guan Xuetao
        }
1582 6e64da3c Guan Xuetao
    } else { /* store */
1583 6e64da3c Guan Xuetao
        if (UCOP_SH_OP != 1) {
1584 6e64da3c Guan Xuetao
            ILLEGAL;
1585 6e64da3c Guan Xuetao
        }
1586 6e64da3c Guan Xuetao
        tmp = load_reg(s, UCOP_REG_D);
1587 6e64da3c Guan Xuetao
        gen_st16(tmp, addr, IS_USER(s));
1588 6e64da3c Guan Xuetao
    }
1589 6e64da3c Guan Xuetao
    /* Perform base writeback before the loaded value to
1590 6e64da3c Guan Xuetao
       ensure correct behavior with overlapping index registers. */
1591 6e64da3c Guan Xuetao
    if (!UCOP_SET_P) {
1592 6e64da3c Guan Xuetao
        gen_add_datah_offset(s, insn, addr);
1593 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, addr);
1594 6e64da3c Guan Xuetao
    } else if (UCOP_SET_W) {
1595 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, addr);
1596 6e64da3c Guan Xuetao
    } else {
1597 6e64da3c Guan Xuetao
        dead_tmp(addr);
1598 6e64da3c Guan Xuetao
    }
1599 6e64da3c Guan Xuetao
    if (UCOP_SET_L) {
1600 6e64da3c Guan Xuetao
        /* Complete the load.  */
1601 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_D, tmp);
1602 6e64da3c Guan Xuetao
    }
1603 6e64da3c Guan Xuetao
}
1604 6e64da3c Guan Xuetao
1605 6e64da3c Guan Xuetao
/* load/store multiple words */
1606 6e64da3c Guan Xuetao
static void do_ldst_m(CPUState *env, DisasContext *s, uint32_t insn)
1607 6e64da3c Guan Xuetao
{
1608 6e64da3c Guan Xuetao
    unsigned int val, i;
1609 6e64da3c Guan Xuetao
    int j, n, reg, user, loaded_base;
1610 6e64da3c Guan Xuetao
    TCGv tmp;
1611 6e64da3c Guan Xuetao
    TCGv tmp2;
1612 6e64da3c Guan Xuetao
    TCGv addr;
1613 6e64da3c Guan Xuetao
    TCGv loaded_var;
1614 6e64da3c Guan Xuetao
1615 6e64da3c Guan Xuetao
    if (UCOP_SET(7)) {
1616 6e64da3c Guan Xuetao
        ILLEGAL;
1617 6e64da3c Guan Xuetao
    }
1618 6e64da3c Guan Xuetao
    /* XXX: store correct base if write back */
1619 6e64da3c Guan Xuetao
    user = 0;
1620 6e64da3c Guan Xuetao
    if (UCOP_SET_B) { /* S bit in instruction table */
1621 6e64da3c Guan Xuetao
        if (IS_USER(s)) {
1622 6e64da3c Guan Xuetao
            ILLEGAL; /* only usable in supervisor mode */
1623 6e64da3c Guan Xuetao
        }
1624 6e64da3c Guan Xuetao
        if (UCOP_SET(18) == 0) { /* pc reg */
1625 6e64da3c Guan Xuetao
            user = 1;
1626 6e64da3c Guan Xuetao
        }
1627 6e64da3c Guan Xuetao
    }
1628 6e64da3c Guan Xuetao
1629 6e64da3c Guan Xuetao
    addr = load_reg(s, UCOP_REG_N);
1630 6e64da3c Guan Xuetao
1631 6e64da3c Guan Xuetao
    /* compute total size */
1632 6e64da3c Guan Xuetao
    loaded_base = 0;
1633 6e64da3c Guan Xuetao
    TCGV_UNUSED(loaded_var);
1634 6e64da3c Guan Xuetao
    n = 0;
1635 6e64da3c Guan Xuetao
    for (i = 0; i < 6; i++) {
1636 6e64da3c Guan Xuetao
        if (UCOP_SET(i)) {
1637 6e64da3c Guan Xuetao
            n++;
1638 6e64da3c Guan Xuetao
        }
1639 6e64da3c Guan Xuetao
    }
1640 6e64da3c Guan Xuetao
    for (i = 9; i < 19; i++) {
1641 6e64da3c Guan Xuetao
        if (UCOP_SET(i)) {
1642 6e64da3c Guan Xuetao
            n++;
1643 6e64da3c Guan Xuetao
        }
1644 6e64da3c Guan Xuetao
    }
1645 6e64da3c Guan Xuetao
    /* XXX: test invalid n == 0 case ? */
1646 6e64da3c Guan Xuetao
    if (UCOP_SET_U) {
1647 6e64da3c Guan Xuetao
        if (UCOP_SET_P) {
1648 6e64da3c Guan Xuetao
            /* pre increment */
1649 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, 4);
1650 6e64da3c Guan Xuetao
        } else {
1651 6e64da3c Guan Xuetao
            /* post increment */
1652 6e64da3c Guan Xuetao
        }
1653 6e64da3c Guan Xuetao
    } else {
1654 6e64da3c Guan Xuetao
        if (UCOP_SET_P) {
1655 6e64da3c Guan Xuetao
            /* pre decrement */
1656 6e64da3c Guan Xuetao
            tcg_gen_addi_i32(addr, addr, -(n * 4));
1657 6e64da3c Guan Xuetao
        } else {
1658 6e64da3c Guan Xuetao
            /* post decrement */
1659 6e64da3c Guan Xuetao
            if (n != 1) {
1660 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
1661 6e64da3c Guan Xuetao
            }
1662 6e64da3c Guan Xuetao
        }
1663 6e64da3c Guan Xuetao
    }
1664 6e64da3c Guan Xuetao
1665 6e64da3c Guan Xuetao
    j = 0;
1666 6e64da3c Guan Xuetao
    reg = UCOP_SET(6) ? 16 : 0;
1667 6e64da3c Guan Xuetao
    for (i = 0; i < 19; i++, reg++) {
1668 6e64da3c Guan Xuetao
        if (i == 6) {
1669 6e64da3c Guan Xuetao
            i = i + 3;
1670 6e64da3c Guan Xuetao
        }
1671 6e64da3c Guan Xuetao
        if (UCOP_SET(i)) {
1672 6e64da3c Guan Xuetao
            if (UCOP_SET_L) { /* load */
1673 6e64da3c Guan Xuetao
                tmp = gen_ld32(addr, IS_USER(s));
1674 6e64da3c Guan Xuetao
                if (reg == 31) {
1675 6e64da3c Guan Xuetao
                    gen_bx(s, tmp);
1676 6e64da3c Guan Xuetao
                } else if (user) {
1677 6e64da3c Guan Xuetao
                    tmp2 = tcg_const_i32(reg);
1678 6e64da3c Guan Xuetao
                    gen_helper_set_user_reg(tmp2, tmp);
1679 6e64da3c Guan Xuetao
                    tcg_temp_free_i32(tmp2);
1680 6e64da3c Guan Xuetao
                    dead_tmp(tmp);
1681 6e64da3c Guan Xuetao
                } else if (reg == UCOP_REG_N) {
1682 6e64da3c Guan Xuetao
                    loaded_var = tmp;
1683 6e64da3c Guan Xuetao
                    loaded_base = 1;
1684 6e64da3c Guan Xuetao
                } else {
1685 6e64da3c Guan Xuetao
                    store_reg(s, reg, tmp);
1686 6e64da3c Guan Xuetao
                }
1687 6e64da3c Guan Xuetao
            } else { /* store */
1688 6e64da3c Guan Xuetao
                if (reg == 31) {
1689 6e64da3c Guan Xuetao
                    /* special case: r31 = PC + 4 */
1690 6e64da3c Guan Xuetao
                    val = (long)s->pc;
1691 6e64da3c Guan Xuetao
                    tmp = new_tmp();
1692 6e64da3c Guan Xuetao
                    tcg_gen_movi_i32(tmp, val);
1693 6e64da3c Guan Xuetao
                } else if (user) {
1694 6e64da3c Guan Xuetao
                    tmp = new_tmp();
1695 6e64da3c Guan Xuetao
                    tmp2 = tcg_const_i32(reg);
1696 6e64da3c Guan Xuetao
                    gen_helper_get_user_reg(tmp, tmp2);
1697 6e64da3c Guan Xuetao
                    tcg_temp_free_i32(tmp2);
1698 6e64da3c Guan Xuetao
                } else {
1699 6e64da3c Guan Xuetao
                    tmp = load_reg(s, reg);
1700 6e64da3c Guan Xuetao
                }
1701 6e64da3c Guan Xuetao
                gen_st32(tmp, addr, IS_USER(s));
1702 6e64da3c Guan Xuetao
            }
1703 6e64da3c Guan Xuetao
            j++;
1704 6e64da3c Guan Xuetao
            /* no need to add after the last transfer */
1705 6e64da3c Guan Xuetao
            if (j != n) {
1706 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, 4);
1707 6e64da3c Guan Xuetao
            }
1708 6e64da3c Guan Xuetao
        }
1709 6e64da3c Guan Xuetao
    }
1710 6e64da3c Guan Xuetao
    if (UCOP_SET_W) { /* write back */
1711 6e64da3c Guan Xuetao
        if (UCOP_SET_U) {
1712 6e64da3c Guan Xuetao
            if (UCOP_SET_P) {
1713 6e64da3c Guan Xuetao
                /* pre increment */
1714 6e64da3c Guan Xuetao
            } else {
1715 6e64da3c Guan Xuetao
                /* post increment */
1716 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, 4);
1717 6e64da3c Guan Xuetao
            }
1718 6e64da3c Guan Xuetao
        } else {
1719 6e64da3c Guan Xuetao
            if (UCOP_SET_P) {
1720 6e64da3c Guan Xuetao
                /* pre decrement */
1721 6e64da3c Guan Xuetao
                if (n != 1) {
1722 6e64da3c Guan Xuetao
                    tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
1723 6e64da3c Guan Xuetao
                }
1724 6e64da3c Guan Xuetao
            } else {
1725 6e64da3c Guan Xuetao
                /* post decrement */
1726 6e64da3c Guan Xuetao
                tcg_gen_addi_i32(addr, addr, -(n * 4));
1727 6e64da3c Guan Xuetao
            }
1728 6e64da3c Guan Xuetao
        }
1729 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, addr);
1730 6e64da3c Guan Xuetao
    } else {
1731 6e64da3c Guan Xuetao
        dead_tmp(addr);
1732 6e64da3c Guan Xuetao
    }
1733 6e64da3c Guan Xuetao
    if (loaded_base) {
1734 6e64da3c Guan Xuetao
        store_reg(s, UCOP_REG_N, loaded_var);
1735 6e64da3c Guan Xuetao
    }
1736 6e64da3c Guan Xuetao
    if (UCOP_SET_B && !user) {
1737 6e64da3c Guan Xuetao
        /* Restore ASR from BSR.  */
1738 6e64da3c Guan Xuetao
        tmp = load_cpu_field(bsr);
1739 6e64da3c Guan Xuetao
        gen_set_asr(tmp, 0xffffffff);
1740 6e64da3c Guan Xuetao
        dead_tmp(tmp);
1741 6e64da3c Guan Xuetao
        s->is_jmp = DISAS_UPDATE;
1742 6e64da3c Guan Xuetao
    }
1743 6e64da3c Guan Xuetao
}
1744 6e64da3c Guan Xuetao
1745 6e64da3c Guan Xuetao
/* branch (and link) */
1746 6e64da3c Guan Xuetao
static void do_branch(CPUState *env, DisasContext *s, uint32_t insn)
1747 6e64da3c Guan Xuetao
{
1748 6e64da3c Guan Xuetao
    unsigned int val;
1749 6e64da3c Guan Xuetao
    int32_t offset;
1750 6e64da3c Guan Xuetao
    TCGv tmp;
1751 6e64da3c Guan Xuetao
1752 6e64da3c Guan Xuetao
    if (UCOP_COND == 0xf) {
1753 6e64da3c Guan Xuetao
        ILLEGAL;
1754 6e64da3c Guan Xuetao
    }
1755 6e64da3c Guan Xuetao
1756 6e64da3c Guan Xuetao
    if (UCOP_COND != 0xe) {
1757 6e64da3c Guan Xuetao
        /* if not always execute, we generate a conditional jump to
1758 6e64da3c Guan Xuetao
           next instruction */
1759 6e64da3c Guan Xuetao
        s->condlabel = gen_new_label();
1760 6e64da3c Guan Xuetao
        gen_test_cc(UCOP_COND ^ 1, s->condlabel);
1761 6e64da3c Guan Xuetao
        s->condjmp = 1;
1762 6e64da3c Guan Xuetao
    }
1763 6e64da3c Guan Xuetao
1764 6e64da3c Guan Xuetao
    val = (int32_t)s->pc;
1765 6e64da3c Guan Xuetao
    if (UCOP_SET_L) {
1766 6e64da3c Guan Xuetao
        tmp = new_tmp();
1767 6e64da3c Guan Xuetao
        tcg_gen_movi_i32(tmp, val);
1768 6e64da3c Guan Xuetao
        store_reg(s, 30, tmp);
1769 6e64da3c Guan Xuetao
    }
1770 6e64da3c Guan Xuetao
    offset = (((int32_t)insn << 8) >> 8);
1771 6e64da3c Guan Xuetao
    val += (offset << 2); /* unicore is pc+4 */
1772 6e64da3c Guan Xuetao
    gen_jmp(s, val);
1773 6e64da3c Guan Xuetao
}
1774 6e64da3c Guan Xuetao
1775 6e64da3c Guan Xuetao
static void disas_uc32_insn(CPUState *env, DisasContext *s)
1776 6e64da3c Guan Xuetao
{
1777 6e64da3c Guan Xuetao
    unsigned int insn;
1778 6e64da3c Guan Xuetao
1779 6e64da3c Guan Xuetao
    insn = ldl_code(s->pc);
1780 6e64da3c Guan Xuetao
    s->pc += 4;
1781 6e64da3c Guan Xuetao
1782 6e64da3c Guan Xuetao
    /* UniCore instructions class:
1783 6e64da3c Guan Xuetao
     * AAAB BBBC xxxx xxxx xxxx xxxD xxEx xxxx
1784 6e64da3c Guan Xuetao
     * AAA  : see switch case
1785 6e64da3c Guan Xuetao
     * BBBB : opcodes or cond or PUBW
1786 6e64da3c Guan Xuetao
     * C    : S OR L
1787 6e64da3c Guan Xuetao
     * D    : 8
1788 6e64da3c Guan Xuetao
     * E    : 5
1789 6e64da3c Guan Xuetao
     */
1790 6e64da3c Guan Xuetao
    switch (insn >> 29) {
1791 fa4e49c0 Gerd Hoffmann
    case 0x0:
1792 6e64da3c Guan Xuetao
        if (UCOP_SET(5) && UCOP_SET(8) && !UCOP_SET(28)) {
1793 6e64da3c Guan Xuetao
            do_mult(env, s, insn);
1794 6e64da3c Guan Xuetao
            break;
1795 6e64da3c Guan Xuetao
        }
1796 6e64da3c Guan Xuetao
1797 6e64da3c Guan Xuetao
        if (UCOP_SET(8)) {
1798 6e64da3c Guan Xuetao
            do_misc(env, s, insn);
1799 6e64da3c Guan Xuetao
            break;
1800 6e64da3c Guan Xuetao
        }
1801 fa4e49c0 Gerd Hoffmann
    case 0x1:
1802 6e64da3c Guan Xuetao
        if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
1803 6e64da3c Guan Xuetao
            do_misc(env, s, insn);
1804 6e64da3c Guan Xuetao
            break;
1805 6e64da3c Guan Xuetao
        }
1806 6e64da3c Guan Xuetao
        do_datap(env, s, insn);
1807 6e64da3c Guan Xuetao
        break;
1808 6e64da3c Guan Xuetao
1809 fa4e49c0 Gerd Hoffmann
    case 0x2:
1810 6e64da3c Guan Xuetao
        if (UCOP_SET(8) && UCOP_SET(5)) {
1811 6e64da3c Guan Xuetao
            do_ldst_hwsb(env, s, insn);
1812 6e64da3c Guan Xuetao
            break;
1813 6e64da3c Guan Xuetao
        }
1814 6e64da3c Guan Xuetao
        if (UCOP_SET(8) || UCOP_SET(5)) {
1815 6e64da3c Guan Xuetao
            ILLEGAL;
1816 6e64da3c Guan Xuetao
        }
1817 fa4e49c0 Gerd Hoffmann
    case 0x3:
1818 6e64da3c Guan Xuetao
        do_ldst_ir(env, s, insn);
1819 6e64da3c Guan Xuetao
        break;
1820 6e64da3c Guan Xuetao
1821 fa4e49c0 Gerd Hoffmann
    case 0x4:
1822 6e64da3c Guan Xuetao
        if (UCOP_SET(8)) {
1823 6e64da3c Guan Xuetao
            ILLEGAL; /* extended instructions */
1824 6e64da3c Guan Xuetao
        }
1825 6e64da3c Guan Xuetao
        do_ldst_m(env, s, insn);
1826 6e64da3c Guan Xuetao
        break;
1827 fa4e49c0 Gerd Hoffmann
    case 0x5:
1828 6e64da3c Guan Xuetao
        do_branch(env, s, insn);
1829 6e64da3c Guan Xuetao
        break;
1830 fa4e49c0 Gerd Hoffmann
    case 0x6:
1831 6e64da3c Guan Xuetao
        /* Coprocessor.  */
1832 6e64da3c Guan Xuetao
        disas_coproc_insn(env, s, insn);
1833 6e64da3c Guan Xuetao
        break;
1834 fa4e49c0 Gerd Hoffmann
    case 0x7:
1835 6e64da3c Guan Xuetao
        if (!UCOP_SET(28)) {
1836 6e64da3c Guan Xuetao
            disas_coproc_insn(env, s, insn);
1837 6e64da3c Guan Xuetao
            break;
1838 6e64da3c Guan Xuetao
        }
1839 6e64da3c Guan Xuetao
        if ((insn & 0xff000000) == 0xff000000) { /* syscall */
1840 6e64da3c Guan Xuetao
            gen_set_pc_im(s->pc);
1841 6e64da3c Guan Xuetao
            s->is_jmp = DISAS_SYSCALL;
1842 6e64da3c Guan Xuetao
            break;
1843 6e64da3c Guan Xuetao
        }
1844 6e64da3c Guan Xuetao
        ILLEGAL;
1845 6e64da3c Guan Xuetao
    }
1846 6e64da3c Guan Xuetao
1847 6e64da3c Guan Xuetao
    return;
1848 6e64da3c Guan Xuetao
}
1849 6e64da3c Guan Xuetao
1850 6e64da3c Guan Xuetao
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
1851 6e64da3c Guan Xuetao
   basic block 'tb'. If search_pc is TRUE, also generate PC
1852 6e64da3c Guan Xuetao
   information for each intermediate instruction. */
1853 6e64da3c Guan Xuetao
static inline void gen_intermediate_code_internal(CPUState *env,
1854 6e64da3c Guan Xuetao
        TranslationBlock *tb, int search_pc)
1855 6e64da3c Guan Xuetao
{
1856 6e64da3c Guan Xuetao
    DisasContext dc1, *dc = &dc1;
1857 6e64da3c Guan Xuetao
    CPUBreakpoint *bp;
1858 6e64da3c Guan Xuetao
    uint16_t *gen_opc_end;
1859 6e64da3c Guan Xuetao
    int j, lj;
1860 6e64da3c Guan Xuetao
    target_ulong pc_start;
1861 6e64da3c Guan Xuetao
    uint32_t next_page_start;
1862 6e64da3c Guan Xuetao
    int num_insns;
1863 6e64da3c Guan Xuetao
    int max_insns;
1864 6e64da3c Guan Xuetao
1865 6e64da3c Guan Xuetao
    /* generate intermediate code */
1866 6e64da3c Guan Xuetao
    num_temps = 0;
1867 6e64da3c Guan Xuetao
1868 6e64da3c Guan Xuetao
    pc_start = tb->pc;
1869 6e64da3c Guan Xuetao
1870 6e64da3c Guan Xuetao
    dc->tb = tb;
1871 6e64da3c Guan Xuetao
1872 6e64da3c Guan Xuetao
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1873 6e64da3c Guan Xuetao
1874 6e64da3c Guan Xuetao
    dc->is_jmp = DISAS_NEXT;
1875 6e64da3c Guan Xuetao
    dc->pc = pc_start;
1876 6e64da3c Guan Xuetao
    dc->singlestep_enabled = env->singlestep_enabled;
1877 6e64da3c Guan Xuetao
    dc->condjmp = 0;
1878 6e64da3c Guan Xuetao
    cpu_F0s = tcg_temp_new_i32();
1879 6e64da3c Guan Xuetao
    cpu_F1s = tcg_temp_new_i32();
1880 6e64da3c Guan Xuetao
    cpu_F0d = tcg_temp_new_i64();
1881 6e64da3c Guan Xuetao
    cpu_F1d = tcg_temp_new_i64();
1882 6e64da3c Guan Xuetao
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1883 6e64da3c Guan Xuetao
    lj = -1;
1884 6e64da3c Guan Xuetao
    num_insns = 0;
1885 6e64da3c Guan Xuetao
    max_insns = tb->cflags & CF_COUNT_MASK;
1886 6e64da3c Guan Xuetao
    if (max_insns == 0) {
1887 6e64da3c Guan Xuetao
        max_insns = CF_COUNT_MASK;
1888 6e64da3c Guan Xuetao
    }
1889 6e64da3c Guan Xuetao
1890 6e64da3c Guan Xuetao
    gen_icount_start();
1891 6e64da3c Guan Xuetao
    do {
1892 6e64da3c Guan Xuetao
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
1893 6e64da3c Guan Xuetao
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1894 6e64da3c Guan Xuetao
                if (bp->pc == dc->pc) {
1895 6e64da3c Guan Xuetao
                    gen_set_pc_im(dc->pc);
1896 6e64da3c Guan Xuetao
                    gen_exception(EXCP_DEBUG);
1897 6e64da3c Guan Xuetao
                    dc->is_jmp = DISAS_JUMP;
1898 6e64da3c Guan Xuetao
                    /* Advance PC so that clearing the breakpoint will
1899 6e64da3c Guan Xuetao
                       invalidate this TB.  */
1900 6e64da3c Guan Xuetao
                    dc->pc += 2; /* FIXME */
1901 6e64da3c Guan Xuetao
                    goto done_generating;
1902 6e64da3c Guan Xuetao
                    break;
1903 6e64da3c Guan Xuetao
                }
1904 6e64da3c Guan Xuetao
            }
1905 6e64da3c Guan Xuetao
        }
1906 6e64da3c Guan Xuetao
        if (search_pc) {
1907 6e64da3c Guan Xuetao
            j = gen_opc_ptr - gen_opc_buf;
1908 6e64da3c Guan Xuetao
            if (lj < j) {
1909 6e64da3c Guan Xuetao
                lj++;
1910 6e64da3c Guan Xuetao
                while (lj < j) {
1911 6e64da3c Guan Xuetao
                    gen_opc_instr_start[lj++] = 0;
1912 6e64da3c Guan Xuetao
                }
1913 6e64da3c Guan Xuetao
            }
1914 6e64da3c Guan Xuetao
            gen_opc_pc[lj] = dc->pc;
1915 6e64da3c Guan Xuetao
            gen_opc_instr_start[lj] = 1;
1916 6e64da3c Guan Xuetao
            gen_opc_icount[lj] = num_insns;
1917 6e64da3c Guan Xuetao
        }
1918 6e64da3c Guan Xuetao
1919 6e64da3c Guan Xuetao
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
1920 6e64da3c Guan Xuetao
            gen_io_start();
1921 6e64da3c Guan Xuetao
        }
1922 6e64da3c Guan Xuetao
1923 6e64da3c Guan Xuetao
        disas_uc32_insn(env, dc);
1924 6e64da3c Guan Xuetao
1925 6e64da3c Guan Xuetao
        if (num_temps) {
1926 6e64da3c Guan Xuetao
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
1927 6e64da3c Guan Xuetao
            num_temps = 0;
1928 6e64da3c Guan Xuetao
        }
1929 6e64da3c Guan Xuetao
1930 6e64da3c Guan Xuetao
        if (dc->condjmp && !dc->is_jmp) {
1931 6e64da3c Guan Xuetao
            gen_set_label(dc->condlabel);
1932 6e64da3c Guan Xuetao
            dc->condjmp = 0;
1933 6e64da3c Guan Xuetao
        }
1934 6e64da3c Guan Xuetao
        /* Translation stops when a conditional branch is encountered.
1935 6e64da3c Guan Xuetao
         * Otherwise the subsequent code could get translated several times.
1936 6e64da3c Guan Xuetao
         * Also stop translation when a page boundary is reached.  This
1937 6e64da3c Guan Xuetao
         * ensures prefetch aborts occur at the right place.  */
1938 6e64da3c Guan Xuetao
        num_insns++;
1939 6e64da3c Guan Xuetao
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
1940 6e64da3c Guan Xuetao
             !env->singlestep_enabled &&
1941 6e64da3c Guan Xuetao
             !singlestep &&
1942 6e64da3c Guan Xuetao
             dc->pc < next_page_start &&
1943 6e64da3c Guan Xuetao
             num_insns < max_insns);
1944 6e64da3c Guan Xuetao
1945 6e64da3c Guan Xuetao
    if (tb->cflags & CF_LAST_IO) {
1946 6e64da3c Guan Xuetao
        if (dc->condjmp) {
1947 6e64da3c Guan Xuetao
            /* FIXME:  This can theoretically happen with self-modifying
1948 6e64da3c Guan Xuetao
               code.  */
1949 6e64da3c Guan Xuetao
            cpu_abort(env, "IO on conditional branch instruction");
1950 6e64da3c Guan Xuetao
        }
1951 6e64da3c Guan Xuetao
        gen_io_end();
1952 6e64da3c Guan Xuetao
    }
1953 6e64da3c Guan Xuetao
1954 6e64da3c Guan Xuetao
    /* At this stage dc->condjmp will only be set when the skipped
1955 6e64da3c Guan Xuetao
       instruction was a conditional branch or trap, and the PC has
1956 6e64da3c Guan Xuetao
       already been written.  */
1957 6e64da3c Guan Xuetao
    if (unlikely(env->singlestep_enabled)) {
1958 6e64da3c Guan Xuetao
        /* Make sure the pc is updated, and raise a debug exception.  */
1959 6e64da3c Guan Xuetao
        if (dc->condjmp) {
1960 6e64da3c Guan Xuetao
            if (dc->is_jmp == DISAS_SYSCALL) {
1961 6e64da3c Guan Xuetao
                gen_exception(UC32_EXCP_PRIV);
1962 6e64da3c Guan Xuetao
            } else {
1963 6e64da3c Guan Xuetao
                gen_exception(EXCP_DEBUG);
1964 6e64da3c Guan Xuetao
            }
1965 6e64da3c Guan Xuetao
            gen_set_label(dc->condlabel);
1966 6e64da3c Guan Xuetao
        }
1967 6e64da3c Guan Xuetao
        if (dc->condjmp || !dc->is_jmp) {
1968 6e64da3c Guan Xuetao
            gen_set_pc_im(dc->pc);
1969 6e64da3c Guan Xuetao
            dc->condjmp = 0;
1970 6e64da3c Guan Xuetao
        }
1971 6e64da3c Guan Xuetao
        if (dc->is_jmp == DISAS_SYSCALL && !dc->condjmp) {
1972 6e64da3c Guan Xuetao
            gen_exception(UC32_EXCP_PRIV);
1973 6e64da3c Guan Xuetao
        } else {
1974 6e64da3c Guan Xuetao
            gen_exception(EXCP_DEBUG);
1975 6e64da3c Guan Xuetao
        }
1976 6e64da3c Guan Xuetao
    } else {
1977 6e64da3c Guan Xuetao
        /* While branches must always occur at the end of an IT block,
1978 6e64da3c Guan Xuetao
           there are a few other things that can cause us to terminate
1979 6e64da3c Guan Xuetao
           the TB in the middel of an IT block:
1980 6e64da3c Guan Xuetao
            - Exception generating instructions (bkpt, swi, undefined).
1981 6e64da3c Guan Xuetao
            - Page boundaries.
1982 6e64da3c Guan Xuetao
            - Hardware watchpoints.
1983 6e64da3c Guan Xuetao
           Hardware breakpoints have already been handled and skip this code.
1984 6e64da3c Guan Xuetao
         */
1985 6e64da3c Guan Xuetao
        switch (dc->is_jmp) {
1986 6e64da3c Guan Xuetao
        case DISAS_NEXT:
1987 6e64da3c Guan Xuetao
            gen_goto_tb(dc, 1, dc->pc);
1988 6e64da3c Guan Xuetao
            break;
1989 6e64da3c Guan Xuetao
        default:
1990 6e64da3c Guan Xuetao
        case DISAS_JUMP:
1991 6e64da3c Guan Xuetao
        case DISAS_UPDATE:
1992 6e64da3c Guan Xuetao
            /* indicate that the hash table must be used to find the next TB */
1993 6e64da3c Guan Xuetao
            tcg_gen_exit_tb(0);
1994 6e64da3c Guan Xuetao
            break;
1995 6e64da3c Guan Xuetao
        case DISAS_TB_JUMP:
1996 6e64da3c Guan Xuetao
            /* nothing more to generate */
1997 6e64da3c Guan Xuetao
            break;
1998 6e64da3c Guan Xuetao
        case DISAS_SYSCALL:
1999 6e64da3c Guan Xuetao
            gen_exception(UC32_EXCP_PRIV);
2000 6e64da3c Guan Xuetao
            break;
2001 6e64da3c Guan Xuetao
        }
2002 6e64da3c Guan Xuetao
        if (dc->condjmp) {
2003 6e64da3c Guan Xuetao
            gen_set_label(dc->condlabel);
2004 6e64da3c Guan Xuetao
            gen_goto_tb(dc, 1, dc->pc);
2005 6e64da3c Guan Xuetao
            dc->condjmp = 0;
2006 6e64da3c Guan Xuetao
        }
2007 6e64da3c Guan Xuetao
    }
2008 6e64da3c Guan Xuetao
2009 6e64da3c Guan Xuetao
done_generating:
2010 6e64da3c Guan Xuetao
    gen_icount_end(tb, num_insns);
2011 6e64da3c Guan Xuetao
    *gen_opc_ptr = INDEX_op_end;
2012 6e64da3c Guan Xuetao
2013 6e64da3c Guan Xuetao
#ifdef DEBUG_DISAS
2014 6e64da3c Guan Xuetao
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
2015 6e64da3c Guan Xuetao
        qemu_log("----------------\n");
2016 6e64da3c Guan Xuetao
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
2017 6e64da3c Guan Xuetao
        log_target_disas(pc_start, dc->pc - pc_start, 0);
2018 6e64da3c Guan Xuetao
        qemu_log("\n");
2019 6e64da3c Guan Xuetao
    }
2020 6e64da3c Guan Xuetao
#endif
2021 6e64da3c Guan Xuetao
    if (search_pc) {
2022 6e64da3c Guan Xuetao
        j = gen_opc_ptr - gen_opc_buf;
2023 6e64da3c Guan Xuetao
        lj++;
2024 6e64da3c Guan Xuetao
        while (lj <= j) {
2025 6e64da3c Guan Xuetao
            gen_opc_instr_start[lj++] = 0;
2026 6e64da3c Guan Xuetao
        }
2027 6e64da3c Guan Xuetao
    } else {
2028 6e64da3c Guan Xuetao
        tb->size = dc->pc - pc_start;
2029 6e64da3c Guan Xuetao
        tb->icount = num_insns;
2030 6e64da3c Guan Xuetao
    }
2031 6e64da3c Guan Xuetao
}
2032 6e64da3c Guan Xuetao
2033 6e64da3c Guan Xuetao
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
2034 6e64da3c Guan Xuetao
{
2035 6e64da3c Guan Xuetao
    gen_intermediate_code_internal(env, tb, 0);
2036 6e64da3c Guan Xuetao
}
2037 6e64da3c Guan Xuetao
2038 6e64da3c Guan Xuetao
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
2039 6e64da3c Guan Xuetao
{
2040 6e64da3c Guan Xuetao
    gen_intermediate_code_internal(env, tb, 1);
2041 6e64da3c Guan Xuetao
}
2042 6e64da3c Guan Xuetao
2043 6e64da3c Guan Xuetao
static const char *cpu_mode_names[16] = {
2044 6e64da3c Guan Xuetao
    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
2045 6e64da3c Guan Xuetao
    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
2046 6e64da3c Guan Xuetao
};
2047 6e64da3c Guan Xuetao
2048 6e64da3c Guan Xuetao
#define UCF64_DUMP_STATE
2049 6e64da3c Guan Xuetao
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
2050 6e64da3c Guan Xuetao
        int flags)
2051 6e64da3c Guan Xuetao
{
2052 6e64da3c Guan Xuetao
    int i;
2053 6e64da3c Guan Xuetao
#ifdef UCF64_DUMP_STATE
2054 6e64da3c Guan Xuetao
    union {
2055 6e64da3c Guan Xuetao
        uint32_t i;
2056 6e64da3c Guan Xuetao
        float s;
2057 6e64da3c Guan Xuetao
    } s0, s1;
2058 6e64da3c Guan Xuetao
    CPU_DoubleU d;
2059 6e64da3c Guan Xuetao
    /* ??? This assumes float64 and double have the same layout.
2060 6e64da3c Guan Xuetao
       Oh well, it's only debug dumps.  */
2061 6e64da3c Guan Xuetao
    union {
2062 6e64da3c Guan Xuetao
        float64 f64;
2063 6e64da3c Guan Xuetao
        double d;
2064 6e64da3c Guan Xuetao
    } d0;
2065 6e64da3c Guan Xuetao
#endif
2066 6e64da3c Guan Xuetao
    uint32_t psr;
2067 6e64da3c Guan Xuetao
2068 6e64da3c Guan Xuetao
    for (i = 0; i < 32; i++) {
2069 6e64da3c Guan Xuetao
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
2070 6e64da3c Guan Xuetao
        if ((i % 4) == 3) {
2071 6e64da3c Guan Xuetao
            cpu_fprintf(f, "\n");
2072 6e64da3c Guan Xuetao
        } else {
2073 6e64da3c Guan Xuetao
            cpu_fprintf(f, " ");
2074 6e64da3c Guan Xuetao
        }
2075 6e64da3c Guan Xuetao
    }
2076 6e64da3c Guan Xuetao
    psr = cpu_asr_read(env);
2077 6e64da3c Guan Xuetao
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
2078 6e64da3c Guan Xuetao
                psr,
2079 6e64da3c Guan Xuetao
                psr & (1 << 31) ? 'N' : '-',
2080 6e64da3c Guan Xuetao
                psr & (1 << 30) ? 'Z' : '-',
2081 6e64da3c Guan Xuetao
                psr & (1 << 29) ? 'C' : '-',
2082 6e64da3c Guan Xuetao
                psr & (1 << 28) ? 'V' : '-',
2083 6e64da3c Guan Xuetao
                cpu_mode_names[psr & 0xf]);
2084 6e64da3c Guan Xuetao
2085 6e64da3c Guan Xuetao
#ifdef UCF64_DUMP_STATE
2086 6e64da3c Guan Xuetao
    for (i = 0; i < 16; i++) {
2087 6e64da3c Guan Xuetao
        d.d = env->ucf64.regs[i];
2088 6e64da3c Guan Xuetao
        s0.i = d.l.lower;
2089 6e64da3c Guan Xuetao
        s1.i = d.l.upper;
2090 6e64da3c Guan Xuetao
        d0.f64 = d.d;
2091 6e64da3c Guan Xuetao
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%" PRIx64 "(%8g)\n",
2092 6e64da3c Guan Xuetao
                    i * 2, (int)s0.i, s0.s,
2093 6e64da3c Guan Xuetao
                    i * 2 + 1, (int)s1.i, s1.s,
2094 6e64da3c Guan Xuetao
                    i, (uint64_t)d0.f64, d0.d);
2095 6e64da3c Guan Xuetao
    }
2096 6e64da3c Guan Xuetao
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
2097 6e64da3c Guan Xuetao
#endif
2098 6e64da3c Guan Xuetao
}
2099 6e64da3c Guan Xuetao
2100 e87b7cb0 Stefan Weil
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
2101 6e64da3c Guan Xuetao
{
2102 6e64da3c Guan Xuetao
    env->regs[31] = gen_opc_pc[pc_pos];
2103 6e64da3c Guan Xuetao
}