~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to target-m68k/translate.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2009-03-22 10:13:17 UTC
  • mfrom: (1.2.1 upstream) (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090322101317-iigjtnu5qil35dtb
Tags: 0.10.1-1
[ Aurelien Jarno ]
* New upstream stable release:
  - patches/80_stable-branch.patch: remove.
* debian/control: 
  - Remove depends on proll.
  - Move depends on device-tree-compiler to build-depends.
  - Bump Standards-Version to 3.8.1 (no changes).
* patches/82_qemu-img_decimal.patch: new patch from upstream to make
  qemu-img accept sizes with decimal values (closes: bug#501400).

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 *
17
17
 * You should have received a copy of the GNU Lesser General Public
18
18
 * License along with this library; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20
20
 */
21
21
#include <stdarg.h>
22
22
#include <stdlib.h>
23
23
#include <stdio.h>
24
24
#include <string.h>
25
25
#include <inttypes.h>
 
26
#include <assert.h>
26
27
 
27
28
#include "config.h"
28
29
#include "cpu.h"
29
30
#include "exec-all.h"
30
31
#include "disas.h"
31
 
#include "m68k-qreg.h"
 
32
#include "tcg-op.h"
 
33
#include "qemu-log.h"
 
34
 
 
35
#include "helpers.h"
 
36
#define GEN_HELPER 1
 
37
#include "helpers.h"
32
38
 
33
39
//#define DEBUG_DISPATCH 1
34
40
 
 
41
/* Fake floating point.  */
 
42
#define tcg_gen_mov_f64 tcg_gen_mov_i64
 
43
#define tcg_gen_qemu_ldf64 tcg_gen_qemu_ld64
 
44
#define tcg_gen_qemu_stf64 tcg_gen_qemu_st64
 
45
 
 
46
#define DEFO32(name, offset) static TCGv QREG_##name;
 
47
#define DEFO64(name, offset) static TCGv_i64 QREG_##name;
 
48
#define DEFF64(name, offset) static TCGv_i64 QREG_##name;
 
49
#include "qregs.def"
 
50
#undef DEFO32
 
51
#undef DEFO64
 
52
#undef DEFF64
 
53
 
 
54
static TCGv_ptr cpu_env;
 
55
 
 
56
static char cpu_reg_names[3*8*3 + 5*4];
 
57
static TCGv cpu_dregs[8];
 
58
static TCGv cpu_aregs[8];
 
59
static TCGv_i64 cpu_fregs[8];
 
60
static TCGv_i64 cpu_macc[4];
 
61
 
 
62
#define DREG(insn, pos) cpu_dregs[((insn) >> (pos)) & 7]
 
63
#define AREG(insn, pos) cpu_aregs[((insn) >> (pos)) & 7]
 
64
#define FREG(insn, pos) cpu_fregs[((insn) >> (pos)) & 7]
 
65
#define MACREG(acc) cpu_macc[acc]
 
66
#define QREG_SP cpu_aregs[7]
 
67
 
 
68
static TCGv NULL_QREG;
 
69
#define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG))
 
70
/* Used to distinguish stores from bad addressing modes.  */
 
71
static TCGv store_dummy;
 
72
 
 
73
#include "gen-icount.h"
 
74
 
 
75
void m68k_tcg_init(void)
 
76
{
 
77
    char *p;
 
78
    int i;
 
79
 
 
80
#define DEFO32(name,  offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, offset), #name);
 
81
#define DEFO64(name,  offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, offset), #name);
 
82
#define DEFF64(name,  offset) DEFO64(name, offset)
 
83
#include "qregs.def"
 
84
#undef DEFO32
 
85
#undef DEFO64
 
86
#undef DEFF64
 
87
 
 
88
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
89
 
 
90
    p = cpu_reg_names;
 
91
    for (i = 0; i < 8; i++) {
 
92
        sprintf(p, "D%d", i);
 
93
        cpu_dregs[i] = tcg_global_mem_new(TCG_AREG0,
 
94
                                          offsetof(CPUM68KState, dregs[i]), p);
 
95
        p += 3;
 
96
        sprintf(p, "A%d", i);
 
97
        cpu_aregs[i] = tcg_global_mem_new(TCG_AREG0,
 
98
                                          offsetof(CPUM68KState, aregs[i]), p);
 
99
        p += 3;
 
100
        sprintf(p, "F%d", i);
 
101
        cpu_fregs[i] = tcg_global_mem_new_i64(TCG_AREG0,
 
102
                                          offsetof(CPUM68KState, fregs[i]), p);
 
103
        p += 3;
 
104
    }
 
105
    for (i = 0; i < 4; i++) {
 
106
        sprintf(p, "ACC%d", i);
 
107
        cpu_macc[i] = tcg_global_mem_new_i64(TCG_AREG0,
 
108
                                         offsetof(CPUM68KState, macc[i]), p);
 
109
        p += 5;
 
110
    }
 
111
 
 
112
    NULL_QREG = tcg_global_mem_new(TCG_AREG0, -4, "NULL");
 
113
    store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL");
 
114
 
 
115
#define GEN_HELPER 2
 
116
#include "helpers.h"
 
117
}
 
118
 
35
119
static inline void qemu_assert(int cond, const char *msg)
36
120
{
37
121
    if (!cond) {
52
136
    struct TranslationBlock *tb;
53
137
    int singlestep_enabled;
54
138
    int is_mem;
 
139
    TCGv_i64 mactmp;
 
140
    int done_mac;
55
141
} DisasContext;
56
142
 
57
143
#define DISAS_JUMP_NEXT 4
67
153
static void *gen_throws_exception;
68
154
#define gen_last_qop NULL
69
155
 
70
 
static uint16_t *gen_opc_ptr;
71
 
static uint32_t *gen_opparam_ptr;
72
 
extern FILE *logfile;
73
 
extern int loglevel;
74
 
 
75
 
enum {
76
 
#define DEF(s, n, copy_size) INDEX_op_ ## s,
77
 
#include "opc.h"
78
 
#undef DEF
79
 
    NB_OPS,
80
 
};
81
 
 
82
 
#include "gen-op.h"
83
 
 
84
 
#if defined(CONFIG_USER_ONLY)
85
 
#define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
86
 
#define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
87
 
#else
88
 
#define gen_st(s, name, addr, val) do { \
89
 
    if (IS_USER(s)) \
90
 
        gen_op_st##name##_user(addr, val); \
91
 
    else \
92
 
        gen_op_st##name##_kernel(addr, val); \
93
 
    } while (0)
94
 
#define gen_ld(s, name, val, addr) do { \
95
 
    if (IS_USER(s)) \
96
 
        gen_op_ld##name##_user(val, addr); \
97
 
    else \
98
 
        gen_op_ld##name##_kernel(val, addr); \
99
 
    } while (0)
100
 
#endif
101
 
 
102
 
#include "op-hacks.h"
103
 
 
104
156
#define OS_BYTE 0
105
157
#define OS_WORD 1
106
158
#define OS_LONG 2
107
159
#define OS_SINGLE 4
108
160
#define OS_DOUBLE 5
109
161
 
110
 
#define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
111
 
#define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
112
 
#define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
113
 
 
114
162
typedef void (*disas_proc)(DisasContext *, uint16_t);
115
163
 
116
164
#ifdef DEBUG_DISPATCH
117
165
#define DISAS_INSN(name) \
118
166
  static void real_disas_##name (DisasContext *s, uint16_t insn); \
119
167
  static void disas_##name (DisasContext *s, uint16_t insn) { \
120
 
    if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
 
168
    qemu_log("Dispatch " #name "\n"); \
121
169
    real_disas_##name(s, insn); } \
122
170
  static void real_disas_##name (DisasContext *s, uint16_t insn)
123
171
#else
125
173
  static void disas_##name (DisasContext *s, uint16_t insn)
126
174
#endif
127
175
 
 
176
/* FIXME: Remove this.  */
 
177
#define gen_im32(val) tcg_const_i32(val)
 
178
 
128
179
/* Generate a load from the specified address.  Narrow values are
129
180
   sign extended to full register width.  */
130
 
static inline int gen_load(DisasContext * s, int opsize, int addr, int sign)
 
181
static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
131
182
{
132
 
    int tmp;
 
183
    TCGv tmp;
 
184
    int index = IS_USER(s);
133
185
    s->is_mem = 1;
 
186
    tmp = tcg_temp_new_i32();
134
187
    switch(opsize) {
135
188
    case OS_BYTE:
136
 
        tmp = gen_new_qreg(QMODE_I32);
137
189
        if (sign)
138
 
            gen_ld(s, 8s32, tmp, addr);
 
190
            tcg_gen_qemu_ld8s(tmp, addr, index);
139
191
        else
140
 
            gen_ld(s, 8u32, tmp, addr);
 
192
            tcg_gen_qemu_ld8u(tmp, addr, index);
141
193
        break;
142
194
    case OS_WORD:
143
 
        tmp = gen_new_qreg(QMODE_I32);
144
195
        if (sign)
145
 
            gen_ld(s, 16s32, tmp, addr);
 
196
            tcg_gen_qemu_ld16s(tmp, addr, index);
146
197
        else
147
 
            gen_ld(s, 16u32, tmp, addr);
 
198
            tcg_gen_qemu_ld16u(tmp, addr, index);
148
199
        break;
149
200
    case OS_LONG:
150
 
        tmp = gen_new_qreg(QMODE_I32);
151
 
        gen_ld(s, 32, tmp, addr);
152
 
        break;
153
201
    case OS_SINGLE:
154
 
        tmp = gen_new_qreg(QMODE_F32);
155
 
        gen_ld(s, f32, tmp, addr);
156
 
        break;
157
 
    case OS_DOUBLE:
158
 
        tmp  = gen_new_qreg(QMODE_F64);
159
 
        gen_ld(s, f64, tmp, addr);
 
202
        tcg_gen_qemu_ld32u(tmp, addr, index);
160
203
        break;
161
204
    default:
162
205
        qemu_assert(0, "bad load size");
165
208
    return tmp;
166
209
}
167
210
 
 
211
static inline TCGv_i64 gen_load64(DisasContext * s, TCGv addr)
 
212
{
 
213
    TCGv_i64 tmp;
 
214
    int index = IS_USER(s);
 
215
    s->is_mem = 1;
 
216
    tmp = tcg_temp_new_i64();
 
217
    tcg_gen_qemu_ldf64(tmp, addr, index);
 
218
    gen_throws_exception = gen_last_qop;
 
219
    return tmp;
 
220
}
 
221
 
168
222
/* Generate a store.  */
169
 
static inline void gen_store(DisasContext *s, int opsize, int addr, int val)
 
223
static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
170
224
{
 
225
    int index = IS_USER(s);
171
226
    s->is_mem = 1;
172
227
    switch(opsize) {
173
228
    case OS_BYTE:
174
 
        gen_st(s, 8, addr, val);
 
229
        tcg_gen_qemu_st8(val, addr, index);
175
230
        break;
176
231
    case OS_WORD:
177
 
        gen_st(s, 16, addr, val);
 
232
        tcg_gen_qemu_st16(val, addr, index);
178
233
        break;
179
234
    case OS_LONG:
180
 
        gen_st(s, 32, addr, val);
181
 
        break;
182
235
    case OS_SINGLE:
183
 
        gen_st(s, f32, addr, val);
184
 
        break;
185
 
    case OS_DOUBLE:
186
 
        gen_st(s, f64, addr, val);
 
236
        tcg_gen_qemu_st32(val, addr, index);
187
237
        break;
188
238
    default:
189
239
        qemu_assert(0, "bad store size");
191
241
    gen_throws_exception = gen_last_qop;
192
242
}
193
243
 
 
244
static inline void gen_store64(DisasContext *s, TCGv addr, TCGv_i64 val)
 
245
{
 
246
    int index = IS_USER(s);
 
247
    s->is_mem = 1;
 
248
    tcg_gen_qemu_stf64(val, addr, index);
 
249
    gen_throws_exception = gen_last_qop;
 
250
}
 
251
 
 
252
typedef enum {
 
253
    EA_STORE,
 
254
    EA_LOADU,
 
255
    EA_LOADS
 
256
} ea_what;
 
257
 
194
258
/* Generate an unsigned load if VAL is 0 a signed load if val is -1,
195
259
   otherwise generate a store.  */
196
 
static int gen_ldst(DisasContext *s, int opsize, int addr, int val)
 
260
static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
 
261
                     ea_what what)
197
262
{
198
 
    if (val > 0) {
 
263
    if (what == EA_STORE) {
199
264
        gen_store(s, opsize, addr, val);
200
 
        return 0;
 
265
        return store_dummy;
201
266
    } else {
202
 
        return gen_load(s, opsize, addr, val != 0);
 
267
        return gen_load(s, opsize, addr, what == EA_LOADS);
203
268
    }
204
269
}
205
270
 
215
280
}
216
281
 
217
282
/* Calculate and address index.  */
218
 
static int gen_addr_index(uint16_t ext, int tmp)
 
283
static TCGv gen_addr_index(uint16_t ext, TCGv tmp)
219
284
{
220
 
    int add;
 
285
    TCGv add;
221
286
    int scale;
222
287
 
223
288
    add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
224
289
    if ((ext & 0x800) == 0) {
225
 
        gen_op_ext16s32(tmp, add);
 
290
        tcg_gen_ext16s_i32(tmp, add);
226
291
        add = tmp;
227
292
    }
228
293
    scale = (ext >> 9) & 3;
229
294
    if (scale != 0) {
230
 
        gen_op_shl32(tmp, add, gen_im32(scale));
 
295
        tcg_gen_shli_i32(tmp, add, scale);
231
296
        add = tmp;
232
297
    }
233
298
    return add;
234
299
}
235
300
 
236
 
/* Handle a base + index + displacement effective addresss.  A base of
237
 
   -1 means pc-relative.  */
238
 
static int gen_lea_indexed(DisasContext *s, int opsize, int base)
 
301
/* Handle a base + index + displacement effective addresss.
 
302
   A NULL_QREG base means pc-relative.  */
 
303
static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
239
304
{
240
305
    uint32_t offset;
241
306
    uint16_t ext;
242
 
    int add;
243
 
    int tmp;
 
307
    TCGv add;
 
308
    TCGv tmp;
244
309
    uint32_t bd, od;
245
310
 
246
311
    offset = s->pc;
248
313
    s->pc += 2;
249
314
 
250
315
    if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
251
 
        return -1;
 
316
        return NULL_QREG;
252
317
 
253
318
    if (ext & 0x100) {
254
319
        /* full extension word format */
255
320
        if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
256
 
            return -1;
 
321
            return NULL_QREG;
257
322
 
258
323
        if ((ext & 0x30) > 0x10) {
259
324
            /* base displacement */
266
331
        } else {
267
332
            bd = 0;
268
333
        }
269
 
        tmp = gen_new_qreg(QMODE_I32);
 
334
        tmp = tcg_temp_new();
270
335
        if ((ext & 0x44) == 0) {
271
336
            /* pre-index */
272
337
            add = gen_addr_index(ext, tmp);
273
338
        } else {
274
 
            add = QREG_NULL;
 
339
            add = NULL_QREG;
275
340
        }
276
341
        if ((ext & 0x80) == 0) {
277
342
            /* base not suppressed */
278
 
            if (base == -1) {
 
343
            if (IS_NULL_QREG(base)) {
279
344
                base = gen_im32(offset + bd);
280
345
                bd = 0;
281
346
            }
282
 
            if (add) {
283
 
                gen_op_add32(tmp, add, base);
 
347
            if (!IS_NULL_QREG(add)) {
 
348
                tcg_gen_add_i32(tmp, add, base);
284
349
                add = tmp;
285
350
            } else {
286
351
                add = base;
287
352
            }
288
353
        }
289
 
        if (add) {
 
354
        if (!IS_NULL_QREG(add)) {
290
355
            if (bd != 0) {
291
 
                gen_op_add32(tmp, add, gen_im32(bd));
 
356
                tcg_gen_addi_i32(tmp, add, bd);
292
357
                add = tmp;
293
358
            }
294
359
        } else {
299
364
            base = gen_load(s, OS_LONG, add, 0);
300
365
            if ((ext & 0x44) == 4) {
301
366
                add = gen_addr_index(ext, tmp);
302
 
                gen_op_add32(tmp, add, base);
 
367
                tcg_gen_add_i32(tmp, add, base);
303
368
                add = tmp;
304
369
            } else {
305
370
                add = base;
316
381
                od = 0;
317
382
            }
318
383
            if (od != 0) {
319
 
                gen_op_add32(tmp, add, gen_im32(od));
 
384
                tcg_gen_addi_i32(tmp, add, od);
320
385
                add = tmp;
321
386
            }
322
387
        }
323
388
    } else {
324
389
        /* brief extension word format */
325
 
        tmp = gen_new_qreg(QMODE_I32);
 
390
        tmp = tcg_temp_new();
326
391
        add = gen_addr_index(ext, tmp);
327
 
        if (base != -1) {
328
 
            gen_op_add32(tmp, add, base);
 
392
        if (!IS_NULL_QREG(base)) {
 
393
            tcg_gen_add_i32(tmp, add, base);
329
394
            if ((int8_t)ext)
330
 
                gen_op_add32(tmp, tmp, gen_im32((int8_t)ext));
 
395
                tcg_gen_addi_i32(tmp, tmp, (int8_t)ext);
331
396
        } else {
332
 
            gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
 
397
            tcg_gen_addi_i32(tmp, add, offset + (int8_t)ext);
333
398
        }
334
399
        add = tmp;
335
400
    }
340
405
static inline void gen_flush_cc_op(DisasContext *s)
341
406
{
342
407
    if (s->cc_op != CC_OP_DYNAMIC)
343
 
        gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
 
408
        tcg_gen_movi_i32(QREG_CC_OP, s->cc_op);
344
409
}
345
410
 
346
411
/* Evaluate all the CC flags.  */
349
414
    if (s->cc_op == CC_OP_FLAGS)
350
415
        return;
351
416
    gen_flush_cc_op(s);
352
 
    gen_op_flush_flags();
 
417
    gen_helper_flush_flags(cpu_env, QREG_CC_OP);
353
418
    s->cc_op = CC_OP_FLAGS;
354
419
}
355
420
 
 
421
static void gen_logic_cc(DisasContext *s, TCGv val)
 
422
{
 
423
    tcg_gen_mov_i32(QREG_CC_DEST, val);
 
424
    s->cc_op = CC_OP_LOGIC;
 
425
}
 
426
 
 
427
static void gen_update_cc_add(TCGv dest, TCGv src)
 
428
{
 
429
    tcg_gen_mov_i32(QREG_CC_DEST, dest);
 
430
    tcg_gen_mov_i32(QREG_CC_SRC, src);
 
431
}
 
432
 
356
433
static inline int opsize_bytes(int opsize)
357
434
{
358
435
    switch (opsize) {
363
440
    case OS_DOUBLE: return 8;
364
441
    default:
365
442
        qemu_assert(0, "bad operand size");
 
443
        return 0;
366
444
    }
367
445
}
368
446
 
369
447
/* Assign value to a register.  If the width is less than the register width
370
448
   only the low part of the register is set.  */
371
 
static void gen_partset_reg(int opsize, int reg, int val)
 
449
static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
372
450
{
373
 
    int tmp;
 
451
    TCGv tmp;
374
452
    switch (opsize) {
375
453
    case OS_BYTE:
376
 
        gen_op_and32(reg, reg, gen_im32(0xffffff00));
377
 
        tmp = gen_new_qreg(QMODE_I32);
378
 
        gen_op_and32(tmp, val, gen_im32(0xff));
379
 
        gen_op_or32(reg, reg, tmp);
 
454
        tcg_gen_andi_i32(reg, reg, 0xffffff00);
 
455
        tmp = tcg_temp_new();
 
456
        tcg_gen_ext8u_i32(tmp, val);
 
457
        tcg_gen_or_i32(reg, reg, tmp);
380
458
        break;
381
459
    case OS_WORD:
382
 
        gen_op_and32(reg, reg, gen_im32(0xffff0000));
383
 
        tmp = gen_new_qreg(QMODE_I32);
384
 
        gen_op_and32(tmp, val, gen_im32(0xffff));
385
 
        gen_op_or32(reg, reg, tmp);
 
460
        tcg_gen_andi_i32(reg, reg, 0xffff0000);
 
461
        tmp = tcg_temp_new();
 
462
        tcg_gen_ext16u_i32(tmp, val);
 
463
        tcg_gen_or_i32(reg, reg, tmp);
386
464
        break;
387
465
    case OS_LONG:
388
 
        gen_op_mov32(reg, val);
389
 
        break;
390
466
    case OS_SINGLE:
391
 
        gen_op_pack_32_f32(reg, val);
 
467
        tcg_gen_mov_i32(reg, val);
392
468
        break;
393
469
    default:
394
470
        qemu_assert(0, "Bad operand size");
397
473
}
398
474
 
399
475
/* Sign or zero extend a value.  */
400
 
static inline int gen_extend(int val, int opsize, int sign)
 
476
static inline TCGv gen_extend(TCGv val, int opsize, int sign)
401
477
{
402
 
    int tmp;
 
478
    TCGv tmp;
403
479
 
404
480
    switch (opsize) {
405
481
    case OS_BYTE:
406
 
        tmp = gen_new_qreg(QMODE_I32);
 
482
        tmp = tcg_temp_new();
407
483
        if (sign)
408
 
            gen_op_ext8s32(tmp, val);
 
484
            tcg_gen_ext8s_i32(tmp, val);
409
485
        else
410
 
            gen_op_ext8u32(tmp, val);
 
486
            tcg_gen_ext8u_i32(tmp, val);
411
487
        break;
412
488
    case OS_WORD:
413
 
        tmp = gen_new_qreg(QMODE_I32);
 
489
        tmp = tcg_temp_new();
414
490
        if (sign)
415
 
            gen_op_ext16s32(tmp, val);
 
491
            tcg_gen_ext16s_i32(tmp, val);
416
492
        else
417
 
            gen_op_ext16u32(tmp, val);
 
493
            tcg_gen_ext16u_i32(tmp, val);
418
494
        break;
419
495
    case OS_LONG:
 
496
    case OS_SINGLE:
420
497
        tmp = val;
421
498
        break;
422
 
    case OS_SINGLE:
423
 
        tmp = gen_new_qreg(QMODE_F32);
424
 
        gen_op_pack_f32_32(tmp, val);
425
 
        break;
426
499
    default:
427
500
        qemu_assert(0, "Bad operand size");
428
501
    }
430
503
}
431
504
 
432
505
/* Generate code for an "effective address".  Does not adjust the base
433
 
   register for autoincrememnt addressing modes.  */
434
 
static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
 
506
   register for autoincrement addressing modes.  */
 
507
static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
435
508
{
436
 
    int reg;
437
 
    int tmp;
 
509
    TCGv reg;
 
510
    TCGv tmp;
438
511
    uint16_t ext;
439
512
    uint32_t offset;
440
513
 
441
 
    reg = insn & 7;
442
514
    switch ((insn >> 3) & 7) {
443
515
    case 0: /* Data register direct.  */
444
516
    case 1: /* Address register direct.  */
445
 
        return -1;
 
517
        return NULL_QREG;
446
518
    case 2: /* Indirect register */
447
519
    case 3: /* Indirect postincrement.  */
448
 
        reg += QREG_A0;
449
 
        return reg;
 
520
        return AREG(insn, 0);
450
521
    case 4: /* Indirect predecrememnt.  */
451
 
        reg += QREG_A0;
452
 
        tmp = gen_new_qreg(QMODE_I32);
453
 
        gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
 
522
        reg = AREG(insn, 0);
 
523
        tmp = tcg_temp_new();
 
524
        tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
454
525
        return tmp;
455
526
    case 5: /* Indirect displacement.  */
456
 
        reg += QREG_A0;
457
 
        tmp = gen_new_qreg(QMODE_I32);
 
527
        reg = AREG(insn, 0);
 
528
        tmp = tcg_temp_new();
458
529
        ext = lduw_code(s->pc);
459
530
        s->pc += 2;
460
 
        gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
 
531
        tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
461
532
        return tmp;
462
533
    case 6: /* Indirect index + displacement.  */
463
 
        reg += QREG_A0;
 
534
        reg = AREG(insn, 0);
464
535
        return gen_lea_indexed(s, opsize, reg);
465
536
    case 7: /* Other */
466
 
        switch (reg) {
 
537
        switch (insn & 7) {
467
538
        case 0: /* Absolute short.  */
468
539
            offset = ldsw_code(s->pc);
469
540
            s->pc += 2;
472
543
            offset = read_im32(s);
473
544
            return gen_im32(offset);
474
545
        case 2: /* pc displacement  */
475
 
            tmp = gen_new_qreg(QMODE_I32);
 
546
            tmp = tcg_temp_new();
476
547
            offset = s->pc;
477
548
            offset += ldsw_code(s->pc);
478
549
            s->pc += 2;
479
550
            return gen_im32(offset);
480
551
        case 3: /* pc index+displacement.  */
481
 
            return gen_lea_indexed(s, opsize, -1);
 
552
            return gen_lea_indexed(s, opsize, NULL_QREG);
482
553
        case 4: /* Immediate.  */
483
554
        default:
484
 
            return -1;
 
555
            return NULL_QREG;
485
556
        }
486
557
    }
487
558
    /* Should never happen.  */
488
 
    return -1;
 
559
    return NULL_QREG;
489
560
}
490
561
 
491
562
/* Helper function for gen_ea. Reuse the computed address between the
492
563
   for read/write operands.  */
493
 
static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
494
 
                              int val, int *addrp)
 
564
static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
 
565
                              TCGv val, TCGv *addrp, ea_what what)
495
566
{
496
 
    int tmp;
 
567
    TCGv tmp;
497
568
 
498
 
    if (addrp && val > 0) {
 
569
    if (addrp && what == EA_STORE) {
499
570
        tmp = *addrp;
500
571
    } else {
501
572
        tmp = gen_lea(s, insn, opsize);
502
 
        if (tmp == -1)
503
 
            return -1;
 
573
        if (IS_NULL_QREG(tmp))
 
574
            return tmp;
504
575
        if (addrp)
505
576
            *addrp = tmp;
506
577
    }
507
 
    return gen_ldst(s, opsize, tmp, val);
 
578
    return gen_ldst(s, opsize, tmp, val, what);
508
579
}
509
580
 
510
581
/* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
511
582
   a write otherwise it is a read (0 == sign extend, -1 == zero extend).
512
583
   ADDRP is non-null for readwrite operands.  */
513
 
static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
514
 
                  int *addrp)
 
584
static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
 
585
                   TCGv *addrp, ea_what what)
515
586
{
516
 
    int reg;
517
 
    int result;
 
587
    TCGv reg;
 
588
    TCGv result;
518
589
    uint32_t offset;
519
590
 
520
 
    reg = insn & 7;
521
591
    switch ((insn >> 3) & 7) {
522
592
    case 0: /* Data register direct.  */
523
 
        reg += QREG_D0;
524
 
        if (val > 0) {
 
593
        reg = DREG(insn, 0);
 
594
        if (what == EA_STORE) {
525
595
            gen_partset_reg(opsize, reg, val);
526
 
            return 0;
 
596
            return store_dummy;
527
597
        } else {
528
 
            return gen_extend(reg, opsize, val);
 
598
            return gen_extend(reg, opsize, what == EA_LOADS);
529
599
        }
530
600
    case 1: /* Address register direct.  */
531
 
        reg += QREG_A0;
532
 
        if (val > 0) {
533
 
            gen_op_mov32(reg, val);
534
 
            return 0;
 
601
        reg = AREG(insn, 0);
 
602
        if (what == EA_STORE) {
 
603
            tcg_gen_mov_i32(reg, val);
 
604
            return store_dummy;
535
605
        } else {
536
 
            return gen_extend(reg, opsize, val);
 
606
            return gen_extend(reg, opsize, what == EA_LOADS);
537
607
        }
538
608
    case 2: /* Indirect register */
539
 
        reg += QREG_A0;
540
 
        return gen_ldst(s, opsize, reg, val);
 
609
        reg = AREG(insn, 0);
 
610
        return gen_ldst(s, opsize, reg, val, what);
541
611
    case 3: /* Indirect postincrement.  */
542
 
        reg += QREG_A0;
543
 
        result = gen_ldst(s, opsize, reg, val);
 
612
        reg = AREG(insn, 0);
 
613
        result = gen_ldst(s, opsize, reg, val, what);
544
614
        /* ??? This is not exception safe.  The instruction may still
545
615
           fault after this point.  */
546
 
        if (val > 0 || !addrp)
547
 
            gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
 
616
        if (what == EA_STORE || !addrp)
 
617
            tcg_gen_addi_i32(reg, reg, opsize_bytes(opsize));
548
618
        return result;
549
619
    case 4: /* Indirect predecrememnt.  */
550
620
        {
551
 
            int tmp;
552
 
            if (addrp && val > 0) {
 
621
            TCGv tmp;
 
622
            if (addrp && what == EA_STORE) {
553
623
                tmp = *addrp;
554
624
            } else {
555
625
                tmp = gen_lea(s, insn, opsize);
556
 
                if (tmp == -1)
557
 
                    return -1;
 
626
                if (IS_NULL_QREG(tmp))
 
627
                    return tmp;
558
628
                if (addrp)
559
629
                    *addrp = tmp;
560
630
            }
561
 
            result = gen_ldst(s, opsize, tmp, val);
 
631
            result = gen_ldst(s, opsize, tmp, val, what);
562
632
            /* ??? This is not exception safe.  The instruction may still
563
633
               fault after this point.  */
564
 
            if (val > 0 || !addrp) {
565
 
                reg += QREG_A0;
566
 
                gen_op_mov32(reg, tmp);
 
634
            if (what == EA_STORE || !addrp) {
 
635
                reg = AREG(insn, 0);
 
636
                tcg_gen_mov_i32(reg, tmp);
567
637
            }
568
638
        }
569
639
        return result;
570
640
    case 5: /* Indirect displacement.  */
571
641
    case 6: /* Indirect index + displacement.  */
572
 
        return gen_ea_once(s, insn, opsize, val, addrp);
 
642
        return gen_ea_once(s, insn, opsize, val, addrp, what);
573
643
    case 7: /* Other */
574
 
        switch (reg) {
 
644
        switch (insn & 7) {
575
645
        case 0: /* Absolute short.  */
576
646
        case 1: /* Absolute long.  */
577
647
        case 2: /* pc displacement  */
578
648
        case 3: /* pc index+displacement.  */
579
 
            return gen_ea_once(s, insn, opsize, val, addrp);
 
649
            return gen_ea_once(s, insn, opsize, val, addrp, what);
580
650
        case 4: /* Immediate.  */
581
651
            /* Sign extend values for consistency.  */
582
652
            switch (opsize) {
583
653
            case OS_BYTE:
584
 
                if (val)
 
654
                if (what == EA_LOADS)
585
655
                    offset = ldsb_code(s->pc + 1);
586
656
                else
587
657
                    offset = ldub_code(s->pc + 1);
588
658
                s->pc += 2;
589
659
                break;
590
660
            case OS_WORD:
591
 
                if (val)
 
661
                if (what == EA_LOADS)
592
662
                    offset = ldsw_code(s->pc);
593
663
                else
594
664
                    offset = lduw_code(s->pc);
600
670
            default:
601
671
                qemu_assert(0, "Bad immediate operand");
602
672
            }
603
 
            return gen_im32(offset);
 
673
            return tcg_const_i32(offset);
604
674
        default:
605
 
            return -1;
 
675
            return NULL_QREG;
606
676
        }
607
677
    }
608
678
    /* Should never happen.  */
609
 
    return -1;
610
 
}
611
 
 
612
 
static void gen_logic_cc(DisasContext *s, int val)
613
 
{
614
 
    gen_op_logic_cc(val);
615
 
    s->cc_op = CC_OP_LOGIC;
616
 
}
617
 
 
 
679
    return NULL_QREG;
 
680
}
 
681
 
 
682
/* This generates a conditional branch, clobbering all temporaries.  */
618
683
static void gen_jmpcc(DisasContext *s, int cond, int l1)
619
684
{
620
 
    int tmp;
 
685
    TCGv tmp;
621
686
 
 
687
    /* TODO: Optimize compare/branch pairs rather than always flushing
 
688
       flag state to CC_OP_FLAGS.  */
622
689
    gen_flush_flags(s);
623
690
    switch (cond) {
624
691
    case 0: /* T */
625
 
        gen_op_jmp(l1);
 
692
        tcg_gen_br(l1);
626
693
        break;
627
694
    case 1: /* F */
628
695
        break;
629
696
    case 2: /* HI (!C && !Z) */
630
 
        tmp = gen_new_qreg(QMODE_I32);
631
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
632
 
        gen_op_jmp_z32(tmp, l1);
 
697
        tmp = tcg_temp_new();
 
698
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
 
699
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
633
700
        break;
634
701
    case 3: /* LS (C || Z) */
635
 
        tmp = gen_new_qreg(QMODE_I32);
636
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
637
 
        gen_op_jmp_nz32(tmp, l1);
 
702
        tmp = tcg_temp_new();
 
703
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
 
704
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
638
705
        break;
639
706
    case 4: /* CC (!C) */
640
 
        tmp = gen_new_qreg(QMODE_I32);
641
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
642
 
        gen_op_jmp_z32(tmp, l1);
 
707
        tmp = tcg_temp_new();
 
708
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
 
709
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
643
710
        break;
644
711
    case 5: /* CS (C) */
645
 
        tmp = gen_new_qreg(QMODE_I32);
646
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
647
 
        gen_op_jmp_nz32(tmp, l1);
 
712
        tmp = tcg_temp_new();
 
713
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
 
714
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
648
715
        break;
649
716
    case 6: /* NE (!Z) */
650
 
        tmp = gen_new_qreg(QMODE_I32);
651
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
652
 
        gen_op_jmp_z32(tmp, l1);
 
717
        tmp = tcg_temp_new();
 
718
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
 
719
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
653
720
        break;
654
721
    case 7: /* EQ (Z) */
655
 
        tmp = gen_new_qreg(QMODE_I32);
656
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
657
 
        gen_op_jmp_nz32(tmp, l1);
 
722
        tmp = tcg_temp_new();
 
723
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
 
724
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
658
725
        break;
659
726
    case 8: /* VC (!V) */
660
 
        tmp = gen_new_qreg(QMODE_I32);
661
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
662
 
        gen_op_jmp_z32(tmp, l1);
 
727
        tmp = tcg_temp_new();
 
728
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
 
729
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
663
730
        break;
664
731
    case 9: /* VS (V) */
665
 
        tmp = gen_new_qreg(QMODE_I32);
666
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
667
 
        gen_op_jmp_nz32(tmp, l1);
 
732
        tmp = tcg_temp_new();
 
733
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
 
734
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
668
735
        break;
669
736
    case 10: /* PL (!N) */
670
 
        tmp = gen_new_qreg(QMODE_I32);
671
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
672
 
        gen_op_jmp_z32(tmp, l1);
 
737
        tmp = tcg_temp_new();
 
738
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
 
739
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
673
740
        break;
674
741
    case 11: /* MI (N) */
675
 
        tmp = gen_new_qreg(QMODE_I32);
676
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
677
 
        gen_op_jmp_nz32(tmp, l1);
 
742
        tmp = tcg_temp_new();
 
743
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
 
744
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
678
745
        break;
679
746
    case 12: /* GE (!(N ^ V)) */
680
 
        tmp = gen_new_qreg(QMODE_I32);
681
 
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
682
 
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
683
 
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
684
 
        gen_op_jmp_z32(tmp, l1);
 
747
        tmp = tcg_temp_new();
 
748
        assert(CCF_V == (CCF_N >> 2));
 
749
        tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
 
750
        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
 
751
        tcg_gen_andi_i32(tmp, tmp, CCF_V);
 
752
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
685
753
        break;
686
754
    case 13: /* LT (N ^ V) */
687
 
        tmp = gen_new_qreg(QMODE_I32);
688
 
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
689
 
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
690
 
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
691
 
        gen_op_jmp_nz32(tmp, l1);
 
755
        tmp = tcg_temp_new();
 
756
        assert(CCF_V == (CCF_N >> 2));
 
757
        tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
 
758
        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
 
759
        tcg_gen_andi_i32(tmp, tmp, CCF_V);
 
760
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
692
761
        break;
693
762
    case 14: /* GT (!(Z || (N ^ V))) */
694
 
        {
695
 
            int l2;
696
 
            l2 = gen_new_label();
697
 
            tmp = gen_new_qreg(QMODE_I32);
698
 
            gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
699
 
            gen_op_jmp_nz32(tmp, l2);
700
 
            tmp = gen_new_qreg(QMODE_I32);
701
 
            gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
702
 
            gen_op_xor32(tmp, tmp, QREG_CC_DEST);
703
 
            gen_op_and32(tmp, tmp, gen_im32(CCF_V));
704
 
            gen_op_jmp_nz32(tmp, l2);
705
 
            gen_op_jmp(l1);
706
 
            gen_set_label(l2);
707
 
        }
 
763
        tmp = tcg_temp_new();
 
764
        assert(CCF_V == (CCF_N >> 2));
 
765
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
 
766
        tcg_gen_shri_i32(tmp, tmp, 2);
 
767
        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
 
768
        tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);
 
769
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
708
770
        break;
709
771
    case 15: /* LE (Z || (N ^ V)) */
710
 
        tmp = gen_new_qreg(QMODE_I32);
711
 
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
712
 
        gen_op_jmp_nz32(tmp, l1);
713
 
        tmp = gen_new_qreg(QMODE_I32);
714
 
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
715
 
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
716
 
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
717
 
        gen_op_jmp_nz32(tmp, l1);
 
772
        tmp = tcg_temp_new();
 
773
        assert(CCF_V == (CCF_N >> 2));
 
774
        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
 
775
        tcg_gen_shri_i32(tmp, tmp, 2);
 
776
        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
 
777
        tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);
 
778
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
718
779
        break;
719
780
    default:
720
781
        /* Should ever happen.  */
726
787
{
727
788
    int l1;
728
789
    int cond;
729
 
    int reg;
 
790
    TCGv reg;
730
791
 
731
792
    l1 = gen_new_label();
732
793
    cond = (insn >> 8) & 0xf;
733
794
    reg = DREG(insn, 0);
734
 
    gen_op_and32(reg, reg, gen_im32(0xffffff00));
 
795
    tcg_gen_andi_i32(reg, reg, 0xffffff00);
 
796
    /* This is safe because we modify the reg directly, with no other values
 
797
       live.  */
735
798
    gen_jmpcc(s, cond ^ 1, l1);
736
 
    gen_op_or32(reg, reg, gen_im32(0xff));
 
799
    tcg_gen_ori_i32(reg, reg, 0xff);
737
800
    gen_set_label(l1);
738
801
}
739
802
 
741
804
static void gen_lookup_tb(DisasContext *s)
742
805
{
743
806
    gen_flush_cc_op(s);
744
 
    gen_op_mov32(QREG_PC, gen_im32(s->pc));
 
807
    tcg_gen_movi_i32(QREG_PC, s->pc);
745
808
    s->is_jmp = DISAS_UPDATE;
746
809
}
747
810
 
748
 
/* Generate a jump to to the address in qreg DEST.  */
749
 
static void gen_jmp(DisasContext *s, int dest)
750
 
{
751
 
    gen_flush_cc_op(s);
752
 
    gen_op_mov32(QREG_PC, dest);
 
811
/* Generate a jump to an immediate address.  */
 
812
static void gen_jmp_im(DisasContext *s, uint32_t dest)
 
813
{
 
814
    gen_flush_cc_op(s);
 
815
    tcg_gen_movi_i32(QREG_PC, dest);
 
816
    s->is_jmp = DISAS_JUMP;
 
817
}
 
818
 
 
819
/* Generate a jump to the address in qreg DEST.  */
 
820
static void gen_jmp(DisasContext *s, TCGv dest)
 
821
{
 
822
    gen_flush_cc_op(s);
 
823
    tcg_gen_mov_i32(QREG_PC, dest);
753
824
    s->is_jmp = DISAS_JUMP;
754
825
}
755
826
 
756
827
static void gen_exception(DisasContext *s, uint32_t where, int nr)
757
828
{
758
829
    gen_flush_cc_op(s);
759
 
    gen_jmp(s, gen_im32(where));
760
 
    gen_op_raise_exception(nr);
 
830
    gen_jmp_im(s, where);
 
831
    gen_helper_raise_exception(tcg_const_i32(nr));
761
832
}
762
833
 
763
834
static inline void gen_addr_fault(DisasContext *s)
765
836
    gen_exception(s, s->insn_pc, EXCP_ADDRESS);
766
837
}
767
838
 
768
 
#define SRC_EA(result, opsize, val, addrp) do { \
769
 
    result = gen_ea(s, insn, opsize, val, addrp); \
770
 
    if (result == -1) { \
 
839
#define SRC_EA(result, opsize, op_sign, addrp) do { \
 
840
    result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \
 
841
    if (IS_NULL_QREG(result)) { \
771
842
        gen_addr_fault(s); \
772
843
        return; \
773
844
    } \
774
845
    } while (0)
775
846
 
776
847
#define DEST_EA(insn, opsize, val, addrp) do { \
777
 
    int ea_result = gen_ea(s, insn, opsize, val, addrp); \
778
 
    if (ea_result == -1) { \
 
848
    TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \
 
849
    if (IS_NULL_QREG(ea_result)) { \
779
850
        gen_addr_fault(s); \
780
851
        return; \
781
852
    } \
787
858
    TranslationBlock *tb;
788
859
 
789
860
    tb = s->tb;
790
 
    if (__builtin_expect (s->singlestep_enabled, 0)) {
 
861
    if (unlikely(s->singlestep_enabled)) {
791
862
        gen_exception(s, dest, EXCP_DEBUG);
792
863
    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
793
864
               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
794
 
        gen_op_goto_tb(0, n, (long)tb);
795
 
        gen_op_mov32(QREG_PC, gen_im32(dest));
796
 
        gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
797
 
        gen_op_exit_tb();
 
865
        tcg_gen_goto_tb(n);
 
866
        tcg_gen_movi_i32(QREG_PC, dest);
 
867
        tcg_gen_exit_tb((long)tb + n);
798
868
    } else {
799
 
        gen_jmp(s, gen_im32(dest));
800
 
        gen_op_mov32(QREG_T0, gen_im32(0));
801
 
        gen_op_exit_tb();
 
869
        gen_jmp_im(s, dest);
 
870
        tcg_gen_exit_tb(0);
802
871
    }
803
872
    s->is_jmp = DISAS_TB_JUMP;
804
873
}
822
891
 
823
892
DISAS_INSN(mulw)
824
893
{
825
 
    int reg;
826
 
    int tmp;
827
 
    int src;
 
894
    TCGv reg;
 
895
    TCGv tmp;
 
896
    TCGv src;
828
897
    int sign;
829
898
 
830
899
    sign = (insn & 0x100) != 0;
831
900
    reg = DREG(insn, 9);
832
 
    tmp = gen_new_qreg(QMODE_I32);
 
901
    tmp = tcg_temp_new();
833
902
    if (sign)
834
 
        gen_op_ext16s32(tmp, reg);
 
903
        tcg_gen_ext16s_i32(tmp, reg);
835
904
    else
836
 
        gen_op_ext16u32(tmp, reg);
837
 
    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
838
 
    gen_op_mul32(tmp, tmp, src);
839
 
    gen_op_mov32(reg, tmp);
 
905
        tcg_gen_ext16u_i32(tmp, reg);
 
906
    SRC_EA(src, OS_WORD, sign, NULL);
 
907
    tcg_gen_mul_i32(tmp, tmp, src);
 
908
    tcg_gen_mov_i32(reg, tmp);
840
909
    /* Unlike m68k, coldfire always clears the overflow bit.  */
841
910
    gen_logic_cc(s, tmp);
842
911
}
843
912
 
844
913
DISAS_INSN(divw)
845
914
{
846
 
    int reg;
847
 
    int tmp;
848
 
    int src;
 
915
    TCGv reg;
 
916
    TCGv tmp;
 
917
    TCGv src;
849
918
    int sign;
850
919
 
851
920
    sign = (insn & 0x100) != 0;
852
921
    reg = DREG(insn, 9);
853
922
    if (sign) {
854
 
        gen_op_ext16s32(QREG_DIV1, reg);
 
923
        tcg_gen_ext16s_i32(QREG_DIV1, reg);
855
924
    } else {
856
 
        gen_op_ext16u32(QREG_DIV1, reg);
 
925
        tcg_gen_ext16u_i32(QREG_DIV1, reg);
857
926
    }
858
 
    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
859
 
    gen_op_mov32(QREG_DIV2, src);
 
927
    SRC_EA(src, OS_WORD, sign, NULL);
 
928
    tcg_gen_mov_i32(QREG_DIV2, src);
860
929
    if (sign) {
861
 
        gen_op_divs(1);
 
930
        gen_helper_divs(cpu_env, tcg_const_i32(1));
862
931
    } else {
863
 
        gen_op_divu(1);
 
932
        gen_helper_divu(cpu_env, tcg_const_i32(1));
864
933
    }
865
934
 
866
 
    tmp = gen_new_qreg(QMODE_I32);
867
 
    src = gen_new_qreg(QMODE_I32);
868
 
    gen_op_ext16u32(tmp, QREG_DIV1);
869
 
    gen_op_shl32(src, QREG_DIV2, gen_im32(16));
870
 
    gen_op_or32(reg, tmp, src);
871
 
    gen_op_flags_set();
 
935
    tmp = tcg_temp_new();
 
936
    src = tcg_temp_new();
 
937
    tcg_gen_ext16u_i32(tmp, QREG_DIV1);
 
938
    tcg_gen_shli_i32(src, QREG_DIV2, 16);
 
939
    tcg_gen_or_i32(reg, tmp, src);
872
940
    s->cc_op = CC_OP_FLAGS;
873
941
}
874
942
 
875
943
DISAS_INSN(divl)
876
944
{
877
 
    int num;
878
 
    int den;
879
 
    int reg;
 
945
    TCGv num;
 
946
    TCGv den;
 
947
    TCGv reg;
880
948
    uint16_t ext;
881
949
 
882
950
    ext = lduw_code(s->pc);
887
955
    }
888
956
    num = DREG(ext, 12);
889
957
    reg = DREG(ext, 0);
890
 
    gen_op_mov32(QREG_DIV1, num);
 
958
    tcg_gen_mov_i32(QREG_DIV1, num);
891
959
    SRC_EA(den, OS_LONG, 0, NULL);
892
 
    gen_op_mov32(QREG_DIV2, den);
 
960
    tcg_gen_mov_i32(QREG_DIV2, den);
893
961
    if (ext & 0x0800) {
894
 
        gen_op_divs(2);
 
962
        gen_helper_divs(cpu_env, tcg_const_i32(0));
895
963
    } else {
896
 
        gen_op_divu(2);
 
964
        gen_helper_divu(cpu_env, tcg_const_i32(0));
897
965
    }
898
 
    if (num == reg) {
 
966
    if ((ext & 7) == ((ext >> 12) & 7)) {
899
967
        /* div */
900
 
        gen_op_mov32 (reg, QREG_DIV1);
 
968
        tcg_gen_mov_i32 (reg, QREG_DIV1);
901
969
    } else {
902
970
        /* rem */
903
 
        gen_op_mov32 (reg, QREG_DIV2);
 
971
        tcg_gen_mov_i32 (reg, QREG_DIV2);
904
972
    }
905
 
    gen_op_flags_set();
906
973
    s->cc_op = CC_OP_FLAGS;
907
974
}
908
975
 
909
976
DISAS_INSN(addsub)
910
977
{
911
 
    int reg;
912
 
    int dest;
913
 
    int src;
914
 
    int tmp;
915
 
    int addr;
 
978
    TCGv reg;
 
979
    TCGv dest;
 
980
    TCGv src;
 
981
    TCGv tmp;
 
982
    TCGv addr;
916
983
    int add;
917
984
 
918
985
    add = (insn & 0x4000) != 0;
919
986
    reg = DREG(insn, 9);
920
 
    dest = gen_new_qreg(QMODE_I32);
 
987
    dest = tcg_temp_new();
921
988
    if (insn & 0x100) {
922
989
        SRC_EA(tmp, OS_LONG, 0, &addr);
923
990
        src = reg;
926
993
        SRC_EA(src, OS_LONG, 0, NULL);
927
994
    }
928
995
    if (add) {
929
 
        gen_op_add32(dest, tmp, src);
930
 
        gen_op_update_xflag_lt(dest, src);
 
996
        tcg_gen_add_i32(dest, tmp, src);
 
997
        gen_helper_xflag_lt(QREG_CC_X, dest, src);
931
998
        s->cc_op = CC_OP_ADD;
932
999
    } else {
933
 
        gen_op_update_xflag_lt(tmp, src);
934
 
        gen_op_sub32(dest, tmp, src);
 
1000
        gen_helper_xflag_lt(QREG_CC_X, tmp, src);
 
1001
        tcg_gen_sub_i32(dest, tmp, src);
935
1002
        s->cc_op = CC_OP_SUB;
936
1003
    }
937
 
    gen_op_update_cc_add(dest, src);
 
1004
    gen_update_cc_add(dest, src);
938
1005
    if (insn & 0x100) {
939
1006
        DEST_EA(insn, OS_LONG, dest, &addr);
940
1007
    } else {
941
 
        gen_op_mov32(reg, dest);
 
1008
        tcg_gen_mov_i32(reg, dest);
942
1009
    }
943
1010
}
944
1011
 
946
1013
/* Reverse the order of the bits in REG.  */
947
1014
DISAS_INSN(bitrev)
948
1015
{
949
 
    int val;
950
 
    int tmp1;
951
 
    int tmp2;
952
 
    int reg;
953
 
 
954
 
    val = gen_new_qreg(QMODE_I32);
955
 
    tmp1 = gen_new_qreg(QMODE_I32);
956
 
    tmp2 = gen_new_qreg(QMODE_I32);
 
1016
    TCGv reg;
957
1017
    reg = DREG(insn, 0);
958
 
    gen_op_mov32(val, reg);
959
 
    /* Reverse bits within each nibble.  */
960
 
    gen_op_shl32(tmp1, val, gen_im32(3));
961
 
    gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
962
 
    gen_op_shl32(tmp2, val, gen_im32(1));
963
 
    gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
964
 
    gen_op_or32(tmp1, tmp1, tmp2);
965
 
    gen_op_shr32(tmp2, val, gen_im32(1));
966
 
    gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
967
 
    gen_op_or32(tmp1, tmp1, tmp2);
968
 
    gen_op_shr32(tmp2, val, gen_im32(3));
969
 
    gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
970
 
    gen_op_or32(tmp1, tmp1, tmp2);
971
 
    /* Reverse nibbles withing bytes.  */
972
 
    gen_op_shl32(val, tmp1, gen_im32(4));
973
 
    gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
974
 
    gen_op_shr32(tmp2, tmp1, gen_im32(4));
975
 
    gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
976
 
    gen_op_or32(val, val, tmp2);
977
 
    /* Reverse bytes.  */
978
 
    gen_op_bswap32(reg, val);
979
 
    gen_op_mov32(reg, val);
 
1018
    gen_helper_bitrev(reg, reg);
980
1019
}
981
1020
 
982
1021
DISAS_INSN(bitop_reg)
983
1022
{
984
1023
    int opsize;
985
1024
    int op;
986
 
    int src1;
987
 
    int src2;
988
 
    int tmp;
989
 
    int addr;
990
 
    int dest;
 
1025
    TCGv src1;
 
1026
    TCGv src2;
 
1027
    TCGv tmp;
 
1028
    TCGv addr;
 
1029
    TCGv dest;
991
1030
 
992
1031
    if ((insn & 0x38) != 0)
993
1032
        opsize = OS_BYTE;
996
1035
    op = (insn >> 6) & 3;
997
1036
    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
998
1037
    src2 = DREG(insn, 9);
999
 
    dest = gen_new_qreg(QMODE_I32);
 
1038
    dest = tcg_temp_new();
1000
1039
 
1001
1040
    gen_flush_flags(s);
1002
 
    tmp = gen_new_qreg(QMODE_I32);
 
1041
    tmp = tcg_temp_new();
1003
1042
    if (opsize == OS_BYTE)
1004
 
        gen_op_and32(tmp, src2, gen_im32(7));
 
1043
        tcg_gen_andi_i32(tmp, src2, 7);
1005
1044
    else
1006
 
        gen_op_and32(tmp, src2, gen_im32(31));
 
1045
        tcg_gen_andi_i32(tmp, src2, 31);
1007
1046
    src2 = tmp;
1008
 
    tmp = gen_new_qreg(QMODE_I32);
1009
 
    gen_op_shl32(tmp, gen_im32(1), src2);
 
1047
    tmp = tcg_temp_new();
 
1048
    tcg_gen_shr_i32(tmp, src1, src2);
 
1049
    tcg_gen_andi_i32(tmp, tmp, 1);
 
1050
    tcg_gen_shli_i32(tmp, tmp, 2);
 
1051
    /* Clear CCF_Z if bit set.  */
 
1052
    tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
 
1053
    tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1010
1054
 
1011
 
    gen_op_btest(src1, tmp);
 
1055
    tcg_gen_shl_i32(tmp, tcg_const_i32(1), src2);
1012
1056
    switch (op) {
1013
1057
    case 1: /* bchg */
1014
 
        gen_op_xor32(dest, src1, tmp);
 
1058
        tcg_gen_xor_i32(dest, src1, tmp);
1015
1059
        break;
1016
1060
    case 2: /* bclr */
1017
 
        gen_op_not32(tmp, tmp);
1018
 
        gen_op_and32(dest, src1, tmp);
 
1061
        tcg_gen_not_i32(tmp, tmp);
 
1062
        tcg_gen_and_i32(dest, src1, tmp);
1019
1063
        break;
1020
1064
    case 3: /* bset */
1021
 
        gen_op_or32(dest, src1, tmp);
 
1065
        tcg_gen_or_i32(dest, src1, tmp);
1022
1066
        break;
1023
1067
    default: /* btst */
1024
1068
        break;
1029
1073
 
1030
1074
DISAS_INSN(sats)
1031
1075
{
1032
 
    int reg;
1033
 
    int tmp;
1034
 
    int l1;
1035
 
 
 
1076
    TCGv reg;
1036
1077
    reg = DREG(insn, 0);
1037
 
    tmp = gen_new_qreg(QMODE_I32);
1038
1078
    gen_flush_flags(s);
1039
 
    gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
1040
 
    l1 = gen_new_label();
1041
 
    gen_op_jmp_z32(tmp, l1);
1042
 
    tmp = gen_new_qreg(QMODE_I32);
1043
 
    gen_op_shr32(tmp, reg, gen_im32(31));
1044
 
    gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
1045
 
    gen_op_mov32(reg, tmp);
1046
 
    gen_set_label(l1);
1047
 
    gen_logic_cc(s, tmp);
 
1079
    gen_helper_sats(reg, reg, QREG_CC_DEST);
 
1080
    gen_logic_cc(s, reg);
1048
1081
}
1049
1082
 
1050
 
static void gen_push(DisasContext *s, int val)
 
1083
static void gen_push(DisasContext *s, TCGv val)
1051
1084
{
1052
 
    int tmp;
 
1085
    TCGv tmp;
1053
1086
 
1054
 
    tmp = gen_new_qreg(QMODE_I32);
1055
 
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
 
1087
    tmp = tcg_temp_new();
 
1088
    tcg_gen_subi_i32(tmp, QREG_SP, 4);
1056
1089
    gen_store(s, OS_LONG, tmp, val);
1057
 
    gen_op_mov32(QREG_SP, tmp);
 
1090
    tcg_gen_mov_i32(QREG_SP, tmp);
1058
1091
}
1059
1092
 
1060
1093
DISAS_INSN(movem)
1061
1094
{
1062
 
    int addr;
 
1095
    TCGv addr;
1063
1096
    int i;
1064
1097
    uint16_t mask;
1065
 
    int reg;
1066
 
    int tmp;
 
1098
    TCGv reg;
 
1099
    TCGv tmp;
1067
1100
    int is_load;
1068
1101
 
1069
1102
    mask = lduw_code(s->pc);
1070
1103
    s->pc += 2;
1071
1104
    tmp = gen_lea(s, insn, OS_LONG);
1072
 
    if (tmp == -1) {
 
1105
    if (IS_NULL_QREG(tmp)) {
1073
1106
        gen_addr_fault(s);
1074
1107
        return;
1075
1108
    }
1076
 
    addr = gen_new_qreg(QMODE_I32);
1077
 
    gen_op_mov32(addr, tmp);
 
1109
    addr = tcg_temp_new();
 
1110
    tcg_gen_mov_i32(addr, tmp);
1078
1111
    is_load = ((insn & 0x0400) != 0);
1079
1112
    for (i = 0; i < 16; i++, mask >>= 1) {
1080
1113
        if (mask & 1) {
1084
1117
                reg = AREG(i, 0);
1085
1118
            if (is_load) {
1086
1119
                tmp = gen_load(s, OS_LONG, addr, 0);
1087
 
                gen_op_mov32(reg, tmp);
 
1120
                tcg_gen_mov_i32(reg, tmp);
1088
1121
            } else {
1089
1122
                gen_store(s, OS_LONG, addr, reg);
1090
1123
            }
1091
1124
            if (mask != 1)
1092
 
                gen_op_add32(addr, addr, gen_im32(4));
 
1125
                tcg_gen_addi_i32(addr, addr, 4);
1093
1126
        }
1094
1127
    }
1095
1128
}
1098
1131
{
1099
1132
    int opsize;
1100
1133
    int op;
1101
 
    int src1;
 
1134
    TCGv src1;
1102
1135
    uint32_t mask;
1103
1136
    int bitnum;
1104
 
    int tmp;
1105
 
    int addr;
1106
 
    int dest;
 
1137
    TCGv tmp;
 
1138
    TCGv addr;
1107
1139
 
1108
1140
    if ((insn & 0x38) != 0)
1109
1141
        opsize = OS_BYTE;
1121
1153
    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
1122
1154
 
1123
1155
    gen_flush_flags(s);
1124
 
    tmp = gen_new_qreg(QMODE_I32);
1125
1156
    if (opsize == OS_BYTE)
1126
1157
        bitnum &= 7;
1127
1158
    else
1128
1159
        bitnum &= 31;
1129
1160
    mask = 1 << bitnum;
1130
1161
 
1131
 
    gen_op_btest(src1, gen_im32(mask));
1132
 
    if (op)
1133
 
        dest = gen_new_qreg(QMODE_I32);
 
1162
    tmp = tcg_temp_new();
 
1163
    assert (CCF_Z == (1 << 2));
 
1164
    if (bitnum > 2)
 
1165
        tcg_gen_shri_i32(tmp, src1, bitnum - 2);
 
1166
    else if (bitnum < 2)
 
1167
        tcg_gen_shli_i32(tmp, src1, 2 - bitnum);
1134
1168
    else
1135
 
        dest = -1;
1136
 
 
1137
 
    switch (op) {
1138
 
    case 1: /* bchg */
1139
 
        gen_op_xor32(dest, src1, gen_im32(mask));
1140
 
        break;
1141
 
    case 2: /* bclr */
1142
 
        gen_op_and32(dest, src1, gen_im32(~mask));
1143
 
        break;
1144
 
    case 3: /* bset */
1145
 
        gen_op_or32(dest, src1, gen_im32(mask));
1146
 
        break;
1147
 
    default: /* btst */
1148
 
        break;
 
1169
        tcg_gen_mov_i32(tmp, src1);
 
1170
    tcg_gen_andi_i32(tmp, tmp, CCF_Z);
 
1171
    /* Clear CCF_Z if bit set.  */
 
1172
    tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
 
1173
    tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
 
1174
    if (op) {
 
1175
        switch (op) {
 
1176
        case 1: /* bchg */
 
1177
            tcg_gen_xori_i32(tmp, src1, mask);
 
1178
            break;
 
1179
        case 2: /* bclr */
 
1180
            tcg_gen_andi_i32(tmp, src1, ~mask);
 
1181
            break;
 
1182
        case 3: /* bset */
 
1183
            tcg_gen_ori_i32(tmp, src1, mask);
 
1184
            break;
 
1185
        default: /* btst */
 
1186
            break;
 
1187
        }
 
1188
        DEST_EA(insn, opsize, tmp, &addr);
1149
1189
    }
1150
 
    if (op)
1151
 
        DEST_EA(insn, opsize, dest, &addr);
1152
1190
}
1153
1191
 
1154
1192
DISAS_INSN(arith_im)
1155
1193
{
1156
1194
    int op;
1157
 
    int src1;
1158
 
    int dest;
1159
 
    int src2;
1160
 
    int addr;
 
1195
    uint32_t im;
 
1196
    TCGv src1;
 
1197
    TCGv dest;
 
1198
    TCGv addr;
1161
1199
 
1162
1200
    op = (insn >> 9) & 7;
1163
1201
    SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1164
 
    src2 = gen_im32(read_im32(s));
1165
 
    dest = gen_new_qreg(QMODE_I32);
 
1202
    im = read_im32(s);
 
1203
    dest = tcg_temp_new();
1166
1204
    switch (op) {
1167
1205
    case 0: /* ori */
1168
 
        gen_op_or32(dest, src1, src2);
 
1206
        tcg_gen_ori_i32(dest, src1, im);
1169
1207
        gen_logic_cc(s, dest);
1170
1208
        break;
1171
1209
    case 1: /* andi */
1172
 
        gen_op_and32(dest, src1, src2);
 
1210
        tcg_gen_andi_i32(dest, src1, im);
1173
1211
        gen_logic_cc(s, dest);
1174
1212
        break;
1175
1213
    case 2: /* subi */
1176
 
        gen_op_mov32(dest, src1);
1177
 
        gen_op_update_xflag_lt(dest, src2);
1178
 
        gen_op_sub32(dest, dest, src2);
1179
 
        gen_op_update_cc_add(dest, src2);
 
1214
        tcg_gen_mov_i32(dest, src1);
 
1215
        gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
 
1216
        tcg_gen_subi_i32(dest, dest, im);
 
1217
        gen_update_cc_add(dest, gen_im32(im));
1180
1218
        s->cc_op = CC_OP_SUB;
1181
1219
        break;
1182
1220
    case 3: /* addi */
1183
 
        gen_op_mov32(dest, src1);
1184
 
        gen_op_add32(dest, dest, src2);
1185
 
        gen_op_update_cc_add(dest, src2);
1186
 
        gen_op_update_xflag_lt(dest, src2);
 
1221
        tcg_gen_mov_i32(dest, src1);
 
1222
        tcg_gen_addi_i32(dest, dest, im);
 
1223
        gen_update_cc_add(dest, gen_im32(im));
 
1224
        gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
1187
1225
        s->cc_op = CC_OP_ADD;
1188
1226
        break;
1189
1227
    case 5: /* eori */
1190
 
        gen_op_xor32(dest, src1, src2);
 
1228
        tcg_gen_xori_i32(dest, src1, im);
1191
1229
        gen_logic_cc(s, dest);
1192
1230
        break;
1193
1231
    case 6: /* cmpi */
1194
 
        gen_op_mov32(dest, src1);
1195
 
        gen_op_sub32(dest, dest, src2);
1196
 
        gen_op_update_cc_add(dest, src2);
 
1232
        tcg_gen_mov_i32(dest, src1);
 
1233
        tcg_gen_subi_i32(dest, dest, im);
 
1234
        gen_update_cc_add(dest, gen_im32(im));
1197
1235
        s->cc_op = CC_OP_SUB;
1198
1236
        break;
1199
1237
    default:
1206
1244
 
1207
1245
DISAS_INSN(byterev)
1208
1246
{
1209
 
    int reg;
 
1247
    TCGv reg;
1210
1248
 
1211
1249
    reg = DREG(insn, 0);
1212
 
    gen_op_bswap32(reg, reg);
 
1250
    tcg_gen_bswap_i32(reg, reg);
1213
1251
}
1214
1252
 
1215
1253
DISAS_INSN(move)
1216
1254
{
1217
 
    int src;
1218
 
    int dest;
 
1255
    TCGv src;
 
1256
    TCGv dest;
1219
1257
    int op;
1220
1258
    int opsize;
1221
1259
 
1232
1270
    default:
1233
1271
        abort();
1234
1272
    }
1235
 
    SRC_EA(src, opsize, -1, NULL);
 
1273
    SRC_EA(src, opsize, 1, NULL);
1236
1274
    op = (insn >> 6) & 7;
1237
1275
    if (op == 1) {
1238
1276
        /* movea */
1239
1277
        /* The value will already have been sign extended.  */
1240
1278
        dest = AREG(insn, 9);
1241
 
        gen_op_mov32(dest, src);
 
1279
        tcg_gen_mov_i32(dest, src);
1242
1280
    } else {
1243
1281
        /* normal move */
1244
1282
        uint16_t dest_ea;
1251
1289
 
1252
1290
DISAS_INSN(negx)
1253
1291
{
1254
 
    int reg;
1255
 
    int dest;
1256
 
    int tmp;
 
1292
    TCGv reg;
1257
1293
 
1258
1294
    gen_flush_flags(s);
1259
1295
    reg = DREG(insn, 0);
1260
 
    dest = gen_new_qreg(QMODE_I32);
1261
 
    gen_op_mov32 (dest, gen_im32(0));
1262
 
    gen_op_subx_cc(dest, reg);
1263
 
    /* !Z is sticky.  */
1264
 
    tmp = gen_new_qreg(QMODE_I32);
1265
 
    gen_op_mov32 (tmp, QREG_CC_DEST);
1266
 
    gen_op_update_cc_add(dest, reg);
1267
 
    gen_op_mov32(reg, dest);
1268
 
    s->cc_op = CC_OP_DYNAMIC;
1269
 
    gen_flush_flags(s);
1270
 
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1271
 
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1272
 
    s->cc_op = CC_OP_FLAGS;
 
1296
    gen_helper_subx_cc(reg, cpu_env, tcg_const_i32(0), reg);
1273
1297
}
1274
1298
 
1275
1299
DISAS_INSN(lea)
1276
1300
{
1277
 
    int reg;
1278
 
    int tmp;
 
1301
    TCGv reg;
 
1302
    TCGv tmp;
1279
1303
 
1280
1304
    reg = AREG(insn, 9);
1281
1305
    tmp = gen_lea(s, insn, OS_LONG);
1282
 
    if (tmp == -1) {
 
1306
    if (IS_NULL_QREG(tmp)) {
1283
1307
        gen_addr_fault(s);
1284
1308
        return;
1285
1309
    }
1286
 
    gen_op_mov32(reg, tmp);
 
1310
    tcg_gen_mov_i32(reg, tmp);
1287
1311
}
1288
1312
 
1289
1313
DISAS_INSN(clr)
1307
1331
    gen_logic_cc(s, gen_im32(0));
1308
1332
}
1309
1333
 
1310
 
static int gen_get_ccr(DisasContext *s)
 
1334
static TCGv gen_get_ccr(DisasContext *s)
1311
1335
{
1312
 
    int dest;
 
1336
    TCGv dest;
1313
1337
 
1314
1338
    gen_flush_flags(s);
1315
 
    dest = gen_new_qreg(QMODE_I32);
1316
 
    gen_op_get_xflag(dest);
1317
 
    gen_op_shl32(dest, dest, gen_im32(4));
1318
 
    gen_op_or32(dest, dest, QREG_CC_DEST);
 
1339
    dest = tcg_temp_new();
 
1340
    tcg_gen_shli_i32(dest, QREG_CC_X, 4);
 
1341
    tcg_gen_or_i32(dest, dest, QREG_CC_DEST);
1319
1342
    return dest;
1320
1343
}
1321
1344
 
1322
1345
DISAS_INSN(move_from_ccr)
1323
1346
{
1324
 
    int reg;
1325
 
    int ccr;
 
1347
    TCGv reg;
 
1348
    TCGv ccr;
1326
1349
 
1327
1350
    ccr = gen_get_ccr(s);
1328
1351
    reg = DREG(insn, 0);
1331
1354
 
1332
1355
DISAS_INSN(neg)
1333
1356
{
1334
 
    int reg;
1335
 
    int src1;
 
1357
    TCGv reg;
 
1358
    TCGv src1;
1336
1359
 
1337
1360
    reg = DREG(insn, 0);
1338
 
    src1 = gen_new_qreg(QMODE_I32);
1339
 
    gen_op_mov32(src1, reg);
1340
 
    gen_op_neg32(reg, src1);
 
1361
    src1 = tcg_temp_new();
 
1362
    tcg_gen_mov_i32(src1, reg);
 
1363
    tcg_gen_neg_i32(reg, src1);
1341
1364
    s->cc_op = CC_OP_SUB;
1342
 
    gen_op_update_cc_add(reg, src1);
1343
 
    gen_op_update_xflag_lt(gen_im32(0), src1);
 
1365
    gen_update_cc_add(reg, src1);
 
1366
    gen_helper_xflag_lt(QREG_CC_X, tcg_const_i32(0), src1);
1344
1367
    s->cc_op = CC_OP_SUB;
1345
1368
}
1346
1369
 
1347
1370
static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1348
1371
{
1349
 
    gen_op_logic_cc(gen_im32(val & 0xf));
1350
 
    gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
 
1372
    tcg_gen_movi_i32(QREG_CC_DEST, val & 0xf);
 
1373
    tcg_gen_movi_i32(QREG_CC_X, (val & 0x10) >> 4);
1351
1374
    if (!ccr_only) {
1352
 
        gen_op_set_sr(gen_im32(val & 0xff00));
 
1375
        gen_helper_set_sr(cpu_env, tcg_const_i32(val & 0xff00));
1353
1376
    }
1354
1377
}
1355
1378
 
1356
1379
static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1357
1380
{
1358
 
    int src1;
1359
 
    int reg;
 
1381
    TCGv tmp;
 
1382
    TCGv reg;
1360
1383
 
1361
1384
    s->cc_op = CC_OP_FLAGS;
1362
1385
    if ((insn & 0x38) == 0)
1363
1386
      {
1364
 
        src1 = gen_new_qreg(QMODE_I32);
 
1387
        tmp = tcg_temp_new();
1365
1388
        reg = DREG(insn, 0);
1366
 
        gen_op_and32(src1, reg, gen_im32(0xf));
1367
 
        gen_op_logic_cc(src1);
1368
 
        gen_op_shr32(src1, reg, gen_im32(4));
1369
 
        gen_op_and32(src1, src1, gen_im32(1));
1370
 
        gen_op_update_xflag_tst(src1);
 
1389
        tcg_gen_andi_i32(QREG_CC_DEST, reg, 0xf);
 
1390
        tcg_gen_shri_i32(tmp, reg, 4);
 
1391
        tcg_gen_andi_i32(QREG_CC_X, tmp, 1);
1371
1392
        if (!ccr_only) {
1372
 
            gen_op_set_sr(reg);
 
1393
            gen_helper_set_sr(cpu_env, reg);
1373
1394
        }
1374
1395
      }
1375
1396
    else if ((insn & 0x3f) == 0x3c)
1390
1411
 
1391
1412
DISAS_INSN(not)
1392
1413
{
1393
 
    int reg;
 
1414
    TCGv reg;
1394
1415
 
1395
1416
    reg = DREG(insn, 0);
1396
 
    gen_op_not32(reg, reg);
 
1417
    tcg_gen_not_i32(reg, reg);
1397
1418
    gen_logic_cc(s, reg);
1398
1419
}
1399
1420
 
1400
1421
DISAS_INSN(swap)
1401
1422
{
1402
 
    int dest;
1403
 
    int src1;
1404
 
    int src2;
1405
 
    int reg;
 
1423
    TCGv src1;
 
1424
    TCGv src2;
 
1425
    TCGv reg;
1406
1426
 
1407
 
    dest = gen_new_qreg(QMODE_I32);
1408
 
    src1 = gen_new_qreg(QMODE_I32);
1409
 
    src2 = gen_new_qreg(QMODE_I32);
 
1427
    src1 = tcg_temp_new();
 
1428
    src2 = tcg_temp_new();
1410
1429
    reg = DREG(insn, 0);
1411
 
    gen_op_shl32(src1, reg, gen_im32(16));
1412
 
    gen_op_shr32(src2, reg, gen_im32(16));
1413
 
    gen_op_or32(dest, src1, src2);
1414
 
    gen_op_mov32(reg, dest);
1415
 
    gen_logic_cc(s, dest);
 
1430
    tcg_gen_shli_i32(src1, reg, 16);
 
1431
    tcg_gen_shri_i32(src2, reg, 16);
 
1432
    tcg_gen_or_i32(reg, src1, src2);
 
1433
    gen_logic_cc(s, reg);
1416
1434
}
1417
1435
 
1418
1436
DISAS_INSN(pea)
1419
1437
{
1420
 
    int tmp;
 
1438
    TCGv tmp;
1421
1439
 
1422
1440
    tmp = gen_lea(s, insn, OS_LONG);
1423
 
    if (tmp == -1) {
 
1441
    if (IS_NULL_QREG(tmp)) {
1424
1442
        gen_addr_fault(s);
1425
1443
        return;
1426
1444
    }
1429
1447
 
1430
1448
DISAS_INSN(ext)
1431
1449
{
1432
 
    int reg;
1433
1450
    int op;
1434
 
    int tmp;
 
1451
    TCGv reg;
 
1452
    TCGv tmp;
1435
1453
 
1436
1454
    reg = DREG(insn, 0);
1437
1455
    op = (insn >> 6) & 7;
1438
 
    tmp = gen_new_qreg(QMODE_I32);
 
1456
    tmp = tcg_temp_new();
1439
1457
    if (op == 3)
1440
 
        gen_op_ext16s32(tmp, reg);
 
1458
        tcg_gen_ext16s_i32(tmp, reg);
1441
1459
    else
1442
 
        gen_op_ext8s32(tmp, reg);
 
1460
        tcg_gen_ext8s_i32(tmp, reg);
1443
1461
    if (op == 2)
1444
1462
        gen_partset_reg(OS_WORD, reg, tmp);
1445
1463
    else
1446
 
      gen_op_mov32(reg, tmp);
 
1464
        tcg_gen_mov_i32(reg, tmp);
1447
1465
    gen_logic_cc(s, tmp);
1448
1466
}
1449
1467
 
1450
1468
DISAS_INSN(tst)
1451
1469
{
1452
1470
    int opsize;
1453
 
    int tmp;
 
1471
    TCGv tmp;
1454
1472
 
1455
1473
    switch ((insn >> 6) & 3) {
1456
1474
    case 0: /* tst.b */
1465
1483
    default:
1466
1484
        abort();
1467
1485
    }
1468
 
    SRC_EA(tmp, opsize, -1, NULL);
 
1486
    SRC_EA(tmp, opsize, 1, NULL);
1469
1487
    gen_logic_cc(s, tmp);
1470
1488
}
1471
1489
 
1482
1500
/* ??? This should be atomic.  */
1483
1501
DISAS_INSN(tas)
1484
1502
{
1485
 
    int dest;
1486
 
    int src1;
1487
 
    int addr;
 
1503
    TCGv dest;
 
1504
    TCGv src1;
 
1505
    TCGv addr;
1488
1506
 
1489
 
    dest = gen_new_qreg(QMODE_I32);
1490
 
    SRC_EA(src1, OS_BYTE, -1, &addr);
 
1507
    dest = tcg_temp_new();
 
1508
    SRC_EA(src1, OS_BYTE, 1, &addr);
1491
1509
    gen_logic_cc(s, src1);
1492
 
    gen_op_or32(dest, src1, gen_im32(0x80));
 
1510
    tcg_gen_ori_i32(dest, src1, 0x80);
1493
1511
    DEST_EA(insn, OS_BYTE, dest, &addr);
1494
1512
}
1495
1513
 
1496
1514
DISAS_INSN(mull)
1497
1515
{
1498
1516
    uint16_t ext;
1499
 
    int reg;
1500
 
    int src1;
1501
 
    int dest;
 
1517
    TCGv reg;
 
1518
    TCGv src1;
 
1519
    TCGv dest;
1502
1520
 
1503
1521
    /* The upper 32 bits of the product are discarded, so
1504
1522
       muls.l and mulu.l are functionally equivalent.  */
1510
1528
    }
1511
1529
    reg = DREG(ext, 12);
1512
1530
    SRC_EA(src1, OS_LONG, 0, NULL);
1513
 
    dest = gen_new_qreg(QMODE_I32);
1514
 
    gen_op_mul32(dest, src1, reg);
1515
 
    gen_op_mov32(reg, dest);
 
1531
    dest = tcg_temp_new();
 
1532
    tcg_gen_mul_i32(dest, src1, reg);
 
1533
    tcg_gen_mov_i32(reg, dest);
1516
1534
    /* Unlike m68k, coldfire always clears the overflow bit.  */
1517
1535
    gen_logic_cc(s, dest);
1518
1536
}
1520
1538
DISAS_INSN(link)
1521
1539
{
1522
1540
    int16_t offset;
1523
 
    int reg;
1524
 
    int tmp;
 
1541
    TCGv reg;
 
1542
    TCGv tmp;
1525
1543
 
1526
1544
    offset = ldsw_code(s->pc);
1527
1545
    s->pc += 2;
1528
1546
    reg = AREG(insn, 0);
1529
 
    tmp = gen_new_qreg(QMODE_I32);
1530
 
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
 
1547
    tmp = tcg_temp_new();
 
1548
    tcg_gen_subi_i32(tmp, QREG_SP, 4);
1531
1549
    gen_store(s, OS_LONG, tmp, reg);
1532
 
    if (reg != QREG_SP)
1533
 
        gen_op_mov32(reg, tmp);
1534
 
    gen_op_add32(QREG_SP, tmp, gen_im32(offset));
 
1550
    if ((insn & 7) != 7)
 
1551
        tcg_gen_mov_i32(reg, tmp);
 
1552
    tcg_gen_addi_i32(QREG_SP, tmp, offset);
1535
1553
}
1536
1554
 
1537
1555
DISAS_INSN(unlk)
1538
1556
{
1539
 
    int src;
1540
 
    int reg;
1541
 
    int tmp;
 
1557
    TCGv src;
 
1558
    TCGv reg;
 
1559
    TCGv tmp;
1542
1560
 
1543
 
    src = gen_new_qreg(QMODE_I32);
 
1561
    src = tcg_temp_new();
1544
1562
    reg = AREG(insn, 0);
1545
 
    gen_op_mov32(src, reg);
 
1563
    tcg_gen_mov_i32(src, reg);
1546
1564
    tmp = gen_load(s, OS_LONG, src, 0);
1547
 
    gen_op_mov32(reg, tmp);
1548
 
    gen_op_add32(QREG_SP, src, gen_im32(4));
 
1565
    tcg_gen_mov_i32(reg, tmp);
 
1566
    tcg_gen_addi_i32(QREG_SP, src, 4);
1549
1567
}
1550
1568
 
1551
1569
DISAS_INSN(nop)
1554
1572
 
1555
1573
DISAS_INSN(rts)
1556
1574
{
1557
 
    int tmp;
 
1575
    TCGv tmp;
1558
1576
 
1559
1577
    tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1560
 
    gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
 
1578
    tcg_gen_addi_i32(QREG_SP, QREG_SP, 4);
1561
1579
    gen_jmp(s, tmp);
1562
1580
}
1563
1581
 
1564
1582
DISAS_INSN(jump)
1565
1583
{
1566
 
    int tmp;
 
1584
    TCGv tmp;
1567
1585
 
1568
1586
    /* Load the target address first to ensure correct exception
1569
1587
       behavior.  */
1570
1588
    tmp = gen_lea(s, insn, OS_LONG);
1571
 
    if (tmp == -1) {
 
1589
    if (IS_NULL_QREG(tmp)) {
1572
1590
        gen_addr_fault(s);
1573
1591
        return;
1574
1592
    }
1581
1599
 
1582
1600
DISAS_INSN(addsubq)
1583
1601
{
1584
 
    int src1;
1585
 
    int src2;
1586
 
    int dest;
 
1602
    TCGv src1;
 
1603
    TCGv src2;
 
1604
    TCGv dest;
1587
1605
    int val;
1588
 
    int addr;
 
1606
    TCGv addr;
1589
1607
 
1590
1608
    SRC_EA(src1, OS_LONG, 0, &addr);
1591
1609
    val = (insn >> 9) & 7;
1592
1610
    if (val == 0)
1593
1611
        val = 8;
1594
 
    src2 = gen_im32(val);
1595
 
    dest = gen_new_qreg(QMODE_I32);
1596
 
    gen_op_mov32(dest, src1);
 
1612
    dest = tcg_temp_new();
 
1613
    tcg_gen_mov_i32(dest, src1);
1597
1614
    if ((insn & 0x38) == 0x08) {
1598
1615
        /* Don't update condition codes if the destination is an
1599
1616
           address register.  */
1600
1617
        if (insn & 0x0100) {
1601
 
            gen_op_sub32(dest, dest, src2);
 
1618
            tcg_gen_subi_i32(dest, dest, val);
1602
1619
        } else {
1603
 
            gen_op_add32(dest, dest, src2);
 
1620
            tcg_gen_addi_i32(dest, dest, val);
1604
1621
        }
1605
1622
    } else {
 
1623
        src2 = gen_im32(val);
1606
1624
        if (insn & 0x0100) {
1607
 
            gen_op_update_xflag_lt(dest, src2);
1608
 
            gen_op_sub32(dest, dest, src2);
 
1625
            gen_helper_xflag_lt(QREG_CC_X, dest, src2);
 
1626
            tcg_gen_subi_i32(dest, dest, val);
1609
1627
            s->cc_op = CC_OP_SUB;
1610
1628
        } else {
1611
 
            gen_op_add32(dest, dest, src2);
1612
 
            gen_op_update_xflag_lt(dest, src2);
 
1629
            tcg_gen_addi_i32(dest, dest, val);
 
1630
            gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1613
1631
            s->cc_op = CC_OP_ADD;
1614
1632
        }
1615
 
        gen_op_update_cc_add(dest, src2);
 
1633
        gen_update_cc_add(dest, src2);
1616
1634
    }
1617
1635
    DEST_EA(insn, OS_LONG, dest, &addr);
1618
1636
}
1669
1687
 
1670
1688
DISAS_INSN(moveq)
1671
1689
{
1672
 
    int tmp;
 
1690
    uint32_t val;
1673
1691
 
1674
 
    tmp = gen_im32((int8_t)insn);
1675
 
    gen_op_mov32(DREG(insn, 9), tmp);
1676
 
    gen_logic_cc(s, tmp);
 
1692
    val = (int8_t)insn;
 
1693
    tcg_gen_movi_i32(DREG(insn, 9), val);
 
1694
    gen_logic_cc(s, tcg_const_i32(val));
1677
1695
}
1678
1696
 
1679
1697
DISAS_INSN(mvzs)
1680
1698
{
1681
1699
    int opsize;
1682
 
    int src;
1683
 
    int reg;
 
1700
    TCGv src;
 
1701
    TCGv reg;
1684
1702
 
1685
1703
    if (insn & 0x40)
1686
1704
        opsize = OS_WORD;
1687
1705
    else
1688
1706
        opsize = OS_BYTE;
1689
 
    SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL);
 
1707
    SRC_EA(src, opsize, (insn & 0x80) == 0, NULL);
1690
1708
    reg = DREG(insn, 9);
1691
 
    gen_op_mov32(reg, src);
 
1709
    tcg_gen_mov_i32(reg, src);
1692
1710
    gen_logic_cc(s, src);
1693
1711
}
1694
1712
 
1695
1713
DISAS_INSN(or)
1696
1714
{
1697
 
    int reg;
1698
 
    int dest;
1699
 
    int src;
1700
 
    int addr;
 
1715
    TCGv reg;
 
1716
    TCGv dest;
 
1717
    TCGv src;
 
1718
    TCGv addr;
1701
1719
 
1702
1720
    reg = DREG(insn, 9);
1703
 
    dest = gen_new_qreg(QMODE_I32);
 
1721
    dest = tcg_temp_new();
1704
1722
    if (insn & 0x100) {
1705
1723
        SRC_EA(src, OS_LONG, 0, &addr);
1706
 
        gen_op_or32(dest, src, reg);
 
1724
        tcg_gen_or_i32(dest, src, reg);
1707
1725
        DEST_EA(insn, OS_LONG, dest, &addr);
1708
1726
    } else {
1709
1727
        SRC_EA(src, OS_LONG, 0, NULL);
1710
 
        gen_op_or32(dest, src, reg);
1711
 
        gen_op_mov32(reg, dest);
 
1728
        tcg_gen_or_i32(dest, src, reg);
 
1729
        tcg_gen_mov_i32(reg, dest);
1712
1730
    }
1713
1731
    gen_logic_cc(s, dest);
1714
1732
}
1715
1733
 
1716
1734
DISAS_INSN(suba)
1717
1735
{
1718
 
    int src;
1719
 
    int reg;
 
1736
    TCGv src;
 
1737
    TCGv reg;
1720
1738
 
1721
1739
    SRC_EA(src, OS_LONG, 0, NULL);
1722
1740
    reg = AREG(insn, 9);
1723
 
    gen_op_sub32(reg, reg, src);
 
1741
    tcg_gen_sub_i32(reg, reg, src);
1724
1742
}
1725
1743
 
1726
1744
DISAS_INSN(subx)
1727
1745
{
1728
 
    int reg;
1729
 
    int src;
1730
 
    int dest;
1731
 
    int tmp;
 
1746
    TCGv reg;
 
1747
    TCGv src;
1732
1748
 
1733
1749
    gen_flush_flags(s);
1734
1750
    reg = DREG(insn, 9);
1735
1751
    src = DREG(insn, 0);
1736
 
    dest = gen_new_qreg(QMODE_I32);
1737
 
    gen_op_mov32 (dest, reg);
1738
 
    gen_op_subx_cc(dest, src);
1739
 
    /* !Z is sticky.  */
1740
 
    tmp = gen_new_qreg(QMODE_I32);
1741
 
    gen_op_mov32 (tmp, QREG_CC_DEST);
1742
 
    gen_op_update_cc_add(dest, src);
1743
 
    gen_op_mov32(reg, dest);
1744
 
    s->cc_op = CC_OP_DYNAMIC;
1745
 
    gen_flush_flags(s);
1746
 
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1747
 
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1748
 
    s->cc_op = CC_OP_FLAGS;
 
1752
    gen_helper_subx_cc(reg, cpu_env, reg, src);
1749
1753
}
1750
1754
 
1751
1755
DISAS_INSN(mov3q)
1752
1756
{
1753
 
    int src;
 
1757
    TCGv src;
1754
1758
    int val;
1755
1759
 
1756
1760
    val = (insn >> 9) & 7;
1764
1768
DISAS_INSN(cmp)
1765
1769
{
1766
1770
    int op;
1767
 
    int src;
1768
 
    int reg;
1769
 
    int dest;
 
1771
    TCGv src;
 
1772
    TCGv reg;
 
1773
    TCGv dest;
1770
1774
    int opsize;
1771
1775
 
1772
1776
    op = (insn >> 6) & 3;
1786
1790
    default:
1787
1791
        abort();
1788
1792
    }
1789
 
    SRC_EA(src, opsize, -1, NULL);
 
1793
    SRC_EA(src, opsize, 1, NULL);
1790
1794
    reg = DREG(insn, 9);
1791
 
    dest = gen_new_qreg(QMODE_I32);
1792
 
    gen_op_sub32(dest, reg, src);
1793
 
    gen_op_update_cc_add(dest, src);
 
1795
    dest = tcg_temp_new();
 
1796
    tcg_gen_sub_i32(dest, reg, src);
 
1797
    gen_update_cc_add(dest, src);
1794
1798
}
1795
1799
 
1796
1800
DISAS_INSN(cmpa)
1797
1801
{
1798
1802
    int opsize;
1799
 
    int src;
1800
 
    int reg;
1801
 
    int dest;
 
1803
    TCGv src;
 
1804
    TCGv reg;
 
1805
    TCGv dest;
1802
1806
 
1803
1807
    if (insn & 0x100) {
1804
1808
        opsize = OS_LONG;
1805
1809
    } else {
1806
1810
        opsize = OS_WORD;
1807
1811
    }
1808
 
    SRC_EA(src, opsize, -1, NULL);
 
1812
    SRC_EA(src, opsize, 1, NULL);
1809
1813
    reg = AREG(insn, 9);
1810
 
    dest = gen_new_qreg(QMODE_I32);
1811
 
    gen_op_sub32(dest, reg, src);
1812
 
    gen_op_update_cc_add(dest, src);
 
1814
    dest = tcg_temp_new();
 
1815
    tcg_gen_sub_i32(dest, reg, src);
 
1816
    gen_update_cc_add(dest, src);
1813
1817
    s->cc_op = CC_OP_SUB;
1814
1818
}
1815
1819
 
1816
1820
DISAS_INSN(eor)
1817
1821
{
1818
 
    int src;
1819
 
    int reg;
1820
 
    int dest;
1821
 
    int addr;
 
1822
    TCGv src;
 
1823
    TCGv reg;
 
1824
    TCGv dest;
 
1825
    TCGv addr;
1822
1826
 
1823
1827
    SRC_EA(src, OS_LONG, 0, &addr);
1824
1828
    reg = DREG(insn, 9);
1825
 
    dest = gen_new_qreg(QMODE_I32);
1826
 
    gen_op_xor32(dest, src, reg);
 
1829
    dest = tcg_temp_new();
 
1830
    tcg_gen_xor_i32(dest, src, reg);
1827
1831
    gen_logic_cc(s, dest);
1828
1832
    DEST_EA(insn, OS_LONG, dest, &addr);
1829
1833
}
1830
1834
 
1831
1835
DISAS_INSN(and)
1832
1836
{
1833
 
    int src;
1834
 
    int reg;
1835
 
    int dest;
1836
 
    int addr;
 
1837
    TCGv src;
 
1838
    TCGv reg;
 
1839
    TCGv dest;
 
1840
    TCGv addr;
1837
1841
 
1838
1842
    reg = DREG(insn, 9);
1839
 
    dest = gen_new_qreg(QMODE_I32);
 
1843
    dest = tcg_temp_new();
1840
1844
    if (insn & 0x100) {
1841
1845
        SRC_EA(src, OS_LONG, 0, &addr);
1842
 
        gen_op_and32(dest, src, reg);
 
1846
        tcg_gen_and_i32(dest, src, reg);
1843
1847
        DEST_EA(insn, OS_LONG, dest, &addr);
1844
1848
    } else {
1845
1849
        SRC_EA(src, OS_LONG, 0, NULL);
1846
 
        gen_op_and32(dest, src, reg);
1847
 
        gen_op_mov32(reg, dest);
 
1850
        tcg_gen_and_i32(dest, src, reg);
 
1851
        tcg_gen_mov_i32(reg, dest);
1848
1852
    }
1849
1853
    gen_logic_cc(s, dest);
1850
1854
}
1851
1855
 
1852
1856
DISAS_INSN(adda)
1853
1857
{
1854
 
    int src;
1855
 
    int reg;
 
1858
    TCGv src;
 
1859
    TCGv reg;
1856
1860
 
1857
1861
    SRC_EA(src, OS_LONG, 0, NULL);
1858
1862
    reg = AREG(insn, 9);
1859
 
    gen_op_add32(reg, reg, src);
 
1863
    tcg_gen_add_i32(reg, reg, src);
1860
1864
}
1861
1865
 
1862
1866
DISAS_INSN(addx)
1863
1867
{
1864
 
    int reg;
1865
 
    int src;
1866
 
    int dest;
1867
 
    int tmp;
 
1868
    TCGv reg;
 
1869
    TCGv src;
1868
1870
 
1869
1871
    gen_flush_flags(s);
1870
1872
    reg = DREG(insn, 9);
1871
1873
    src = DREG(insn, 0);
1872
 
    dest = gen_new_qreg(QMODE_I32);
1873
 
    gen_op_mov32 (dest, reg);
1874
 
    gen_op_addx_cc(dest, src);
1875
 
    /* !Z is sticky.  */
1876
 
    tmp = gen_new_qreg(QMODE_I32);
1877
 
    gen_op_mov32 (tmp, QREG_CC_DEST);
1878
 
    gen_op_update_cc_add(dest, src);
1879
 
    gen_op_mov32(reg, dest);
1880
 
    s->cc_op = CC_OP_DYNAMIC;
1881
 
    gen_flush_flags(s);
1882
 
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1883
 
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
 
1874
    gen_helper_addx_cc(reg, cpu_env, reg, src);
1884
1875
    s->cc_op = CC_OP_FLAGS;
1885
1876
}
1886
1877
 
 
1878
/* TODO: This could be implemented without helper functions.  */
1887
1879
DISAS_INSN(shift_im)
1888
1880
{
1889
 
    int reg;
 
1881
    TCGv reg;
1890
1882
    int tmp;
 
1883
    TCGv shift;
1891
1884
 
1892
1885
    reg = DREG(insn, 0);
1893
1886
    tmp = (insn >> 9) & 7;
1894
1887
    if (tmp == 0)
1895
 
      tmp = 8;
 
1888
        tmp = 8;
 
1889
    shift = gen_im32(tmp);
 
1890
    /* No need to flush flags becuse we know we will set C flag.  */
1896
1891
    if (insn & 0x100) {
1897
 
        gen_op_shl_im_cc(reg, tmp);
1898
 
        s->cc_op = CC_OP_SHL;
 
1892
        gen_helper_shl_cc(reg, cpu_env, reg, shift);
1899
1893
    } else {
1900
1894
        if (insn & 8) {
1901
 
            gen_op_shr_im_cc(reg, tmp);
1902
 
            s->cc_op = CC_OP_SHR;
 
1895
            gen_helper_shr_cc(reg, cpu_env, reg, shift);
1903
1896
        } else {
1904
 
            gen_op_sar_im_cc(reg, tmp);
1905
 
            s->cc_op = CC_OP_SAR;
 
1897
            gen_helper_sar_cc(reg, cpu_env, reg, shift);
1906
1898
        }
1907
1899
    }
 
1900
    s->cc_op = CC_OP_SHIFT;
1908
1901
}
1909
1902
 
1910
1903
DISAS_INSN(shift_reg)
1911
1904
{
1912
 
    int reg;
1913
 
    int src;
1914
 
    int tmp;
 
1905
    TCGv reg;
 
1906
    TCGv shift;
1915
1907
 
1916
1908
    reg = DREG(insn, 0);
1917
 
    src = DREG(insn, 9);
1918
 
    tmp = gen_new_qreg(QMODE_I32);
1919
 
    gen_op_and32(tmp, src, gen_im32(63));
 
1909
    shift = DREG(insn, 9);
 
1910
    /* Shift by zero leaves C flag unmodified.   */
 
1911
    gen_flush_flags(s);
1920
1912
    if (insn & 0x100) {
1921
 
        gen_op_shl_cc(reg, tmp);
1922
 
        s->cc_op = CC_OP_SHL;
 
1913
        gen_helper_shl_cc(reg, cpu_env, reg, shift);
1923
1914
    } else {
1924
1915
        if (insn & 8) {
1925
 
            gen_op_shr_cc(reg, tmp);
1926
 
            s->cc_op = CC_OP_SHR;
 
1916
            gen_helper_shr_cc(reg, cpu_env, reg, shift);
1927
1917
        } else {
1928
 
            gen_op_sar_cc(reg, tmp);
1929
 
            s->cc_op = CC_OP_SAR;
 
1918
            gen_helper_sar_cc(reg, cpu_env, reg, shift);
1930
1919
        }
1931
1920
    }
 
1921
    s->cc_op = CC_OP_SHIFT;
1932
1922
}
1933
1923
 
1934
1924
DISAS_INSN(ff1)
1935
1925
{
1936
 
    int reg;
 
1926
    TCGv reg;
1937
1927
    reg = DREG(insn, 0);
1938
1928
    gen_logic_cc(s, reg);
1939
 
    gen_op_ff1(reg, reg);
 
1929
    gen_helper_ff1(reg, reg);
1940
1930
}
1941
1931
 
1942
 
static int gen_get_sr(DisasContext *s)
 
1932
static TCGv gen_get_sr(DisasContext *s)
1943
1933
{
1944
 
    int ccr;
1945
 
    int sr;
 
1934
    TCGv ccr;
 
1935
    TCGv sr;
1946
1936
 
1947
1937
    ccr = gen_get_ccr(s);
1948
 
    sr = gen_new_qreg(QMODE_I32);
1949
 
    gen_op_and32(sr, QREG_SR, gen_im32(0xffe0));
1950
 
    gen_op_or32(sr, sr, ccr);
 
1938
    sr = tcg_temp_new();
 
1939
    tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
 
1940
    tcg_gen_or_i32(sr, sr, ccr);
1951
1941
    return sr;
1952
1942
}
1953
1943
 
1975
1965
 
1976
1966
DISAS_INSN(move_from_sr)
1977
1967
{
1978
 
    int reg;
1979
 
    int sr;
 
1968
    TCGv reg;
 
1969
    TCGv sr;
1980
1970
 
1981
1971
    if (IS_USER(s)) {
1982
1972
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2019
2009
 
2020
2010
DISAS_INSN(halt)
2021
2011
{
2022
 
    gen_jmp(s, gen_im32(s->pc));
2023
 
    gen_op_halt();
 
2012
    gen_exception(s, s->pc, EXCP_HALT_INSN);
2024
2013
}
2025
2014
 
2026
2015
DISAS_INSN(stop)
2036
2025
    s->pc += 2;
2037
2026
 
2038
2027
    gen_set_sr_im(s, ext, 0);
2039
 
    gen_jmp(s, gen_im32(s->pc));
2040
 
    gen_op_stop();
 
2028
    tcg_gen_movi_i32(QREG_HALTED, 1);
 
2029
    gen_exception(s, s->pc, EXCP_HLT);
2041
2030
}
2042
2031
 
2043
2032
DISAS_INSN(rte)
2052
2041
DISAS_INSN(movec)
2053
2042
{
2054
2043
    uint16_t ext;
2055
 
    int reg;
 
2044
    TCGv reg;
2056
2045
 
2057
2046
    if (IS_USER(s)) {
2058
2047
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2067
2056
    } else {
2068
2057
        reg = DREG(ext, 12);
2069
2058
    }
2070
 
    gen_op_movec(gen_im32(ext & 0xfff), reg);
 
2059
    gen_helper_movec(cpu_env, tcg_const_i32(ext & 0xfff), reg);
2071
2060
    gen_lookup_tb(s);
2072
2061
}
2073
2062
 
2114
2103
DISAS_INSN(fpu)
2115
2104
{
2116
2105
    uint16_t ext;
 
2106
    int32_t offset;
2117
2107
    int opmode;
2118
 
    int src;
2119
 
    int dest;
2120
 
    int res;
 
2108
    TCGv_i64 src;
 
2109
    TCGv_i64 dest;
 
2110
    TCGv_i64 res;
 
2111
    TCGv tmp32;
2121
2112
    int round;
 
2113
    int set_dest;
2122
2114
    int opsize;
2123
2115
 
2124
2116
    ext = lduw_code(s->pc);
2131
2123
        goto undef;
2132
2124
    case 3: /* fmove out */
2133
2125
        src = FREG(ext, 7);
 
2126
        tmp32 = tcg_temp_new_i32();
2134
2127
        /* fmove */
2135
2128
        /* ??? TODO: Proper behavior on overflow.  */
2136
2129
        switch ((ext >> 10) & 7) {
2137
2130
        case 0:
2138
2131
            opsize = OS_LONG;
2139
 
            res = gen_new_qreg(QMODE_I32);
2140
 
            gen_op_f64_to_i32(res, src);
 
2132
            gen_helper_f64_to_i32(tmp32, cpu_env, src);
2141
2133
            break;
2142
2134
        case 1:
2143
2135
            opsize = OS_SINGLE;
2144
 
            res = gen_new_qreg(QMODE_F32);
2145
 
            gen_op_f64_to_f32(res, src);
 
2136
            gen_helper_f64_to_f32(tmp32, cpu_env, src);
2146
2137
            break;
2147
2138
        case 4:
2148
2139
            opsize = OS_WORD;
2149
 
            res = gen_new_qreg(QMODE_I32);
2150
 
            gen_op_f64_to_i32(res, src);
2151
 
            break;
2152
 
        case 5:
2153
 
            opsize = OS_DOUBLE;
2154
 
            res = src;
2155
 
            break;
 
2140
            gen_helper_f64_to_i32(tmp32, cpu_env, src);
 
2141
            break;
 
2142
        case 5: /* OS_DOUBLE */
 
2143
            tcg_gen_mov_i32(tmp32, AREG(insn, 0));
 
2144
            switch ((insn >> 3) & 7) {
 
2145
            case 2:
 
2146
            case 3:
 
2147
                break;
 
2148
            case 4:
 
2149
                tcg_gen_addi_i32(tmp32, tmp32, -8);
 
2150
                break;
 
2151
            case 5:
 
2152
                offset = ldsw_code(s->pc);
 
2153
                s->pc += 2;
 
2154
                tcg_gen_addi_i32(tmp32, tmp32, offset);
 
2155
                break;
 
2156
            default:
 
2157
                goto undef;
 
2158
            }
 
2159
            gen_store64(s, tmp32, src);
 
2160
            switch ((insn >> 3) & 7) {
 
2161
            case 3:
 
2162
                tcg_gen_addi_i32(tmp32, tmp32, 8);
 
2163
                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
 
2164
                break;
 
2165
            case 4:
 
2166
                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
 
2167
                break;
 
2168
            }
 
2169
            tcg_temp_free_i32(tmp32);
 
2170
            return;
2156
2171
        case 6:
2157
2172
            opsize = OS_BYTE;
2158
 
            res = gen_new_qreg(QMODE_I32);
2159
 
            gen_op_f64_to_i32(res, src);
 
2173
            gen_helper_f64_to_i32(tmp32, cpu_env, src);
2160
2174
            break;
2161
2175
        default:
2162
2176
            goto undef;
2163
2177
        }
2164
 
        DEST_EA(insn, opsize, res, NULL);
 
2178
        DEST_EA(insn, opsize, tmp32, NULL);
 
2179
        tcg_temp_free_i32(tmp32);
2165
2180
        return;
2166
2181
    case 4: /* fmove to control register.  */
2167
2182
        switch ((ext >> 10) & 7) {
2179
2194
        switch ((ext >> 10) & 7) {
2180
2195
        case 4: /* FPCR */
2181
2196
            /* Not implemented.  Always return zero.  */
2182
 
            res = gen_im32(0);
 
2197
            tmp32 = gen_im32(0);
2183
2198
            break;
2184
2199
        case 1: /* FPIAR */
2185
2200
        case 2: /* FPSR */
2188
2203
                      (ext >> 10) & 7);
2189
2204
            goto undef;
2190
2205
        }
2191
 
        DEST_EA(insn, OS_LONG, res, NULL);
 
2206
        DEST_EA(insn, OS_LONG, tmp32, NULL);
2192
2207
        break;
2193
2208
    case 6: /* fmovem */
2194
2209
    case 7:
2195
2210
        {
2196
 
        int addr;
2197
 
        uint16_t mask;
2198
 
        if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
2199
 
            goto undef;
2200
 
        src = gen_lea(s, insn, OS_LONG);
2201
 
        if (src == -1) {
2202
 
            gen_addr_fault(s);
2203
 
            return;
2204
 
        }
2205
 
        addr = gen_new_qreg(QMODE_I32);
2206
 
        gen_op_mov32(addr, src);
2207
 
        mask = 0x80;
2208
 
        dest = QREG_F0;
2209
 
        while (mask) {
2210
 
            if (ext & mask) {
2211
 
                s->is_mem = 1;
2212
 
                if (ext & (1 << 13)) {
2213
 
                    /* store */
2214
 
                    gen_st(s, f64, addr, dest);
2215
 
                } else {
2216
 
                    /* load */
2217
 
                    gen_ld(s, f64, dest, addr);
 
2211
            TCGv addr;
 
2212
            uint16_t mask;
 
2213
            int i;
 
2214
            if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
 
2215
                goto undef;
 
2216
            tmp32 = gen_lea(s, insn, OS_LONG);
 
2217
            if (IS_NULL_QREG(tmp32)) {
 
2218
                gen_addr_fault(s);
 
2219
                return;
 
2220
            }
 
2221
            addr = tcg_temp_new_i32();
 
2222
            tcg_gen_mov_i32(addr, tmp32);
 
2223
            mask = 0x80;
 
2224
            for (i = 0; i < 8; i++) {
 
2225
                if (ext & mask) {
 
2226
                    s->is_mem = 1;
 
2227
                    dest = FREG(i, 0);
 
2228
                    if (ext & (1 << 13)) {
 
2229
                        /* store */
 
2230
                        tcg_gen_qemu_stf64(dest, addr, IS_USER(s));
 
2231
                    } else {
 
2232
                        /* load */
 
2233
                        tcg_gen_qemu_ldf64(dest, addr, IS_USER(s));
 
2234
                    }
 
2235
                    if (ext & (mask - 1))
 
2236
                        tcg_gen_addi_i32(addr, addr, 8);
2218
2237
                }
2219
 
                if (ext & (mask - 1))
2220
 
                    gen_op_add32(addr, addr, gen_im32(8));
 
2238
                mask >>= 1;
2221
2239
            }
2222
 
            mask >>= 1;
2223
 
            dest++;
2224
 
        }
 
2240
            tcg_temp_free_i32(addr);
2225
2241
        }
2226
2242
        return;
2227
2243
    }
2228
2244
    if (ext & (1 << 14)) {
2229
 
        int tmp;
2230
 
 
2231
2245
        /* Source effective address.  */
2232
2246
        switch ((ext >> 10) & 7) {
2233
2247
        case 0: opsize = OS_LONG; break;
2238
2252
        default:
2239
2253
            goto undef;
2240
2254
        }
2241
 
        SRC_EA(tmp, opsize, -1, NULL);
2242
2255
        if (opsize == OS_DOUBLE) {
2243
 
            src = tmp;
 
2256
            tmp32 = tcg_temp_new_i32();
 
2257
            tcg_gen_mov_i32(tmp32, AREG(insn, 0));
 
2258
            switch ((insn >> 3) & 7) {
 
2259
            case 2:
 
2260
            case 3:
 
2261
                break;
 
2262
            case 4:
 
2263
                tcg_gen_addi_i32(tmp32, tmp32, -8);
 
2264
                break;
 
2265
            case 5:
 
2266
                offset = ldsw_code(s->pc);
 
2267
                s->pc += 2;
 
2268
                tcg_gen_addi_i32(tmp32, tmp32, offset);
 
2269
                break;
 
2270
            case 7:
 
2271
                offset = ldsw_code(s->pc);
 
2272
                offset += s->pc - 2;
 
2273
                s->pc += 2;
 
2274
                tcg_gen_addi_i32(tmp32, tmp32, offset);
 
2275
                break;
 
2276
            default:
 
2277
                goto undef;
 
2278
            }
 
2279
            src = gen_load64(s, tmp32);
 
2280
            switch ((insn >> 3) & 7) {
 
2281
            case 3:
 
2282
                tcg_gen_addi_i32(tmp32, tmp32, 8);
 
2283
                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
 
2284
                break;
 
2285
            case 4:
 
2286
                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
 
2287
                break;
 
2288
            }
 
2289
            tcg_temp_free_i32(tmp32);
2244
2290
        } else {
2245
 
            src = gen_new_qreg(QMODE_F64);
 
2291
            SRC_EA(tmp32, opsize, 1, NULL);
 
2292
            src = tcg_temp_new_i64();
2246
2293
            switch (opsize) {
2247
2294
            case OS_LONG:
2248
2295
            case OS_WORD:
2249
2296
            case OS_BYTE:
2250
 
                gen_op_i32_to_f64(src, tmp);
 
2297
                gen_helper_i32_to_f64(src, cpu_env, tmp32);
2251
2298
                break;
2252
2299
            case OS_SINGLE:
2253
 
                gen_op_f32_to_f64(src, tmp);
 
2300
                gen_helper_f32_to_f64(src, cpu_env, tmp32);
2254
2301
                break;
2255
2302
            }
2256
2303
        }
2259
2306
        src = FREG(ext, 10);
2260
2307
    }
2261
2308
    dest = FREG(ext, 7);
2262
 
    res = gen_new_qreg(QMODE_F64);
 
2309
    res = tcg_temp_new_i64();
2263
2310
    if (opmode != 0x3a)
2264
 
        gen_op_movf64(res, dest);
 
2311
        tcg_gen_mov_f64(res, dest);
2265
2312
    round = 1;
 
2313
    set_dest = 1;
2266
2314
    switch (opmode) {
2267
2315
    case 0: case 0x40: case 0x44: /* fmove */
2268
 
        gen_op_movf64(res, src);
 
2316
        tcg_gen_mov_f64(res, src);
2269
2317
        break;
2270
2318
    case 1: /* fint */
2271
 
        gen_op_iround_f64(res, src);
 
2319
        gen_helper_iround_f64(res, cpu_env, src);
2272
2320
        round = 0;
2273
2321
        break;
2274
2322
    case 3: /* fintrz */
2275
 
        gen_op_itrunc_f64(res, src);
 
2323
        gen_helper_itrunc_f64(res, cpu_env, src);
2276
2324
        round = 0;
2277
2325
        break;
2278
2326
    case 4: case 0x41: case 0x45: /* fsqrt */
2279
 
        gen_op_sqrtf64(res, src);
 
2327
        gen_helper_sqrt_f64(res, cpu_env, src);
2280
2328
        break;
2281
2329
    case 0x18: case 0x58: case 0x5c: /* fabs */
2282
 
        gen_op_absf64(res, src);
 
2330
        gen_helper_abs_f64(res, src);
2283
2331
        break;
2284
2332
    case 0x1a: case 0x5a: case 0x5e: /* fneg */
2285
 
        gen_op_chsf64(res, src);
 
2333
        gen_helper_chs_f64(res, src);
2286
2334
        break;
2287
2335
    case 0x20: case 0x60: case 0x64: /* fdiv */
2288
 
        gen_op_divf64(res, res, src);
 
2336
        gen_helper_div_f64(res, cpu_env, res, src);
2289
2337
        break;
2290
2338
    case 0x22: case 0x62: case 0x66: /* fadd */
2291
 
        gen_op_addf64(res, res, src);
 
2339
        gen_helper_add_f64(res, cpu_env, res, src);
2292
2340
        break;
2293
2341
    case 0x23: case 0x63: case 0x67: /* fmul */
2294
 
        gen_op_mulf64(res, res, src);
 
2342
        gen_helper_mul_f64(res, cpu_env, res, src);
2295
2343
        break;
2296
2344
    case 0x28: case 0x68: case 0x6c: /* fsub */
2297
 
        gen_op_subf64(res, res, src);
 
2345
        gen_helper_sub_f64(res, cpu_env, res, src);
2298
2346
        break;
2299
2347
    case 0x38: /* fcmp */
2300
 
        gen_op_sub_cmpf64(res, res, src);
2301
 
        dest = 0;
 
2348
        gen_helper_sub_cmp_f64(res, cpu_env, res, src);
 
2349
        set_dest = 0;
2302
2350
        round = 0;
2303
2351
        break;
2304
2352
    case 0x3a: /* ftst */
2305
 
        gen_op_movf64(res, src);
2306
 
        dest = 0;
 
2353
        tcg_gen_mov_f64(res, src);
 
2354
        set_dest = 0;
2307
2355
        round = 0;
2308
2356
        break;
2309
2357
    default:
2310
2358
        goto undef;
2311
2359
    }
 
2360
    if (ext & (1 << 14)) {
 
2361
        tcg_temp_free_i64(src);
 
2362
    }
2312
2363
    if (round) {
2313
2364
        if (opmode & 0x40) {
2314
2365
            if ((opmode & 0x4) != 0)
2318
2369
        }
2319
2370
    }
2320
2371
    if (round) {
2321
 
        int tmp;
2322
 
 
2323
 
        tmp = gen_new_qreg(QMODE_F32);
2324
 
        gen_op_f64_to_f32(tmp, res);
2325
 
        gen_op_f32_to_f64(res, tmp);
2326
 
    }
2327
 
    gen_op_fp_result(res);
2328
 
    if (dest) {
2329
 
        gen_op_movf64(dest, res);
2330
 
    }
 
2372
        TCGv tmp = tcg_temp_new_i32();
 
2373
        gen_helper_f64_to_f32(tmp, cpu_env, res);
 
2374
        gen_helper_f32_to_f64(res, cpu_env, tmp);
 
2375
        tcg_temp_free_i32(tmp);
 
2376
    }
 
2377
    tcg_gen_mov_f64(QREG_FP_RESULT, res);
 
2378
    if (set_dest) {
 
2379
        tcg_gen_mov_f64(dest, res);
 
2380
    }
 
2381
    tcg_temp_free_i64(res);
2331
2382
    return;
2332
2383
undef:
 
2384
    /* FIXME: Is this right for offset addressing modes?  */
2333
2385
    s->pc -= 2;
2334
2386
    disas_undef_fpu(s, insn);
2335
2387
}
2338
2390
{
2339
2391
    uint32_t offset;
2340
2392
    uint32_t addr;
2341
 
    int flag;
2342
 
    int zero;
 
2393
    TCGv flag;
2343
2394
    int l1;
2344
2395
 
2345
2396
    addr = s->pc;
2352
2403
 
2353
2404
    l1 = gen_new_label();
2354
2405
    /* TODO: Raise BSUN exception.  */
2355
 
    flag = gen_new_qreg(QMODE_I32);
2356
 
    zero = gen_new_qreg(QMODE_F64);
2357
 
    gen_op_zerof64(zero);
2358
 
    gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
 
2406
    flag = tcg_temp_new();
 
2407
    gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT);
2359
2408
    /* Jump to l1 if condition is true.  */
2360
2409
    switch (insn & 0xf) {
2361
2410
    case 0: /* f */
2362
2411
        break;
2363
2412
    case 1: /* eq (=0) */
2364
 
        gen_op_jmp_z32(flag, l1);
 
2413
        tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2365
2414
        break;
2366
2415
    case 2: /* ogt (=1) */
2367
 
        gen_op_sub32(flag, flag, gen_im32(1));
2368
 
        gen_op_jmp_z32(flag, l1);
 
2416
        tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(1), l1);
2369
2417
        break;
2370
2418
    case 3: /* oge (=0 or =1) */
2371
 
        gen_op_jmp_z32(flag, l1);
2372
 
        gen_op_sub32(flag, flag, gen_im32(1));
2373
 
        gen_op_jmp_z32(flag, l1);
 
2419
        tcg_gen_brcond_i32(TCG_COND_LEU, flag, tcg_const_i32(1), l1);
2374
2420
        break;
2375
2421
    case 4: /* olt (=-1) */
2376
 
        gen_op_jmp_s32(flag, l1);
 
2422
        tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(0), l1);
2377
2423
        break;
2378
2424
    case 5: /* ole (=-1 or =0) */
2379
 
        gen_op_jmp_s32(flag, l1);
2380
 
        gen_op_jmp_z32(flag, l1);
 
2425
        tcg_gen_brcond_i32(TCG_COND_LE, flag, tcg_const_i32(0), l1);
2381
2426
        break;
2382
2427
    case 6: /* ogl (=-1 or =1) */
2383
 
        gen_op_jmp_s32(flag, l1);
2384
 
        gen_op_sub32(flag, flag, gen_im32(1));
2385
 
        gen_op_jmp_z32(flag, l1);
 
2428
        tcg_gen_andi_i32(flag, flag, 1);
 
2429
        tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2386
2430
        break;
2387
2431
    case 7: /* or (=2) */
2388
 
        gen_op_sub32(flag, flag, gen_im32(2));
2389
 
        gen_op_jmp_z32(flag, l1);
 
2432
        tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(2), l1);
2390
2433
        break;
2391
2434
    case 8: /* un (<2) */
2392
 
        gen_op_sub32(flag, flag, gen_im32(2));
2393
 
        gen_op_jmp_s32(flag, l1);
 
2435
        tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(2), l1);
2394
2436
        break;
2395
2437
    case 9: /* ueq (=0 or =2) */
2396
 
        gen_op_jmp_z32(flag, l1);
2397
 
        gen_op_sub32(flag, flag, gen_im32(2));
2398
 
        gen_op_jmp_z32(flag, l1);
 
2438
        tcg_gen_andi_i32(flag, flag, 1);
 
2439
        tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2399
2440
        break;
2400
2441
    case 10: /* ugt (>0) */
2401
 
        /* ??? Add jmp_gtu.  */
2402
 
        gen_op_sub32(flag, flag, gen_im32(1));
2403
 
        gen_op_jmp_ns32(flag, l1);
 
2442
        tcg_gen_brcond_i32(TCG_COND_GT, flag, tcg_const_i32(0), l1);
2404
2443
        break;
2405
2444
    case 11: /* uge (>=0) */
2406
 
        gen_op_jmp_ns32(flag, l1);
 
2445
        tcg_gen_brcond_i32(TCG_COND_GE, flag, tcg_const_i32(0), l1);
2407
2446
        break;
2408
2447
    case 12: /* ult (=-1 or =2) */
2409
 
        gen_op_jmp_s32(flag, l1);
2410
 
        gen_op_sub32(flag, flag, gen_im32(2));
2411
 
        gen_op_jmp_z32(flag, l1);
 
2448
        tcg_gen_brcond_i32(TCG_COND_GEU, flag, tcg_const_i32(2), l1);
2412
2449
        break;
2413
2450
    case 13: /* ule (!=1) */
2414
 
        gen_op_sub32(flag, flag, gen_im32(1));
2415
 
        gen_op_jmp_nz32(flag, l1);
 
2451
        tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(1), l1);
2416
2452
        break;
2417
2453
    case 14: /* ne (!=0) */
2418
 
        gen_op_jmp_nz32(flag, l1);
 
2454
        tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2419
2455
        break;
2420
2456
    case 15: /* t */
2421
 
        gen_op_mov32(flag, gen_im32(1));
 
2457
        tcg_gen_br(l1);
2422
2458
        break;
2423
2459
    }
2424
2460
    gen_jmp_tb(s, 0, s->pc);
2438
2474
    qemu_assert(0, "FSAVE not implemented");
2439
2475
}
2440
2476
 
2441
 
static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
 
2477
static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
2442
2478
{
2443
 
    int tmp = gen_new_qreg(QMODE_I32);
 
2479
    TCGv tmp = tcg_temp_new();
2444
2480
    if (s->env->macsr & MACSR_FI) {
2445
2481
        if (upper)
2446
 
            gen_op_and32(tmp, val, gen_im32(0xffff0000));
 
2482
            tcg_gen_andi_i32(tmp, val, 0xffff0000);
2447
2483
        else
2448
 
            gen_op_shl32(tmp, val, gen_im32(16));
 
2484
            tcg_gen_shli_i32(tmp, val, 16);
2449
2485
    } else if (s->env->macsr & MACSR_SU) {
2450
2486
        if (upper)
2451
 
            gen_op_sar32(tmp, val, gen_im32(16));
 
2487
            tcg_gen_sari_i32(tmp, val, 16);
2452
2488
        else
2453
 
            gen_op_ext16s32(tmp, val);
 
2489
            tcg_gen_ext16s_i32(tmp, val);
2454
2490
    } else {
2455
2491
        if (upper)
2456
 
            gen_op_shr32(tmp, val, gen_im32(16));
 
2492
            tcg_gen_shri_i32(tmp, val, 16);
2457
2493
        else
2458
 
            gen_op_ext16u32(tmp, val);
 
2494
            tcg_gen_ext16u_i32(tmp, val);
2459
2495
    }
2460
2496
    return tmp;
2461
2497
}
2462
2498
 
 
2499
static void gen_mac_clear_flags(void)
 
2500
{
 
2501
    tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR,
 
2502
                     ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV));
 
2503
}
 
2504
 
2463
2505
DISAS_INSN(mac)
2464
2506
{
2465
 
    int rx;
2466
 
    int ry;
 
2507
    TCGv rx;
 
2508
    TCGv ry;
2467
2509
    uint16_t ext;
2468
2510
    int acc;
2469
 
    int l1;
2470
 
    int tmp;
2471
 
    int addr;
2472
 
    int loadval;
 
2511
    TCGv tmp;
 
2512
    TCGv addr;
 
2513
    TCGv loadval;
2473
2514
    int dual;
2474
 
    int saved_flags = -1;
 
2515
    TCGv saved_flags;
 
2516
 
 
2517
    if (!s->done_mac) {
 
2518
        s->mactmp = tcg_temp_new_i64();
 
2519
        s->done_mac = 1;
 
2520
    }
2475
2521
 
2476
2522
    ext = lduw_code(s->pc);
2477
2523
    s->pc += 2;
2485
2531
    if (insn & 0x30) {
2486
2532
        /* MAC with load.  */
2487
2533
        tmp = gen_lea(s, insn, OS_LONG);
2488
 
        addr = gen_new_qreg(QMODE_I32);
2489
 
        gen_op_and32(addr, tmp, QREG_MAC_MASK);
 
2534
        addr = tcg_temp_new();
 
2535
        tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
2490
2536
        /* Load the value now to ensure correct exception behavior.
2491
2537
           Perform writeback after reading the MAC inputs.  */
2492
2538
        loadval = gen_load(s, OS_LONG, addr, 0);
2495
2541
        rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
2496
2542
        ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
2497
2543
    } else {
2498
 
        loadval = addr = -1;
 
2544
        loadval = addr = NULL_QREG;
2499
2545
        rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2500
2546
        ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2501
2547
    }
2502
2548
 
2503
 
    gen_op_mac_clear_flags();
 
2549
    gen_mac_clear_flags();
 
2550
#if 0
2504
2551
    l1 = -1;
 
2552
    /* Disabled because conditional branches clobber temporary vars.  */
2505
2553
    if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
2506
2554
        /* Skip the multiply if we know we will ignore it.  */
2507
2555
        l1 = gen_new_label();
2508
 
        tmp = gen_new_qreg(QMODE_I32);
2509
 
        gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));
 
2556
        tmp = tcg_temp_new();
 
2557
        tcg_gen_andi_i32(tmp, QREG_MACSR, 1 << (acc + 8));
2510
2558
        gen_op_jmp_nz32(tmp, l1);
2511
2559
    }
 
2560
#endif
2512
2561
 
2513
2562
    if ((ext & 0x0800) == 0) {
2514
2563
        /* Word.  */
2516
2565
        ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2517
2566
    }
2518
2567
    if (s->env->macsr & MACSR_FI) {
2519
 
        gen_op_macmulf(rx, ry);
 
2568
        gen_helper_macmulf(s->mactmp, cpu_env, rx, ry);
2520
2569
    } else {
2521
2570
        if (s->env->macsr & MACSR_SU)
2522
 
            gen_op_macmuls(rx, ry);
 
2571
            gen_helper_macmuls(s->mactmp, cpu_env, rx, ry);
2523
2572
        else
2524
 
            gen_op_macmulu(rx, ry);
 
2573
            gen_helper_macmulu(s->mactmp, cpu_env, rx, ry);
2525
2574
        switch ((ext >> 9) & 3) {
2526
2575
        case 1:
2527
 
            gen_op_macshl();
 
2576
            tcg_gen_shli_i64(s->mactmp, s->mactmp, 1);
2528
2577
            break;
2529
2578
        case 3:
2530
 
            gen_op_macshr();
 
2579
            tcg_gen_shri_i64(s->mactmp, s->mactmp, 1);
2531
2580
            break;
2532
2581
        }
2533
2582
    }
2534
2583
 
2535
2584
    if (dual) {
2536
2585
        /* Save the overflow flag from the multiply.  */
2537
 
        saved_flags = gen_new_qreg(QMODE_I32);
2538
 
        gen_op_mov32(saved_flags, QREG_MACSR);
 
2586
        saved_flags = tcg_temp_new();
 
2587
        tcg_gen_mov_i32(saved_flags, QREG_MACSR);
 
2588
    } else {
 
2589
        saved_flags = NULL_QREG;
2539
2590
    }
2540
2591
 
 
2592
#if 0
 
2593
    /* Disabled because conditional branches clobber temporary vars.  */
2541
2594
    if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2542
2595
        /* Skip the accumulate if the value is already saturated.  */
2543
2596
        l1 = gen_new_label();
2544
 
        tmp = gen_new_qreg(QMODE_I32);
 
2597
        tmp = tcg_temp_new();
2545
2598
        gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2546
2599
        gen_op_jmp_nz32(tmp, l1);
2547
2600
    }
 
2601
#endif
2548
2602
 
2549
2603
    if (insn & 0x100)
2550
 
        gen_op_macsub(acc);
 
2604
        tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2551
2605
    else
2552
 
        gen_op_macadd(acc);
 
2606
        tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2553
2607
 
2554
2608
    if (s->env->macsr & MACSR_FI)
2555
 
        gen_op_macsatf(acc);
 
2609
        gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2556
2610
    else if (s->env->macsr & MACSR_SU)
2557
 
        gen_op_macsats(acc);
 
2611
        gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2558
2612
    else
2559
 
        gen_op_macsatu(acc);
 
2613
        gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2560
2614
 
 
2615
#if 0
 
2616
    /* Disabled because conditional branches clobber temporary vars.  */
2561
2617
    if (l1 != -1)
2562
2618
        gen_set_label(l1);
 
2619
#endif
2563
2620
 
2564
2621
    if (dual) {
2565
2622
        /* Dual accumulate variant.  */
2566
2623
        acc = (ext >> 2) & 3;
2567
2624
        /* Restore the overflow flag from the multiplier.  */
2568
 
        gen_op_mov32(QREG_MACSR, saved_flags);
 
2625
        tcg_gen_mov_i32(QREG_MACSR, saved_flags);
 
2626
#if 0
 
2627
        /* Disabled because conditional branches clobber temporary vars.  */
2569
2628
        if ((s->env->macsr & MACSR_OMC) != 0) {
2570
2629
            /* Skip the accumulate if the value is already saturated.  */
2571
2630
            l1 = gen_new_label();
2572
 
            tmp = gen_new_qreg(QMODE_I32);
 
2631
            tmp = tcg_temp_new();
2573
2632
            gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2574
2633
            gen_op_jmp_nz32(tmp, l1);
2575
2634
        }
 
2635
#endif
2576
2636
        if (ext & 2)
2577
 
            gen_op_macsub(acc);
 
2637
            tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2578
2638
        else
2579
 
            gen_op_macadd(acc);
 
2639
            tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2580
2640
        if (s->env->macsr & MACSR_FI)
2581
 
            gen_op_macsatf(acc);
 
2641
            gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2582
2642
        else if (s->env->macsr & MACSR_SU)
2583
 
            gen_op_macsats(acc);
 
2643
            gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2584
2644
        else
2585
 
            gen_op_macsatu(acc);
 
2645
            gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
 
2646
#if 0
 
2647
        /* Disabled because conditional branches clobber temporary vars.  */
2586
2648
        if (l1 != -1)
2587
2649
            gen_set_label(l1);
 
2650
#endif
2588
2651
    }
2589
 
    gen_op_mac_set_flags(acc);
 
2652
    gen_helper_mac_set_flags(cpu_env, tcg_const_i32(acc));
2590
2653
 
2591
2654
    if (insn & 0x30) {
2592
 
        int rw;
 
2655
        TCGv rw;
2593
2656
        rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2594
 
        gen_op_mov32(rw, loadval);
 
2657
        tcg_gen_mov_i32(rw, loadval);
2595
2658
        /* FIXME: Should address writeback happen with the masked or
2596
2659
           unmasked value?  */
2597
2660
        switch ((insn >> 3) & 7) {
2598
2661
        case 3: /* Post-increment.  */
2599
 
            gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
 
2662
            tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
2600
2663
            break;
2601
2664
        case 4: /* Pre-decrement.  */
2602
 
            gen_op_mov32(AREG(insn, 0), addr);
 
2665
            tcg_gen_mov_i32(AREG(insn, 0), addr);
2603
2666
        }
2604
2667
    }
2605
2668
}
2606
2669
 
2607
2670
DISAS_INSN(from_mac)
2608
2671
{
2609
 
    int rx;
2610
 
    int acc;
 
2672
    TCGv rx;
 
2673
    TCGv_i64 acc;
 
2674
    int accnum;
2611
2675
 
2612
2676
    rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2613
 
    acc = (insn >> 9) & 3;
 
2677
    accnum = (insn >> 9) & 3;
 
2678
    acc = MACREG(accnum);
2614
2679
    if (s->env->macsr & MACSR_FI) {
2615
 
        gen_op_get_macf(rx, acc);
 
2680
        gen_helper_get_macf(rx, cpu_env, acc);
2616
2681
    } else if ((s->env->macsr & MACSR_OMC) == 0) {
2617
 
        gen_op_get_maci(rx, acc);
 
2682
        tcg_gen_trunc_i64_i32(rx, acc);
2618
2683
    } else if (s->env->macsr & MACSR_SU) {
2619
 
        gen_op_get_macs(rx, acc);
 
2684
        gen_helper_get_macs(rx, acc);
2620
2685
    } else {
2621
 
        gen_op_get_macu(rx, acc);
2622
 
    }
2623
 
    if (insn & 0x40)
2624
 
        gen_op_clear_mac(acc);
 
2686
        gen_helper_get_macu(rx, acc);
 
2687
    }
 
2688
    if (insn & 0x40) {
 
2689
        tcg_gen_movi_i64(acc, 0);
 
2690
        tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
 
2691
    }
2625
2692
}
2626
2693
 
2627
2694
DISAS_INSN(move_mac)
2628
2695
{
 
2696
    /* FIXME: This can be done without a helper.  */
2629
2697
    int src;
2630
 
    int dest;
 
2698
    TCGv dest;
2631
2699
    src = insn & 3;
2632
 
    dest = (insn >> 9) & 3;
2633
 
    gen_op_move_mac(dest, src);
2634
 
    gen_op_mac_clear_flags();
2635
 
    gen_op_mac_set_flags(dest);
 
2700
    dest = tcg_const_i32((insn >> 9) & 3);
 
2701
    gen_helper_mac_move(cpu_env, dest, tcg_const_i32(src));
 
2702
    gen_mac_clear_flags();
 
2703
    gen_helper_mac_set_flags(cpu_env, dest);
2636
2704
}
2637
2705
 
2638
2706
DISAS_INSN(from_macsr)
2639
2707
{
2640
 
    int reg;
 
2708
    TCGv reg;
2641
2709
 
2642
2710
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2643
 
    gen_op_mov32(reg, QREG_MACSR);
 
2711
    tcg_gen_mov_i32(reg, QREG_MACSR);
2644
2712
}
2645
2713
 
2646
2714
DISAS_INSN(from_mask)
2647
2715
{
2648
 
    int reg;
 
2716
    TCGv reg;
2649
2717
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2650
 
    gen_op_mov32(reg, QREG_MAC_MASK);
 
2718
    tcg_gen_mov_i32(reg, QREG_MAC_MASK);
2651
2719
}
2652
2720
 
2653
2721
DISAS_INSN(from_mext)
2654
2722
{
2655
 
    int reg;
2656
 
    int acc;
 
2723
    TCGv reg;
 
2724
    TCGv acc;
2657
2725
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2658
 
    acc = (insn & 0x400) ? 2 : 0;
 
2726
    acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2659
2727
    if (s->env->macsr & MACSR_FI)
2660
 
        gen_op_get_mac_extf(reg, acc);
 
2728
        gen_helper_get_mac_extf(reg, cpu_env, acc);
2661
2729
    else
2662
 
        gen_op_get_mac_exti(reg, acc);
 
2730
        gen_helper_get_mac_exti(reg, cpu_env, acc);
2663
2731
}
2664
2732
 
2665
2733
DISAS_INSN(macsr_to_ccr)
2666
2734
{
2667
 
    gen_op_mov32(QREG_CC_X, gen_im32(0));
2668
 
    gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
 
2735
    tcg_gen_movi_i32(QREG_CC_X, 0);
 
2736
    tcg_gen_andi_i32(QREG_CC_DEST, QREG_MACSR, 0xf);
2669
2737
    s->cc_op = CC_OP_FLAGS;
2670
2738
}
2671
2739
 
2672
2740
DISAS_INSN(to_mac)
2673
2741
{
2674
 
    int acc;
2675
 
    int val;
2676
 
    acc = (insn >>9) & 3;
 
2742
    TCGv_i64 acc;
 
2743
    TCGv val;
 
2744
    int accnum;
 
2745
    accnum = (insn >> 9) & 3;
 
2746
    acc = MACREG(accnum);
2677
2747
    SRC_EA(val, OS_LONG, 0, NULL);
2678
2748
    if (s->env->macsr & MACSR_FI) {
2679
 
        gen_op_set_macf(val, acc);
 
2749
        tcg_gen_ext_i32_i64(acc, val);
 
2750
        tcg_gen_shli_i64(acc, acc, 8);
2680
2751
    } else if (s->env->macsr & MACSR_SU) {
2681
 
        gen_op_set_macs(val, acc);
 
2752
        tcg_gen_ext_i32_i64(acc, val);
2682
2753
    } else {
2683
 
        gen_op_set_macu(val, acc);
 
2754
        tcg_gen_extu_i32_i64(acc, val);
2684
2755
    }
2685
 
    gen_op_mac_clear_flags();
2686
 
    gen_op_mac_set_flags(acc);
 
2756
    tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
 
2757
    gen_mac_clear_flags();
 
2758
    gen_helper_mac_set_flags(cpu_env, tcg_const_i32(accnum));
2687
2759
}
2688
2760
 
2689
2761
DISAS_INSN(to_macsr)
2690
2762
{
2691
 
    int val;
 
2763
    TCGv val;
2692
2764
    SRC_EA(val, OS_LONG, 0, NULL);
2693
 
    gen_op_set_macsr(val);
 
2765
    gen_helper_set_macsr(cpu_env, val);
2694
2766
    gen_lookup_tb(s);
2695
2767
}
2696
2768
 
2697
2769
DISAS_INSN(to_mask)
2698
2770
{
2699
 
    int val;
 
2771
    TCGv val;
2700
2772
    SRC_EA(val, OS_LONG, 0, NULL);
2701
 
    gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
 
2773
    tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
2702
2774
}
2703
2775
 
2704
2776
DISAS_INSN(to_mext)
2705
2777
{
2706
 
    int val;
2707
 
    int acc;
 
2778
    TCGv val;
 
2779
    TCGv acc;
2708
2780
    SRC_EA(val, OS_LONG, 0, NULL);
2709
 
    acc = (insn & 0x400) ? 2 : 0;
 
2781
    acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2710
2782
    if (s->env->macsr & MACSR_FI)
2711
 
        gen_op_set_mac_extf(val, acc);
 
2783
        gen_helper_set_mac_extf(cpu_env, val, acc);
2712
2784
    else if (s->env->macsr & MACSR_SU)
2713
 
        gen_op_set_mac_exts(val, acc);
 
2785
        gen_helper_set_mac_exts(cpu_env, val, acc);
2714
2786
    else
2715
 
        gen_op_set_mac_extu(val, acc);
 
2787
        gen_helper_set_mac_extu(cpu_env, val, acc);
2716
2788
}
2717
2789
 
2718
2790
static disas_proc opcode_table[65536];
2888
2960
    opcode_table[insn](s, insn);
2889
2961
}
2890
2962
 
2891
 
#if 0
2892
 
/* Save the result of a floating point operation.  */
2893
 
static void expand_op_fp_result(qOP *qop)
2894
 
{
2895
 
    gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2896
 
}
2897
 
 
2898
 
/* Dummy op to indicate that the flags have been set.  */
2899
 
static void expand_op_flags_set(qOP *qop)
2900
 
{
2901
 
}
2902
 
 
2903
 
/* Convert the confition codes into CC_OP_FLAGS format.  */
2904
 
static void expand_op_flush_flags(qOP *qop)
2905
 
{
2906
 
    int cc_opreg;
2907
 
 
2908
 
    if (qop->args[0] == CC_OP_DYNAMIC)
2909
 
        cc_opreg = QREG_CC_OP;
2910
 
    else
2911
 
        cc_opreg = gen_im32(qop->args[0]);
2912
 
    gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2913
 
}
2914
 
 
2915
 
/* Set CC_DEST after a logical or direct flag setting operation.  */
2916
 
static void expand_op_logic_cc(qOP *qop)
2917
 
{
2918
 
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2919
 
}
2920
 
 
2921
 
/* Set CC_SRC and CC_DEST after an arithmetic operation.  */
2922
 
static void expand_op_update_cc_add(qOP *qop)
2923
 
{
2924
 
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2925
 
    gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2926
 
}
2927
 
 
2928
 
/* Update the X flag.  */
2929
 
static void expand_op_update_xflag(qOP *qop)
2930
 
{
2931
 
    int arg0;
2932
 
    int arg1;
2933
 
 
2934
 
    arg0 = qop->args[0];
2935
 
    arg1 = qop->args[1];
2936
 
    if (arg1 == QREG_NULL) {
2937
 
        /* CC_X = arg0.  */
2938
 
        gen_op_mov32(QREG_CC_X, arg0);
2939
 
    } else {
2940
 
        /* CC_X = arg0 < (unsigned)arg1.  */
2941
 
        gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2942
 
    }
2943
 
}
2944
 
 
2945
 
/* Set arg0 to the contents of the X flag.  */
2946
 
static void expand_op_get_xflag(qOP *qop)
2947
 
{
2948
 
    gen_op_mov32(qop->args[0], QREG_CC_X);
2949
 
}
2950
 
 
2951
 
/* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
2952
 
   already know the shift is within range.  */
2953
 
static inline void expand_shift_im(qOP *qop, int right, int arith)
2954
 
{
2955
 
    int val;
2956
 
    int reg;
2957
 
    int tmp;
2958
 
    int im;
2959
 
 
2960
 
    reg = qop->args[0];
2961
 
    im = qop->args[1];
2962
 
    tmp = gen_im32(im);
2963
 
    val = gen_new_qreg(QMODE_I32);
2964
 
    gen_op_mov32(val, reg);
2965
 
    gen_op_mov32(QREG_CC_DEST, val);
2966
 
    gen_op_mov32(QREG_CC_SRC, tmp);
2967
 
    if (right) {
2968
 
        if (arith) {
2969
 
            gen_op_sar32(reg, val, tmp);
2970
 
        } else {
2971
 
            gen_op_shr32(reg, val, tmp);
2972
 
        }
2973
 
        if (im == 1)
2974
 
            tmp = QREG_NULL;
2975
 
        else
2976
 
            tmp = gen_im32(im - 1);
2977
 
    } else {
2978
 
        gen_op_shl32(reg, val, tmp);
2979
 
        tmp = gen_im32(32 - im);
2980
 
    }
2981
 
    if (tmp != QREG_NULL)
2982
 
        gen_op_shr32(val, val, tmp);
2983
 
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
2984
 
}
2985
 
 
2986
 
static void expand_op_shl_im_cc(qOP *qop)
2987
 
{
2988
 
    expand_shift_im(qop, 0, 0);
2989
 
}
2990
 
 
2991
 
static void expand_op_shr_im_cc(qOP *qop)
2992
 
{
2993
 
    expand_shift_im(qop, 1, 0);
2994
 
}
2995
 
 
2996
 
static void expand_op_sar_im_cc(qOP *qop)
2997
 
{
2998
 
    expand_shift_im(qop, 1, 1);
2999
 
}
3000
 
 
3001
 
/* Expand a shift by register.  */
3002
 
/* ??? This gives incorrect answers for shifts by 0 or >= 32 */
3003
 
static inline void expand_shift_reg(qOP *qop, int right, int arith)
3004
 
{
3005
 
    int val;
3006
 
    int reg;
3007
 
    int shift;
3008
 
    int tmp;
3009
 
 
3010
 
    reg = qop->args[0];
3011
 
    shift = qop->args[1];
3012
 
    val = gen_new_qreg(QMODE_I32);
3013
 
    gen_op_mov32(val, reg);
3014
 
    gen_op_mov32(QREG_CC_DEST, val);
3015
 
    gen_op_mov32(QREG_CC_SRC, shift);
3016
 
    tmp = gen_new_qreg(QMODE_I32);
3017
 
    if (right) {
3018
 
        if (arith) {
3019
 
            gen_op_sar32(reg, val, shift);
3020
 
        } else {
3021
 
            gen_op_shr32(reg, val, shift);
3022
 
        }
3023
 
        gen_op_sub32(tmp, shift, gen_im32(1));
3024
 
    } else {
3025
 
        gen_op_shl32(reg, val, shift);
3026
 
        gen_op_sub32(tmp, gen_im32(31), shift);
3027
 
    }
3028
 
    gen_op_shl32(val, val, tmp);
3029
 
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
3030
 
}
3031
 
 
3032
 
static void expand_op_shl_cc(qOP *qop)
3033
 
{
3034
 
    expand_shift_reg(qop, 0, 0);
3035
 
}
3036
 
 
3037
 
static void expand_op_shr_cc(qOP *qop)
3038
 
{
3039
 
    expand_shift_reg(qop, 1, 0);
3040
 
}
3041
 
 
3042
 
static void expand_op_sar_cc(qOP *qop)
3043
 
{
3044
 
    expand_shift_reg(qop, 1, 1);
3045
 
}
3046
 
 
3047
 
/* Set the Z flag to (arg0 & arg1) == 0.  */
3048
 
static void expand_op_btest(qOP *qop)
3049
 
{
3050
 
    int tmp;
3051
 
    int l1;
3052
 
 
3053
 
    l1 = gen_new_label();
3054
 
    tmp = gen_new_qreg(QMODE_I32);
3055
 
    gen_op_and32(tmp, qop->args[0], qop->args[1]);
3056
 
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
3057
 
    gen_op_jmp_nz32(tmp, l1);
3058
 
    gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
3059
 
    gen_op_label(l1);
3060
 
}
3061
 
 
3062
 
/* arg0 += arg1 + CC_X */
3063
 
static void expand_op_addx_cc(qOP *qop)
3064
 
{
3065
 
    int arg0 = qop->args[0];
3066
 
    int arg1 = qop->args[1];
3067
 
    int l1, l2;
3068
 
 
3069
 
    gen_op_add32 (arg0, arg0, arg1);
3070
 
    l1 = gen_new_label();
3071
 
    l2 = gen_new_label();
3072
 
    gen_op_jmp_z32(QREG_CC_X, l1);
3073
 
    gen_op_add32(arg0, arg0, gen_im32(1));
3074
 
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
3075
 
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3076
 
    gen_op_jmp(l2);
3077
 
    gen_set_label(l1);
3078
 
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
3079
 
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3080
 
    gen_set_label(l2);
3081
 
}
3082
 
 
3083
 
/* arg0 -= arg1 + CC_X */
3084
 
static void expand_op_subx_cc(qOP *qop)
3085
 
{
3086
 
    int arg0 = qop->args[0];
3087
 
    int arg1 = qop->args[1];
3088
 
    int l1, l2;
3089
 
 
3090
 
    l1 = gen_new_label();
3091
 
    l2 = gen_new_label();
3092
 
    gen_op_jmp_z32(QREG_CC_X, l1);
3093
 
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3094
 
    gen_op_sub32(arg0, arg0, gen_im32(1));
3095
 
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
3096
 
    gen_op_jmp(l2);
3097
 
    gen_set_label(l1);
3098
 
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3099
 
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
3100
 
    gen_set_label(l2);
3101
 
    gen_op_sub32 (arg0, arg0, arg1);
3102
 
}
3103
 
 
3104
 
/* Expand target specific ops to generic qops.  */
3105
 
static void expand_target_qops(void)
3106
 
{
3107
 
    qOP *qop;
3108
 
    qOP *next;
3109
 
    int c;
3110
 
 
3111
 
    /* Copy the list of qops, expanding target specific ops as we go.  */
3112
 
    qop = gen_first_qop;
3113
 
    gen_first_qop = NULL;
3114
 
    gen_last_qop = NULL;
3115
 
    for (; qop; qop = next) {
3116
 
        c = qop->opcode;
3117
 
        next = qop->next;
3118
 
        if (c < FIRST_TARGET_OP) {
3119
 
            qop->prev = gen_last_qop;
3120
 
            qop->next = NULL;
3121
 
            if (gen_last_qop)
3122
 
                gen_last_qop->next = qop;
3123
 
            else
3124
 
                gen_first_qop = qop;
3125
 
            gen_last_qop = qop;
3126
 
            continue;
3127
 
        }
3128
 
        switch (c) {
3129
 
#define DEF(name, nargs, barrier) \
3130
 
        case INDEX_op_##name: \
3131
 
            expand_op_##name(qop); \
3132
 
            break;
3133
 
#include "qop-target.def"
3134
 
#undef DEF
3135
 
        default:
3136
 
            cpu_abort(NULL, "Unexpanded target qop");
3137
 
        }
3138
 
    }
3139
 
}
3140
 
 
3141
 
/* ??? Implement this.  */
3142
 
static void
3143
 
optimize_flags(void)
3144
 
{
3145
 
}
3146
 
#endif
3147
 
 
3148
2963
/* generate intermediate code for basic block 'tb'.  */
3149
 
static inline int
 
2964
static inline void
3150
2965
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3151
2966
                               int search_pc)
3152
2967
{
3153
2968
    DisasContext dc1, *dc = &dc1;
3154
2969
    uint16_t *gen_opc_end;
 
2970
    CPUBreakpoint *bp;
3155
2971
    int j, lj;
3156
2972
    target_ulong pc_start;
3157
2973
    int pc_offset;
3158
2974
    int last_cc_op;
 
2975
    int num_insns;
 
2976
    int max_insns;
3159
2977
 
3160
2978
    /* generate intermediate code */
3161
2979
    pc_start = tb->pc;
3162
2980
 
3163
2981
    dc->tb = tb;
3164
2982
 
3165
 
    gen_opc_ptr = gen_opc_buf;
3166
2983
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3167
 
    gen_opparam_ptr = gen_opparam_buf;
3168
2984
 
3169
2985
    dc->env = env;
3170
2986
    dc->is_jmp = DISAS_NEXT;
3174
2990
    dc->fpcr = env->fpcr;
3175
2991
    dc->user = (env->sr & SR_S) == 0;
3176
2992
    dc->is_mem = 0;
3177
 
    nb_gen_labels = 0;
 
2993
    dc->done_mac = 0;
3178
2994
    lj = -1;
 
2995
    num_insns = 0;
 
2996
    max_insns = tb->cflags & CF_COUNT_MASK;
 
2997
    if (max_insns == 0)
 
2998
        max_insns = CF_COUNT_MASK;
 
2999
 
 
3000
    gen_icount_start();
3179
3001
    do {
3180
 
        free_qreg = 0;
3181
3002
        pc_offset = dc->pc - pc_start;
3182
3003
        gen_throws_exception = NULL;
3183
 
        if (env->nb_breakpoints > 0) {
3184
 
            for(j = 0; j < env->nb_breakpoints; j++) {
3185
 
                if (env->breakpoints[j] == dc->pc) {
 
3004
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
 
3005
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
 
3006
                if (bp->pc == dc->pc) {
3186
3007
                    gen_exception(dc, dc->pc, EXCP_DEBUG);
3187
3008
                    dc->is_jmp = DISAS_JUMP;
3188
3009
                    break;
3200
3021
            }
3201
3022
            gen_opc_pc[lj] = dc->pc;
3202
3023
            gen_opc_instr_start[lj] = 1;
 
3024
            gen_opc_icount[lj] = num_insns;
3203
3025
        }
 
3026
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
 
3027
            gen_io_start();
3204
3028
        last_cc_op = dc->cc_op;
3205
3029
        dc->insn_pc = dc->pc;
3206
3030
        disas_m68k_insn(env, dc);
3207
 
 
3208
 
        /* Terminate the TB on memory ops if watchpoints are present.  */
3209
 
        /* FIXME: This should be replacd by the deterministic execution
3210
 
         * IRQ raising bits.  */
3211
 
        if (dc->is_mem && env->nb_watchpoints)
3212
 
            break;
 
3031
        num_insns++;
3213
3032
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3214
3033
             !env->singlestep_enabled &&
3215
 
             (pc_offset) < (TARGET_PAGE_SIZE - 32));
 
3034
             (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
 
3035
             num_insns < max_insns);
3216
3036
 
3217
 
    if (__builtin_expect(env->singlestep_enabled, 0)) {
 
3037
    if (tb->cflags & CF_LAST_IO)
 
3038
        gen_io_end();
 
3039
    if (unlikely(env->singlestep_enabled)) {
3218
3040
        /* Make sure the pc is updated, and raise a debug exception.  */
3219
3041
        if (!dc->is_jmp) {
3220
3042
            gen_flush_cc_op(dc);
3221
 
            gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
 
3043
            tcg_gen_movi_i32(QREG_PC, dc->pc);
3222
3044
        }
3223
 
        gen_op_raise_exception(EXCP_DEBUG);
 
3045
        gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG));
3224
3046
    } else {
3225
3047
        switch(dc->is_jmp) {
3226
3048
        case DISAS_NEXT:
3232
3054
        case DISAS_UPDATE:
3233
3055
            gen_flush_cc_op(dc);
3234
3056
            /* indicate that the hash table must be used to find the next TB */
3235
 
            gen_op_mov32(QREG_T0, gen_im32(0));
3236
 
            gen_op_exit_tb();
 
3057
            tcg_gen_exit_tb(0);
3237
3058
            break;
3238
3059
        case DISAS_TB_JUMP:
3239
3060
            /* nothing more to generate */
3240
3061
            break;
3241
3062
        }
3242
3063
    }
 
3064
    gen_icount_end(tb, num_insns);
3243
3065
    *gen_opc_ptr = INDEX_op_end;
3244
3066
 
3245
3067
#ifdef DEBUG_DISAS
3246
 
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3247
 
        fprintf(logfile, "----------------\n");
3248
 
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3249
 
        target_disas(logfile, pc_start, dc->pc - pc_start, 0);
3250
 
        fprintf(logfile, "\n");
3251
 
        if (loglevel & (CPU_LOG_TB_OP)) {
3252
 
            fprintf(logfile, "OP:\n");
3253
 
            dump_ops(gen_opc_buf, gen_opparam_buf);
3254
 
            fprintf(logfile, "\n");
3255
 
        }
 
3068
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 
3069
        qemu_log("----------------\n");
 
3070
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
 
3071
        log_target_disas(pc_start, dc->pc - pc_start, 0);
 
3072
        qemu_log("\n");
3256
3073
    }
3257
3074
#endif
3258
3075
    if (search_pc) {
3262
3079
            gen_opc_instr_start[lj++] = 0;
3263
3080
    } else {
3264
3081
        tb->size = dc->pc - pc_start;
 
3082
        tb->icount = num_insns;
3265
3083
    }
3266
3084
 
3267
3085
    //optimize_flags();
3268
3086
    //expand_target_qops();
3269
 
    return 0;
3270
 
}
3271
 
 
3272
 
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
3273
 
{
3274
 
    return gen_intermediate_code_internal(env, tb, 0);
3275
 
}
3276
 
 
3277
 
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
3278
 
{
3279
 
    return gen_intermediate_code_internal(env, tb, 1);
 
3087
}
 
3088
 
 
3089
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
 
3090
{
 
3091
    gen_intermediate_code_internal(env, tb, 0);
 
3092
}
 
3093
 
 
3094
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
 
3095
{
 
3096
    gen_intermediate_code_internal(env, tb, 1);
3280
3097
}
3281
3098
 
3282
3099
void cpu_dump_state(CPUState *env, FILE *f,
3301
3118
    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
3302
3119
}
3303
3120
 
 
3121
void gen_pc_load(CPUState *env, TranslationBlock *tb,
 
3122
                unsigned long searched_pc, int pc_pos, void *puc)
 
3123
{
 
3124
    env->pc = gen_opc_pc[pc_pos];
 
3125
}