~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to target-arm/translate.c

  • Committer: ths
  • Date: 2007-05-05 19:24:38 UTC
  • Revision ID: git-v1:608e8ce280cee231b3de0e7922060efd23447a54
Linker scripts for MIPS hosts.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2772 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  ARM translation
3
 
 *
 
3
 * 
4
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 
 *  Copyright (c) 2005-2007 CodeSourcery
 
5
 *  Copyright (c) 2005 CodeSourcery, LLC
6
6
 *  Copyright (c) 2007 OpenedHand, Ltd.
7
7
 *
8
8
 * This library is free software; you can redistribute it and/or
28
28
#include "cpu.h"
29
29
#include "exec-all.h"
30
30
#include "disas.h"
31
 
#include "tcg-op.h"
32
 
#include "qemu-log.h"
33
 
 
34
 
#define GEN_HELPER 1
35
 
#include "helpers.h"
36
 
 
37
 
#define ENABLE_ARCH_5J    0
38
 
#define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
39
 
#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
40
 
#define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
41
 
#define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
42
 
 
43
 
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
 
31
 
 
32
#define ENABLE_ARCH_5J  0
 
33
#define ENABLE_ARCH_6   1
 
34
#define ENABLE_ARCH_6T2 1
 
35
 
 
36
#define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
44
37
 
45
38
/* internal defines */
46
39
typedef struct DisasContext {
50
43
    int condjmp;
51
44
    /* The label that will be jumped to when the instruction is skipped.  */
52
45
    int condlabel;
53
 
    /* Thumb-2 condtional execution bits.  */
54
 
    int condexec_mask;
55
 
    int condexec_cond;
56
46
    struct TranslationBlock *tb;
57
47
    int singlestep_enabled;
58
48
    int thumb;
68
58
#define IS_USER(s) (s->user)
69
59
#endif
70
60
 
71
 
/* These instructions trap after executing, so defer them until after the
72
 
   conditional executions state has been updated.  */
73
 
#define DISAS_WFI 4
74
 
#define DISAS_SWI 5
75
 
 
76
 
static TCGv cpu_env;
77
 
/* We reuse the same 64-bit temporaries for efficiency.  */
78
 
static TCGv cpu_V0, cpu_V1, cpu_M0;
79
 
 
80
 
/* FIXME:  These should be removed.  */
81
 
static TCGv cpu_T[2];
82
 
static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
83
 
 
84
 
#define ICOUNT_TEMP cpu_T[0]
85
 
#include "gen-icount.h"
86
 
 
87
 
/* initialize TCG globals.  */
88
 
void arm_translate_init(void)
89
 
{
90
 
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
91
 
 
92
 
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
93
 
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
94
 
}
95
 
 
96
 
/* The code generator doesn't like lots of temporaries, so maintain our own
97
 
   cache for reuse within a function.  */
98
 
#define MAX_TEMPS 8
99
 
static int num_temps;
100
 
static TCGv temps[MAX_TEMPS];
101
 
 
102
 
/* Allocate a temporary variable.  */
103
 
static TCGv new_tmp(void)
104
 
{
105
 
    TCGv tmp;
106
 
    if (num_temps == MAX_TEMPS)
107
 
        abort();
108
 
 
109
 
    if (GET_TCGV(temps[num_temps]))
110
 
      return temps[num_temps++];
111
 
 
112
 
    tmp = tcg_temp_new(TCG_TYPE_I32);
113
 
    temps[num_temps++] = tmp;
114
 
    return tmp;
115
 
}
116
 
 
117
 
/* Release a temporary variable.  */
118
 
static void dead_tmp(TCGv tmp)
119
 
{
120
 
    int i;
121
 
    num_temps--;
122
 
    i = num_temps;
123
 
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
124
 
        return;
125
 
 
126
 
    /* Shuffle this temp to the last slot.  */
127
 
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
128
 
        i--;
129
 
    while (i < num_temps) {
130
 
        temps[i] = temps[i + 1];
131
 
        i++;
132
 
    }
133
 
    temps[i] = tmp;
134
 
}
135
 
 
136
 
static inline TCGv load_cpu_offset(int offset)
137
 
{
138
 
    TCGv tmp = new_tmp();
139
 
    tcg_gen_ld_i32(tmp, cpu_env, offset);
140
 
    return tmp;
141
 
}
142
 
 
143
 
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
144
 
 
145
 
static inline void store_cpu_offset(TCGv var, int offset)
146
 
{
147
 
    tcg_gen_st_i32(var, cpu_env, offset);
148
 
    dead_tmp(var);
149
 
}
150
 
 
151
 
#define store_cpu_field(var, name) \
152
 
    store_cpu_offset(var, offsetof(CPUState, name))
153
 
 
154
 
/* Set a variable to the value of a CPU register.  */
155
 
static void load_reg_var(DisasContext *s, TCGv var, int reg)
156
 
{
157
 
    if (reg == 15) {
158
 
        uint32_t addr;
159
 
        /* normaly, since we updated PC, we need only to add one insn */
160
 
        if (s->thumb)
161
 
            addr = (long)s->pc + 2;
162
 
        else
163
 
            addr = (long)s->pc + 4;
164
 
        tcg_gen_movi_i32(var, addr);
165
 
    } else {
166
 
        tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
167
 
    }
168
 
}
169
 
 
170
 
/* Create a new temporary and set it to the value of a CPU register.  */
171
 
static inline TCGv load_reg(DisasContext *s, int reg)
172
 
{
173
 
    TCGv tmp = new_tmp();
174
 
    load_reg_var(s, tmp, reg);
175
 
    return tmp;
176
 
}
177
 
 
178
 
/* Set a CPU register.  The source must be a temporary and will be
179
 
   marked as dead.  */
180
 
static void store_reg(DisasContext *s, int reg, TCGv var)
181
 
{
182
 
    if (reg == 15) {
183
 
        tcg_gen_andi_i32(var, var, ~1);
184
 
        s->is_jmp = DISAS_JUMP;
185
 
    }
186
 
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
187
 
    dead_tmp(var);
188
 
}
189
 
 
190
 
 
191
 
/* Basic operations.  */
192
 
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
193
 
#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
194
 
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
195
 
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
196
 
 
197
 
#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
198
 
#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
199
 
#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
200
 
#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
201
 
 
202
 
#define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
203
 
#define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
204
 
#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
205
 
#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206
 
#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
207
 
#define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
208
 
 
209
 
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
210
 
#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
211
 
#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
212
 
#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
213
 
#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
214
 
#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
215
 
#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
216
 
 
217
 
#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
218
 
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219
 
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220
 
#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
221
 
#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
222
 
 
223
 
/* Value extensions.  */
224
 
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
225
 
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
226
 
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227
 
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
228
 
 
229
 
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
230
 
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
231
 
 
232
 
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
233
 
 
234
 
#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
235
 
/* Set NZCV flags from the high 4 bits of var.  */
236
 
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
237
 
 
238
 
static void gen_exception(int excp)
239
 
{
240
 
    TCGv tmp = new_tmp();
241
 
    tcg_gen_movi_i32(tmp, excp);
242
 
    gen_helper_exception(tmp);
243
 
    dead_tmp(tmp);
244
 
}
245
 
 
246
 
static void gen_smul_dual(TCGv a, TCGv b)
247
 
{
248
 
    TCGv tmp1 = new_tmp();
249
 
    TCGv tmp2 = new_tmp();
250
 
    tcg_gen_ext16s_i32(tmp1, a);
251
 
    tcg_gen_ext16s_i32(tmp2, b);
252
 
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
253
 
    dead_tmp(tmp2);
254
 
    tcg_gen_sari_i32(a, a, 16);
255
 
    tcg_gen_sari_i32(b, b, 16);
256
 
    tcg_gen_mul_i32(b, b, a);
257
 
    tcg_gen_mov_i32(a, tmp1);
258
 
    dead_tmp(tmp1);
259
 
}
260
 
 
261
 
/* Byteswap each halfword.  */
262
 
static void gen_rev16(TCGv var)
263
 
{
264
 
    TCGv tmp = new_tmp();
265
 
    tcg_gen_shri_i32(tmp, var, 8);
266
 
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
267
 
    tcg_gen_shli_i32(var, var, 8);
268
 
    tcg_gen_andi_i32(var, var, 0xff00ff00);
269
 
    tcg_gen_or_i32(var, var, tmp);
270
 
    dead_tmp(tmp);
271
 
}
272
 
 
273
 
/* Byteswap low halfword and sign extend.  */
274
 
static void gen_revsh(TCGv var)
275
 
{
276
 
    TCGv tmp = new_tmp();
277
 
    tcg_gen_shri_i32(tmp, var, 8);
278
 
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
279
 
    tcg_gen_shli_i32(var, var, 8);
280
 
    tcg_gen_ext8s_i32(var, var);
281
 
    tcg_gen_or_i32(var, var, tmp);
282
 
    dead_tmp(tmp);
283
 
}
284
 
 
285
 
/* Unsigned bitfield extract.  */
286
 
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
287
 
{
288
 
    if (shift)
289
 
        tcg_gen_shri_i32(var, var, shift);
290
 
    tcg_gen_andi_i32(var, var, mask);
291
 
}
292
 
 
293
 
/* Signed bitfield extract.  */
294
 
static void gen_sbfx(TCGv var, int shift, int width)
295
 
{
296
 
    uint32_t signbit;
297
 
 
298
 
    if (shift)
299
 
        tcg_gen_sari_i32(var, var, shift);
300
 
    if (shift + width < 32) {
301
 
        signbit = 1u << (width - 1);
302
 
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
303
 
        tcg_gen_xori_i32(var, var, signbit);
304
 
        tcg_gen_subi_i32(var, var, signbit);
305
 
    }
306
 
}
307
 
 
308
 
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
309
 
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
310
 
{
311
 
    tcg_gen_andi_i32(val, val, mask);
312
 
    tcg_gen_shli_i32(val, val, shift);
313
 
    tcg_gen_andi_i32(base, base, ~(mask << shift));
314
 
    tcg_gen_or_i32(dest, base, val);
315
 
}
316
 
 
317
 
/* Round the top 32 bits of a 64-bit value.  */
318
 
static void gen_roundqd(TCGv a, TCGv b)
319
 
{
320
 
    tcg_gen_shri_i32(a, a, 31);
321
 
    tcg_gen_add_i32(a, a, b);
322
 
}
323
 
 
324
 
/* FIXME: Most targets have native widening multiplication.
325
 
   It would be good to use that instead of a full wide multiply.  */
326
 
/* 32x32->64 multiply.  Marks inputs as dead.  */
327
 
static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
328
 
{
329
 
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
330
 
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
331
 
 
332
 
    tcg_gen_extu_i32_i64(tmp1, a);
333
 
    dead_tmp(a);
334
 
    tcg_gen_extu_i32_i64(tmp2, b);
335
 
    dead_tmp(b);
336
 
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
337
 
    return tmp1;
338
 
}
339
 
 
340
 
static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
341
 
{
342
 
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
343
 
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
344
 
 
345
 
    tcg_gen_ext_i32_i64(tmp1, a);
346
 
    dead_tmp(a);
347
 
    tcg_gen_ext_i32_i64(tmp2, b);
348
 
    dead_tmp(b);
349
 
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
350
 
    return tmp1;
351
 
}
352
 
 
353
 
/* Unsigned 32x32->64 multiply.  */
354
 
static void gen_op_mull_T0_T1(void)
355
 
{
356
 
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
357
 
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
358
 
 
359
 
    tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
360
 
    tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
361
 
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
362
 
    tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
363
 
    tcg_gen_shri_i64(tmp1, tmp1, 32);
364
 
    tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
365
 
}
366
 
 
367
 
/* Signed 32x32->64 multiply.  */
368
 
static void gen_imull(TCGv a, TCGv b)
369
 
{
370
 
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
371
 
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
372
 
 
373
 
    tcg_gen_ext_i32_i64(tmp1, a);
374
 
    tcg_gen_ext_i32_i64(tmp2, b);
375
 
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
376
 
    tcg_gen_trunc_i64_i32(a, tmp1);
377
 
    tcg_gen_shri_i64(tmp1, tmp1, 32);
378
 
    tcg_gen_trunc_i64_i32(b, tmp1);
379
 
}
380
 
#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
381
 
 
382
 
/* Swap low and high halfwords.  */
383
 
static void gen_swap_half(TCGv var)
384
 
{
385
 
    TCGv tmp = new_tmp();
386
 
    tcg_gen_shri_i32(tmp, var, 16);
387
 
    tcg_gen_shli_i32(var, var, 16);
388
 
    tcg_gen_or_i32(var, var, tmp);
389
 
    dead_tmp(tmp);
390
 
}
391
 
 
392
 
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
393
 
    tmp = (t0 ^ t1) & 0x8000;
394
 
    t0 &= ~0x8000;
395
 
    t1 &= ~0x8000;
396
 
    t0 = (t0 + t1) ^ tmp;
397
 
 */
398
 
 
399
 
static void gen_add16(TCGv t0, TCGv t1)
400
 
{
401
 
    TCGv tmp = new_tmp();
402
 
    tcg_gen_xor_i32(tmp, t0, t1);
403
 
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
404
 
    tcg_gen_andi_i32(t0, t0, ~0x8000);
405
 
    tcg_gen_andi_i32(t1, t1, ~0x8000);
406
 
    tcg_gen_add_i32(t0, t0, t1);
407
 
    tcg_gen_xor_i32(t0, t0, tmp);
408
 
    dead_tmp(tmp);
409
 
    dead_tmp(t1);
410
 
}
411
 
 
412
 
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
413
 
 
414
 
/* Set CF to the top bit of var.  */
415
 
static void gen_set_CF_bit31(TCGv var)
416
 
{
417
 
    TCGv tmp = new_tmp();
418
 
    tcg_gen_shri_i32(tmp, var, 31);
419
 
    gen_set_CF(var);
420
 
    dead_tmp(tmp);
421
 
}
422
 
 
423
 
/* Set N and Z flags from var.  */
424
 
static inline void gen_logic_CC(TCGv var)
425
 
{
426
 
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
427
 
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
428
 
}
429
 
 
430
 
/* T0 += T1 + CF.  */
431
 
static void gen_adc_T0_T1(void)
432
 
{
433
 
    TCGv tmp;
434
 
    gen_op_addl_T0_T1();
435
 
    tmp = load_cpu_field(CF);
436
 
    tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
437
 
    dead_tmp(tmp);
438
 
}
439
 
 
440
 
/* dest = T0 - T1 + CF - 1.  */
441
 
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
442
 
{
443
 
    TCGv tmp;
444
 
    tcg_gen_sub_i32(dest, t0, t1);
445
 
    tmp = load_cpu_field(CF);
446
 
    tcg_gen_add_i32(dest, dest, tmp);
447
 
    tcg_gen_subi_i32(dest, dest, 1);
448
 
    dead_tmp(tmp);
449
 
}
450
 
 
451
 
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
452
 
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
453
 
 
454
 
/* T0 &= ~T1.  Clobbers T1.  */
455
 
/* FIXME: Implement bic natively.  */
456
 
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
457
 
{
458
 
    TCGv tmp = new_tmp();
459
 
    tcg_gen_not_i32(tmp, t1);
460
 
    tcg_gen_and_i32(dest, t0, tmp);
461
 
    dead_tmp(tmp);
462
 
}
463
 
static inline void gen_op_bicl_T0_T1(void)
464
 
{
465
 
    gen_op_notl_T1();
466
 
    gen_op_andl_T0_T1();
467
 
}
468
 
 
469
 
/* FIXME:  Implement this natively.  */
470
 
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
471
 
 
472
 
/* FIXME:  Implement this natively.  */
473
 
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
474
 
{
475
 
    TCGv tmp;
476
 
 
477
 
    if (i == 0)
478
 
        return;
479
 
 
480
 
    tmp = new_tmp();
481
 
    tcg_gen_shri_i32(tmp, t1, i);
482
 
    tcg_gen_shli_i32(t1, t1, 32 - i);
483
 
    tcg_gen_or_i32(t0, t1, tmp);
484
 
    dead_tmp(tmp);
485
 
}
486
 
 
487
 
static void shifter_out_im(TCGv var, int shift)
488
 
{
489
 
    TCGv tmp = new_tmp();
490
 
    if (shift == 0) {
491
 
        tcg_gen_andi_i32(tmp, var, 1);
492
 
    } else {
493
 
        tcg_gen_shri_i32(tmp, var, shift);
494
 
        if (shift != 31);
495
 
            tcg_gen_andi_i32(tmp, tmp, 1);
496
 
    }
497
 
    gen_set_CF(tmp);
498
 
    dead_tmp(tmp);
499
 
}
500
 
 
501
 
/* Shift by immediate.  Includes special handling for shift == 0.  */
502
 
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
503
 
{
504
 
    switch (shiftop) {
505
 
    case 0: /* LSL */
506
 
        if (shift != 0) {
507
 
            if (flags)
508
 
                shifter_out_im(var, 32 - shift);
509
 
            tcg_gen_shli_i32(var, var, shift);
510
 
        }
511
 
        break;
512
 
    case 1: /* LSR */
513
 
        if (shift == 0) {
514
 
            if (flags) {
515
 
                tcg_gen_shri_i32(var, var, 31);
516
 
                gen_set_CF(var);
517
 
            }
518
 
            tcg_gen_movi_i32(var, 0);
519
 
        } else {
520
 
            if (flags)
521
 
                shifter_out_im(var, shift - 1);
522
 
            tcg_gen_shri_i32(var, var, shift);
523
 
        }
524
 
        break;
525
 
    case 2: /* ASR */
526
 
        if (shift == 0)
527
 
            shift = 32;
528
 
        if (flags)
529
 
            shifter_out_im(var, shift - 1);
530
 
        if (shift == 32)
531
 
          shift = 31;
532
 
        tcg_gen_sari_i32(var, var, shift);
533
 
        break;
534
 
    case 3: /* ROR/RRX */
535
 
        if (shift != 0) {
536
 
            if (flags)
537
 
                shifter_out_im(var, shift - 1);
538
 
            tcg_gen_rori_i32(var, var, shift); break;
539
 
        } else {
540
 
            TCGv tmp = load_cpu_field(CF);
541
 
            if (flags)
542
 
                shifter_out_im(var, 0);
543
 
            tcg_gen_shri_i32(var, var, 1);
544
 
            tcg_gen_shli_i32(tmp, tmp, 31);
545
 
            tcg_gen_or_i32(var, var, tmp);
546
 
            dead_tmp(tmp);
547
 
        }
548
 
    }
549
 
};
550
 
 
551
 
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
552
 
                                     TCGv shift, int flags)
553
 
{
554
 
    if (flags) {
555
 
        switch (shiftop) {
556
 
        case 0: gen_helper_shl_cc(var, var, shift); break;
557
 
        case 1: gen_helper_shr_cc(var, var, shift); break;
558
 
        case 2: gen_helper_sar_cc(var, var, shift); break;
559
 
        case 3: gen_helper_ror_cc(var, var, shift); break;
560
 
        }
561
 
    } else {
562
 
        switch (shiftop) {
563
 
        case 0: gen_helper_shl(var, var, shift); break;
564
 
        case 1: gen_helper_shr(var, var, shift); break;
565
 
        case 2: gen_helper_sar(var, var, shift); break;
566
 
        case 3: gen_helper_ror(var, var, shift); break;
567
 
        }
568
 
    }
569
 
    dead_tmp(shift);
570
 
}
571
 
 
572
 
#define PAS_OP(pfx) \
573
 
    switch (op2) {  \
574
 
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
575
 
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
576
 
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
577
 
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
578
 
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
579
 
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
580
 
    }
581
 
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
582
 
{
583
 
    TCGv tmp;
584
 
 
585
 
    switch (op1) {
586
 
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
587
 
    case 1:
588
 
        tmp = tcg_temp_new(TCG_TYPE_PTR);
589
 
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
590
 
        PAS_OP(s)
591
 
        break;
592
 
    case 5:
593
 
        tmp = tcg_temp_new(TCG_TYPE_PTR);
594
 
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
595
 
        PAS_OP(u)
596
 
        break;
597
 
#undef gen_pas_helper
598
 
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
599
 
    case 2:
600
 
        PAS_OP(q);
601
 
        break;
602
 
    case 3:
603
 
        PAS_OP(sh);
604
 
        break;
605
 
    case 6:
606
 
        PAS_OP(uq);
607
 
        break;
608
 
    case 7:
609
 
        PAS_OP(uh);
610
 
        break;
611
 
#undef gen_pas_helper
612
 
    }
613
 
}
614
 
#undef PAS_OP
615
 
 
616
 
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
617
 
#define PAS_OP(pfx) \
618
 
    switch (op2) {  \
619
 
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
620
 
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
621
 
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
622
 
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
623
 
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
624
 
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
625
 
    }
626
 
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
627
 
{
628
 
    TCGv tmp;
629
 
 
630
 
    switch (op1) {
631
 
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
632
 
    case 0:
633
 
        tmp = tcg_temp_new(TCG_TYPE_PTR);
634
 
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
635
 
        PAS_OP(s)
636
 
        break;
637
 
    case 4:
638
 
        tmp = tcg_temp_new(TCG_TYPE_PTR);
639
 
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
640
 
        PAS_OP(u)
641
 
        break;
642
 
#undef gen_pas_helper
643
 
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
644
 
    case 1:
645
 
        PAS_OP(q);
646
 
        break;
647
 
    case 2:
648
 
        PAS_OP(sh);
649
 
        break;
650
 
    case 5:
651
 
        PAS_OP(uq);
652
 
        break;
653
 
    case 6:
654
 
        PAS_OP(uh);
655
 
        break;
656
 
#undef gen_pas_helper
657
 
    }
658
 
}
659
 
#undef PAS_OP
660
 
 
661
 
static void gen_test_cc(int cc, int label)
662
 
{
663
 
    TCGv tmp;
664
 
    TCGv tmp2;
665
 
    int inv;
666
 
 
667
 
    switch (cc) {
668
 
    case 0: /* eq: Z */
669
 
        tmp = load_cpu_field(ZF);
670
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
671
 
        break;
672
 
    case 1: /* ne: !Z */
673
 
        tmp = load_cpu_field(ZF);
674
 
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
675
 
        break;
676
 
    case 2: /* cs: C */
677
 
        tmp = load_cpu_field(CF);
678
 
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
679
 
        break;
680
 
    case 3: /* cc: !C */
681
 
        tmp = load_cpu_field(CF);
682
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
683
 
        break;
684
 
    case 4: /* mi: N */
685
 
        tmp = load_cpu_field(NF);
686
 
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
687
 
        break;
688
 
    case 5: /* pl: !N */
689
 
        tmp = load_cpu_field(NF);
690
 
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
691
 
        break;
692
 
    case 6: /* vs: V */
693
 
        tmp = load_cpu_field(VF);
694
 
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
695
 
        break;
696
 
    case 7: /* vc: !V */
697
 
        tmp = load_cpu_field(VF);
698
 
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
699
 
        break;
700
 
    case 8: /* hi: C && !Z */
701
 
        inv = gen_new_label();
702
 
        tmp = load_cpu_field(CF);
703
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
704
 
        dead_tmp(tmp);
705
 
        tmp = load_cpu_field(ZF);
706
 
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
707
 
        gen_set_label(inv);
708
 
        break;
709
 
    case 9: /* ls: !C || Z */
710
 
        tmp = load_cpu_field(CF);
711
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
712
 
        dead_tmp(tmp);
713
 
        tmp = load_cpu_field(ZF);
714
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
715
 
        break;
716
 
    case 10: /* ge: N == V -> N ^ V == 0 */
717
 
        tmp = load_cpu_field(VF);
718
 
        tmp2 = load_cpu_field(NF);
719
 
        tcg_gen_xor_i32(tmp, tmp, tmp2);
720
 
        dead_tmp(tmp2);
721
 
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
722
 
        break;
723
 
    case 11: /* lt: N != V -> N ^ V != 0 */
724
 
        tmp = load_cpu_field(VF);
725
 
        tmp2 = load_cpu_field(NF);
726
 
        tcg_gen_xor_i32(tmp, tmp, tmp2);
727
 
        dead_tmp(tmp2);
728
 
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
729
 
        break;
730
 
    case 12: /* gt: !Z && N == V */
731
 
        inv = gen_new_label();
732
 
        tmp = load_cpu_field(ZF);
733
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
734
 
        dead_tmp(tmp);
735
 
        tmp = load_cpu_field(VF);
736
 
        tmp2 = load_cpu_field(NF);
737
 
        tcg_gen_xor_i32(tmp, tmp, tmp2);
738
 
        dead_tmp(tmp2);
739
 
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
740
 
        gen_set_label(inv);
741
 
        break;
742
 
    case 13: /* le: Z || N != V */
743
 
        tmp = load_cpu_field(ZF);
744
 
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
745
 
        dead_tmp(tmp);
746
 
        tmp = load_cpu_field(VF);
747
 
        tmp2 = load_cpu_field(NF);
748
 
        tcg_gen_xor_i32(tmp, tmp, tmp2);
749
 
        dead_tmp(tmp2);
750
 
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
751
 
        break;
752
 
    default:
753
 
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
754
 
        abort();
755
 
    }
756
 
    dead_tmp(tmp);
757
 
}
758
 
 
759
 
static const uint8_t table_logic_cc[16] = {
 
61
#define DISAS_JUMP_NEXT 4
 
62
 
 
63
#ifdef USE_DIRECT_JUMP
 
64
#define TBPARAM(x)
 
65
#else
 
66
#define TBPARAM(x) (long)(x)
 
67
#endif
 
68
 
 
69
/* XXX: move that elsewhere */
 
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
static GenOpFunc1 *gen_test_cc[14] = {
 
85
    gen_op_test_eq,
 
86
    gen_op_test_ne,
 
87
    gen_op_test_cs,
 
88
    gen_op_test_cc,
 
89
    gen_op_test_mi,
 
90
    gen_op_test_pl,
 
91
    gen_op_test_vs,
 
92
    gen_op_test_vc,
 
93
    gen_op_test_hi,
 
94
    gen_op_test_ls,
 
95
    gen_op_test_ge,
 
96
    gen_op_test_lt,
 
97
    gen_op_test_gt,
 
98
    gen_op_test_le,
 
99
};
 
100
 
 
101
const uint8_t table_logic_cc[16] = {
760
102
    1, /* and */
761
103
    1, /* xor */
762
104
    0, /* sub */
774
116
    1, /* bic */
775
117
    1, /* mvn */
776
118
};
777
 
 
778
 
/* Set PC and Thumb state from an immediate address.  */
779
 
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
780
 
{
781
 
    TCGv tmp;
782
 
 
783
 
    s->is_jmp = DISAS_UPDATE;
784
 
    tmp = new_tmp();
785
 
    if (s->thumb != (addr & 1)) {
786
 
        tcg_gen_movi_i32(tmp, addr & 1);
787
 
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
788
 
    }
789
 
    tcg_gen_movi_i32(tmp, addr & ~1);
790
 
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
791
 
    dead_tmp(tmp);
792
 
}
793
 
 
794
 
/* Set PC and Thumb state from var.  var is marked as dead.  */
795
 
static inline void gen_bx(DisasContext *s, TCGv var)
796
 
{
797
 
    TCGv tmp;
798
 
 
799
 
    s->is_jmp = DISAS_UPDATE;
800
 
    tmp = new_tmp();
801
 
    tcg_gen_andi_i32(tmp, var, 1);
802
 
    store_cpu_field(tmp, thumb);
803
 
    tcg_gen_andi_i32(var, var, ~1);
804
 
    store_cpu_field(var, regs[15]);
805
 
}
806
 
 
807
 
/* TODO: This should be removed.  Use gen_bx instead.  */
808
 
static inline void gen_bx_T0(DisasContext *s)
809
 
{
810
 
    TCGv tmp = new_tmp();
811
 
    tcg_gen_mov_i32(tmp, cpu_T[0]);
812
 
    gen_bx(s, tmp);
813
 
}
 
119
    
 
120
static GenOpFunc1 *gen_shift_T1_im[4] = {
 
121
    gen_op_shll_T1_im,
 
122
    gen_op_shrl_T1_im,
 
123
    gen_op_sarl_T1_im,
 
124
    gen_op_rorl_T1_im,
 
125
};
 
126
 
 
127
static GenOpFunc *gen_shift_T1_0[4] = {
 
128
    NULL,
 
129
    gen_op_shrl_T1_0,
 
130
    gen_op_sarl_T1_0,
 
131
    gen_op_rrxl_T1,
 
132
};
 
133
 
 
134
static GenOpFunc1 *gen_shift_T2_im[4] = {
 
135
    gen_op_shll_T2_im,
 
136
    gen_op_shrl_T2_im,
 
137
    gen_op_sarl_T2_im,
 
138
    gen_op_rorl_T2_im,
 
139
};
 
140
 
 
141
static GenOpFunc *gen_shift_T2_0[4] = {
 
142
    NULL,
 
143
    gen_op_shrl_T2_0,
 
144
    gen_op_sarl_T2_0,
 
145
    gen_op_rrxl_T2,
 
146
};
 
147
 
 
148
static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
 
149
    gen_op_shll_T1_im_cc,
 
150
    gen_op_shrl_T1_im_cc,
 
151
    gen_op_sarl_T1_im_cc,
 
152
    gen_op_rorl_T1_im_cc,
 
153
};
 
154
 
 
155
static GenOpFunc *gen_shift_T1_0_cc[4] = {
 
156
    NULL,
 
157
    gen_op_shrl_T1_0_cc,
 
158
    gen_op_sarl_T1_0_cc,
 
159
    gen_op_rrxl_T1_cc,
 
160
};
 
161
 
 
162
static GenOpFunc *gen_shift_T1_T0[4] = {
 
163
    gen_op_shll_T1_T0,
 
164
    gen_op_shrl_T1_T0,
 
165
    gen_op_sarl_T1_T0,
 
166
    gen_op_rorl_T1_T0,
 
167
};
 
168
 
 
169
static GenOpFunc *gen_shift_T1_T0_cc[4] = {
 
170
    gen_op_shll_T1_T0_cc,
 
171
    gen_op_shrl_T1_T0_cc,
 
172
    gen_op_sarl_T1_T0_cc,
 
173
    gen_op_rorl_T1_T0_cc,
 
174
};
 
175
 
 
176
static GenOpFunc *gen_op_movl_TN_reg[3][16] = {
 
177
    {
 
178
        gen_op_movl_T0_r0,
 
179
        gen_op_movl_T0_r1,
 
180
        gen_op_movl_T0_r2,
 
181
        gen_op_movl_T0_r3,
 
182
        gen_op_movl_T0_r4,
 
183
        gen_op_movl_T0_r5,
 
184
        gen_op_movl_T0_r6,
 
185
        gen_op_movl_T0_r7,
 
186
        gen_op_movl_T0_r8,
 
187
        gen_op_movl_T0_r9,
 
188
        gen_op_movl_T0_r10,
 
189
        gen_op_movl_T0_r11,
 
190
        gen_op_movl_T0_r12,
 
191
        gen_op_movl_T0_r13,
 
192
        gen_op_movl_T0_r14,
 
193
        gen_op_movl_T0_r15,
 
194
    },
 
195
    {
 
196
        gen_op_movl_T1_r0,
 
197
        gen_op_movl_T1_r1,
 
198
        gen_op_movl_T1_r2,
 
199
        gen_op_movl_T1_r3,
 
200
        gen_op_movl_T1_r4,
 
201
        gen_op_movl_T1_r5,
 
202
        gen_op_movl_T1_r6,
 
203
        gen_op_movl_T1_r7,
 
204
        gen_op_movl_T1_r8,
 
205
        gen_op_movl_T1_r9,
 
206
        gen_op_movl_T1_r10,
 
207
        gen_op_movl_T1_r11,
 
208
        gen_op_movl_T1_r12,
 
209
        gen_op_movl_T1_r13,
 
210
        gen_op_movl_T1_r14,
 
211
        gen_op_movl_T1_r15,
 
212
    },
 
213
    {
 
214
        gen_op_movl_T2_r0,
 
215
        gen_op_movl_T2_r1,
 
216
        gen_op_movl_T2_r2,
 
217
        gen_op_movl_T2_r3,
 
218
        gen_op_movl_T2_r4,
 
219
        gen_op_movl_T2_r5,
 
220
        gen_op_movl_T2_r6,
 
221
        gen_op_movl_T2_r7,
 
222
        gen_op_movl_T2_r8,
 
223
        gen_op_movl_T2_r9,
 
224
        gen_op_movl_T2_r10,
 
225
        gen_op_movl_T2_r11,
 
226
        gen_op_movl_T2_r12,
 
227
        gen_op_movl_T2_r13,
 
228
        gen_op_movl_T2_r14,
 
229
        gen_op_movl_T2_r15,
 
230
    },
 
231
};
 
232
 
 
233
static GenOpFunc *gen_op_movl_reg_TN[2][16] = {
 
234
    {
 
235
        gen_op_movl_r0_T0,
 
236
        gen_op_movl_r1_T0,
 
237
        gen_op_movl_r2_T0,
 
238
        gen_op_movl_r3_T0,
 
239
        gen_op_movl_r4_T0,
 
240
        gen_op_movl_r5_T0,
 
241
        gen_op_movl_r6_T0,
 
242
        gen_op_movl_r7_T0,
 
243
        gen_op_movl_r8_T0,
 
244
        gen_op_movl_r9_T0,
 
245
        gen_op_movl_r10_T0,
 
246
        gen_op_movl_r11_T0,
 
247
        gen_op_movl_r12_T0,
 
248
        gen_op_movl_r13_T0,
 
249
        gen_op_movl_r14_T0,
 
250
        gen_op_movl_r15_T0,
 
251
    },
 
252
    {
 
253
        gen_op_movl_r0_T1,
 
254
        gen_op_movl_r1_T1,
 
255
        gen_op_movl_r2_T1,
 
256
        gen_op_movl_r3_T1,
 
257
        gen_op_movl_r4_T1,
 
258
        gen_op_movl_r5_T1,
 
259
        gen_op_movl_r6_T1,
 
260
        gen_op_movl_r7_T1,
 
261
        gen_op_movl_r8_T1,
 
262
        gen_op_movl_r9_T1,
 
263
        gen_op_movl_r10_T1,
 
264
        gen_op_movl_r11_T1,
 
265
        gen_op_movl_r12_T1,
 
266
        gen_op_movl_r13_T1,
 
267
        gen_op_movl_r14_T1,
 
268
        gen_op_movl_r15_T1,
 
269
    },
 
270
};
 
271
 
 
272
static GenOpFunc1 *gen_op_movl_TN_im[3] = {
 
273
    gen_op_movl_T0_im,
 
274
    gen_op_movl_T1_im,
 
275
    gen_op_movl_T2_im,
 
276
};
 
277
 
 
278
static GenOpFunc1 *gen_shift_T0_im_thumb[3] = {
 
279
    gen_op_shll_T0_im_thumb,
 
280
    gen_op_shrl_T0_im_thumb,
 
281
    gen_op_sarl_T0_im_thumb,
 
282
};
 
283
 
 
284
static inline void gen_bx(DisasContext *s)
 
285
{
 
286
  s->is_jmp = DISAS_UPDATE;
 
287
  gen_op_bx_T0();
 
288
}
 
289
 
814
290
 
815
291
#if defined(CONFIG_USER_ONLY)
816
292
#define gen_ldst(name, s) gen_op_##name##_raw()
823
299
        gen_op_##name##_kernel(); \
824
300
    } while (0)
825
301
#endif
826
 
static inline TCGv gen_ld8s(TCGv addr, int index)
827
 
{
828
 
    TCGv tmp = new_tmp();
829
 
    tcg_gen_qemu_ld8s(tmp, addr, index);
830
 
    return tmp;
831
 
}
832
 
static inline TCGv gen_ld8u(TCGv addr, int index)
833
 
{
834
 
    TCGv tmp = new_tmp();
835
 
    tcg_gen_qemu_ld8u(tmp, addr, index);
836
 
    return tmp;
837
 
}
838
 
static inline TCGv gen_ld16s(TCGv addr, int index)
839
 
{
840
 
    TCGv tmp = new_tmp();
841
 
    tcg_gen_qemu_ld16s(tmp, addr, index);
842
 
    return tmp;
843
 
}
844
 
static inline TCGv gen_ld16u(TCGv addr, int index)
845
 
{
846
 
    TCGv tmp = new_tmp();
847
 
    tcg_gen_qemu_ld16u(tmp, addr, index);
848
 
    return tmp;
849
 
}
850
 
static inline TCGv gen_ld32(TCGv addr, int index)
851
 
{
852
 
    TCGv tmp = new_tmp();
853
 
    tcg_gen_qemu_ld32u(tmp, addr, index);
854
 
    return tmp;
855
 
}
856
 
static inline void gen_st8(TCGv val, TCGv addr, int index)
857
 
{
858
 
    tcg_gen_qemu_st8(val, addr, index);
859
 
    dead_tmp(val);
860
 
}
861
 
static inline void gen_st16(TCGv val, TCGv addr, int index)
862
 
{
863
 
    tcg_gen_qemu_st16(val, addr, index);
864
 
    dead_tmp(val);
865
 
}
866
 
static inline void gen_st32(TCGv val, TCGv addr, int index)
867
 
{
868
 
    tcg_gen_qemu_st32(val, addr, index);
869
 
    dead_tmp(val);
 
302
 
 
303
static inline void gen_movl_TN_reg(DisasContext *s, int reg, int t)
 
304
{
 
305
    int val;
 
306
 
 
307
    if (reg == 15) {
 
308
        /* normaly, since we updated PC, we need only to add one insn */
 
309
        if (s->thumb)
 
310
            val = (long)s->pc + 2;
 
311
        else
 
312
            val = (long)s->pc + 4;
 
313
        gen_op_movl_TN_im[t](val);
 
314
    } else {
 
315
        gen_op_movl_TN_reg[t][reg]();
 
316
    }
870
317
}
871
318
 
872
319
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
873
320
{
874
 
    load_reg_var(s, cpu_T[0], reg);
 
321
    gen_movl_TN_reg(s, reg, 0);
875
322
}
876
323
 
877
324
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
878
325
{
879
 
    load_reg_var(s, cpu_T[1], reg);
 
326
    gen_movl_TN_reg(s, reg, 1);
880
327
}
881
328
 
882
329
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
883
330
{
884
 
    load_reg_var(s, cpu_T[2], reg);
885
 
}
886
 
 
887
 
static inline void gen_set_pc_im(uint32_t val)
888
 
{
889
 
    TCGv tmp = new_tmp();
890
 
    tcg_gen_movi_i32(tmp, val);
891
 
    store_cpu_field(tmp, regs[15]);
 
331
    gen_movl_TN_reg(s, reg, 2);
892
332
}
893
333
 
894
334
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
895
335
{
896
 
    TCGv tmp;
897
 
    if (reg == 15) {
898
 
        tmp = new_tmp();
899
 
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
900
 
    } else {
901
 
        tmp = cpu_T[t];
902
 
    }
903
 
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
904
 
    if (reg == 15) {
905
 
        dead_tmp(tmp);
 
336
    gen_op_movl_reg_TN[t][reg]();
 
337
    if (reg == 15) {
906
338
        s->is_jmp = DISAS_JUMP;
907
339
    }
908
340
}
925
357
    s->is_jmp = DISAS_UPDATE;
926
358
}
927
359
 
928
 
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
929
 
                                       TCGv var)
 
360
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
930
361
{
931
362
    int val, rm, shift, shiftop;
932
 
    TCGv offset;
933
363
 
934
364
    if (!(insn & (1 << 25))) {
935
365
        /* immediate */
937
367
        if (!(insn & (1 << 23)))
938
368
            val = -val;
939
369
        if (val != 0)
940
 
            tcg_gen_addi_i32(var, var, val);
 
370
            gen_op_addl_T1_im(val);
941
371
    } else {
942
372
        /* shift/register */
943
373
        rm = (insn) & 0xf;
944
374
        shift = (insn >> 7) & 0x1f;
 
375
        gen_movl_T2_reg(s, rm);
945
376
        shiftop = (insn >> 5) & 3;
946
 
        offset = load_reg(s, rm);
947
 
        gen_arm_shift_im(offset, shiftop, shift, 0);
 
377
        if (shift != 0) {
 
378
            gen_shift_T2_im[shiftop](shift);
 
379
        } else if (shiftop != 0) {
 
380
            gen_shift_T2_0[shiftop]();
 
381
        }
948
382
        if (!(insn & (1 << 23)))
949
 
            tcg_gen_sub_i32(var, var, offset);
 
383
            gen_op_subl_T1_T2();
950
384
        else
951
 
            tcg_gen_add_i32(var, var, offset);
952
 
        dead_tmp(offset);
 
385
            gen_op_addl_T1_T2();
953
386
    }
954
387
}
955
388
 
956
389
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
957
 
                                        int extra, TCGv var)
 
390
                                        int extra)
958
391
{
959
392
    int val, rm;
960
 
    TCGv offset;
961
 
 
 
393
    
962
394
    if (insn & (1 << 22)) {
963
395
        /* immediate */
964
396
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
966
398
            val = -val;
967
399
        val += extra;
968
400
        if (val != 0)
969
 
            tcg_gen_addi_i32(var, var, val);
 
401
            gen_op_addl_T1_im(val);
970
402
    } else {
971
403
        /* register */
972
404
        if (extra)
973
 
            tcg_gen_addi_i32(var, var, extra);
 
405
            gen_op_addl_T1_im(extra);
974
406
        rm = (insn) & 0xf;
975
 
        offset = load_reg(s, rm);
 
407
        gen_movl_T2_reg(s, rm);
976
408
        if (!(insn & (1 << 23)))
977
 
            tcg_gen_sub_i32(var, var, offset);
 
409
            gen_op_subl_T1_T2();
978
410
        else
979
 
            tcg_gen_add_i32(var, var, offset);
980
 
        dead_tmp(offset);
 
411
            gen_op_addl_T1_T2();
981
412
    }
982
413
}
983
414
 
984
 
#define VFP_OP2(name)                                                 \
985
 
static inline void gen_vfp_##name(int dp)                             \
986
 
{                                                                     \
987
 
    if (dp)                                                           \
988
 
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
989
 
    else                                                              \
990
 
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
991
 
}
992
 
 
993
 
#define VFP_OP1(name)                               \
994
 
static inline void gen_vfp_##name(int dp, int arg)  \
995
 
{                                                   \
996
 
    if (dp)                                         \
997
 
        gen_op_vfp_##name##d(arg);                  \
998
 
    else                                            \
999
 
        gen_op_vfp_##name##s(arg);                  \
1000
 
}
1001
 
 
1002
 
VFP_OP2(add)
1003
 
VFP_OP2(sub)
1004
 
VFP_OP2(mul)
1005
 
VFP_OP2(div)
1006
 
 
1007
 
#undef VFP_OP2
1008
 
 
1009
 
static inline void gen_vfp_abs(int dp)
1010
 
{
1011
 
    if (dp)
1012
 
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1013
 
    else
1014
 
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1015
 
}
1016
 
 
1017
 
static inline void gen_vfp_neg(int dp)
1018
 
{
1019
 
    if (dp)
1020
 
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1021
 
    else
1022
 
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1023
 
}
1024
 
 
1025
 
static inline void gen_vfp_sqrt(int dp)
1026
 
{
1027
 
    if (dp)
1028
 
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1029
 
    else
1030
 
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1031
 
}
1032
 
 
1033
 
static inline void gen_vfp_cmp(int dp)
1034
 
{
1035
 
    if (dp)
1036
 
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1037
 
    else
1038
 
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1039
 
}
1040
 
 
1041
 
static inline void gen_vfp_cmpe(int dp)
1042
 
{
1043
 
    if (dp)
1044
 
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1045
 
    else
1046
 
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1047
 
}
1048
 
 
1049
 
static inline void gen_vfp_F1_ld0(int dp)
1050
 
{
1051
 
    if (dp)
1052
 
        tcg_gen_movi_i64(cpu_F1d, 0);
1053
 
    else
1054
 
        tcg_gen_movi_i32(cpu_F1s, 0);
1055
 
}
1056
 
 
1057
 
static inline void gen_vfp_uito(int dp)
1058
 
{
1059
 
    if (dp)
1060
 
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1061
 
    else
1062
 
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1063
 
}
1064
 
 
1065
 
static inline void gen_vfp_sito(int dp)
1066
 
{
1067
 
    if (dp)
1068
 
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1069
 
    else
1070
 
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1071
 
}
1072
 
 
1073
 
static inline void gen_vfp_toui(int dp)
1074
 
{
1075
 
    if (dp)
1076
 
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1077
 
    else
1078
 
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1079
 
}
1080
 
 
1081
 
static inline void gen_vfp_touiz(int dp)
1082
 
{
1083
 
    if (dp)
1084
 
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1085
 
    else
1086
 
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1087
 
}
1088
 
 
1089
 
static inline void gen_vfp_tosi(int dp)
1090
 
{
1091
 
    if (dp)
1092
 
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1093
 
    else
1094
 
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1095
 
}
1096
 
 
1097
 
static inline void gen_vfp_tosiz(int dp)
1098
 
{
1099
 
    if (dp)
1100
 
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1101
 
    else
1102
 
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1103
 
}
1104
 
 
1105
 
#define VFP_GEN_FIX(name) \
1106
 
static inline void gen_vfp_##name(int dp, int shift) \
1107
 
{ \
1108
 
    if (dp) \
1109
 
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1110
 
    else \
1111
 
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1112
 
}
1113
 
VFP_GEN_FIX(tosh)
1114
 
VFP_GEN_FIX(tosl)
1115
 
VFP_GEN_FIX(touh)
1116
 
VFP_GEN_FIX(toul)
1117
 
VFP_GEN_FIX(shto)
1118
 
VFP_GEN_FIX(slto)
1119
 
VFP_GEN_FIX(uhto)
1120
 
VFP_GEN_FIX(ulto)
1121
 
#undef VFP_GEN_FIX
 
415
#define VFP_OP(name)                      \
 
416
static inline void gen_vfp_##name(int dp) \
 
417
{                                         \
 
418
    if (dp)                               \
 
419
        gen_op_vfp_##name##d();           \
 
420
    else                                  \
 
421
        gen_op_vfp_##name##s();           \
 
422
}
 
423
 
 
424
VFP_OP(add)
 
425
VFP_OP(sub)
 
426
VFP_OP(mul)
 
427
VFP_OP(div)
 
428
VFP_OP(neg)
 
429
VFP_OP(abs)
 
430
VFP_OP(sqrt)
 
431
VFP_OP(cmp)
 
432
VFP_OP(cmpe)
 
433
VFP_OP(F1_ld0)
 
434
VFP_OP(uito)
 
435
VFP_OP(sito)
 
436
VFP_OP(toui)
 
437
VFP_OP(touiz)
 
438
VFP_OP(tosi)
 
439
VFP_OP(tosiz)
 
440
 
 
441
#undef VFP_OP
1122
442
 
1123
443
static inline void gen_vfp_ld(DisasContext *s, int dp)
1124
444
{
1125
445
    if (dp)
1126
 
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
 
446
        gen_ldst(vfp_ldd, s);
1127
447
    else
1128
 
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
 
448
        gen_ldst(vfp_lds, s);
1129
449
}
1130
450
 
1131
451
static inline void gen_vfp_st(DisasContext *s, int dp)
1132
452
{
1133
453
    if (dp)
1134
 
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
 
454
        gen_ldst(vfp_std, s);
1135
455
    else
1136
 
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
 
456
        gen_ldst(vfp_sts, s);
1137
457
}
1138
458
 
1139
459
static inline long
1149
469
          + offsetof(CPU_DoubleU, l.lower);
1150
470
    }
1151
471
}
1152
 
 
1153
 
/* Return the offset of a 32-bit piece of a NEON register.
1154
 
   zero is the least significant end of the register.  */
1155
 
static inline long
1156
 
neon_reg_offset (int reg, int n)
1157
 
{
1158
 
    int sreg;
1159
 
    sreg = reg * 2 + n;
1160
 
    return vfp_reg_offset(0, sreg);
1161
 
}
1162
 
 
1163
 
/* FIXME: Remove these.  */
1164
 
#define neon_T0 cpu_T[0]
1165
 
#define neon_T1 cpu_T[1]
1166
 
#define NEON_GET_REG(T, reg, n) \
1167
 
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1168
 
#define NEON_SET_REG(T, reg, n) \
1169
 
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1170
 
 
1171
 
static TCGv neon_load_reg(int reg, int pass)
1172
 
{
1173
 
    TCGv tmp = new_tmp();
1174
 
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1175
 
    return tmp;
1176
 
}
1177
 
 
1178
 
static void neon_store_reg(int reg, int pass, TCGv var)
1179
 
{
1180
 
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1181
 
    dead_tmp(var);
1182
 
}
1183
 
 
1184
 
static inline void neon_load_reg64(TCGv var, int reg)
1185
 
{
1186
 
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1187
 
}
1188
 
 
1189
 
static inline void neon_store_reg64(TCGv var, int reg)
1190
 
{
1191
 
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192
 
}
1193
 
 
1194
 
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1195
 
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1196
 
#define tcg_gen_st_f32 tcg_gen_st_i32
1197
 
#define tcg_gen_st_f64 tcg_gen_st_i64
1198
 
 
1199
472
static inline void gen_mov_F0_vreg(int dp, int reg)
1200
473
{
1201
474
    if (dp)
1202
 
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
 
475
        gen_op_vfp_getreg_F0d(vfp_reg_offset(dp, reg));
1203
476
    else
1204
 
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
 
477
        gen_op_vfp_getreg_F0s(vfp_reg_offset(dp, reg));
1205
478
}
1206
479
 
1207
480
static inline void gen_mov_F1_vreg(int dp, int reg)
1208
481
{
1209
482
    if (dp)
1210
 
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
 
483
        gen_op_vfp_getreg_F1d(vfp_reg_offset(dp, reg));
1211
484
    else
1212
 
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
 
485
        gen_op_vfp_getreg_F1s(vfp_reg_offset(dp, reg));
1213
486
}
1214
487
 
1215
488
static inline void gen_mov_vreg_F0(int dp, int reg)
1216
489
{
1217
490
    if (dp)
1218
 
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
 
491
        gen_op_vfp_setreg_F0d(vfp_reg_offset(dp, reg));
1219
492
    else
1220
 
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
 
493
        gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg));
1221
494
}
1222
495
 
1223
496
#define ARM_CP_RW_BIT   (1 << 20)
1224
497
 
1225
 
static inline void iwmmxt_load_reg(TCGv var, int reg)
1226
 
{
1227
 
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1228
 
}
1229
 
 
1230
 
static inline void iwmmxt_store_reg(TCGv var, int reg)
1231
 
{
1232
 
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1233
 
}
1234
 
 
1235
 
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1236
 
{
1237
 
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1238
 
}
1239
 
 
1240
 
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1241
 
{
1242
 
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1243
 
}
1244
 
 
1245
 
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1246
 
{
1247
 
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1248
 
}
1249
 
 
1250
 
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1251
 
{
1252
 
    iwmmxt_store_reg(cpu_M0, rn);
1253
 
}
1254
 
 
1255
 
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1256
 
{
1257
 
    iwmmxt_load_reg(cpu_M0, rn);
1258
 
}
1259
 
 
1260
 
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1261
 
{
1262
 
    iwmmxt_load_reg(cpu_V1, rn);
1263
 
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1264
 
}
1265
 
 
1266
 
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1267
 
{
1268
 
    iwmmxt_load_reg(cpu_V1, rn);
1269
 
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1270
 
}
1271
 
 
1272
 
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1273
 
{
1274
 
    iwmmxt_load_reg(cpu_V1, rn);
1275
 
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1276
 
}
1277
 
 
1278
 
#define IWMMXT_OP(name) \
1279
 
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1280
 
{ \
1281
 
    iwmmxt_load_reg(cpu_V1, rn); \
1282
 
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1283
 
}
1284
 
 
1285
 
#define IWMMXT_OP_ENV(name) \
1286
 
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1287
 
{ \
1288
 
    iwmmxt_load_reg(cpu_V1, rn); \
1289
 
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1290
 
}
1291
 
 
1292
 
#define IWMMXT_OP_ENV_SIZE(name) \
1293
 
IWMMXT_OP_ENV(name##b) \
1294
 
IWMMXT_OP_ENV(name##w) \
1295
 
IWMMXT_OP_ENV(name##l)
1296
 
 
1297
 
#define IWMMXT_OP_ENV1(name) \
1298
 
static inline void gen_op_iwmmxt_##name##_M0(void) \
1299
 
{ \
1300
 
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1301
 
}
1302
 
 
1303
 
IWMMXT_OP(maddsq)
1304
 
IWMMXT_OP(madduq)
1305
 
IWMMXT_OP(sadb)
1306
 
IWMMXT_OP(sadw)
1307
 
IWMMXT_OP(mulslw)
1308
 
IWMMXT_OP(mulshw)
1309
 
IWMMXT_OP(mululw)
1310
 
IWMMXT_OP(muluhw)
1311
 
IWMMXT_OP(macsw)
1312
 
IWMMXT_OP(macuw)
1313
 
 
1314
 
IWMMXT_OP_ENV_SIZE(unpackl)
1315
 
IWMMXT_OP_ENV_SIZE(unpackh)
1316
 
 
1317
 
IWMMXT_OP_ENV1(unpacklub)
1318
 
IWMMXT_OP_ENV1(unpackluw)
1319
 
IWMMXT_OP_ENV1(unpacklul)
1320
 
IWMMXT_OP_ENV1(unpackhub)
1321
 
IWMMXT_OP_ENV1(unpackhuw)
1322
 
IWMMXT_OP_ENV1(unpackhul)
1323
 
IWMMXT_OP_ENV1(unpacklsb)
1324
 
IWMMXT_OP_ENV1(unpacklsw)
1325
 
IWMMXT_OP_ENV1(unpacklsl)
1326
 
IWMMXT_OP_ENV1(unpackhsb)
1327
 
IWMMXT_OP_ENV1(unpackhsw)
1328
 
IWMMXT_OP_ENV1(unpackhsl)
1329
 
 
1330
 
IWMMXT_OP_ENV_SIZE(cmpeq)
1331
 
IWMMXT_OP_ENV_SIZE(cmpgtu)
1332
 
IWMMXT_OP_ENV_SIZE(cmpgts)
1333
 
 
1334
 
IWMMXT_OP_ENV_SIZE(mins)
1335
 
IWMMXT_OP_ENV_SIZE(minu)
1336
 
IWMMXT_OP_ENV_SIZE(maxs)
1337
 
IWMMXT_OP_ENV_SIZE(maxu)
1338
 
 
1339
 
IWMMXT_OP_ENV_SIZE(subn)
1340
 
IWMMXT_OP_ENV_SIZE(addn)
1341
 
IWMMXT_OP_ENV_SIZE(subu)
1342
 
IWMMXT_OP_ENV_SIZE(addu)
1343
 
IWMMXT_OP_ENV_SIZE(subs)
1344
 
IWMMXT_OP_ENV_SIZE(adds)
1345
 
 
1346
 
IWMMXT_OP_ENV(avgb0)
1347
 
IWMMXT_OP_ENV(avgb1)
1348
 
IWMMXT_OP_ENV(avgw0)
1349
 
IWMMXT_OP_ENV(avgw1)
1350
 
 
1351
 
IWMMXT_OP(msadb)
1352
 
 
1353
 
IWMMXT_OP_ENV(packuw)
1354
 
IWMMXT_OP_ENV(packul)
1355
 
IWMMXT_OP_ENV(packuq)
1356
 
IWMMXT_OP_ENV(packsw)
1357
 
IWMMXT_OP_ENV(packsl)
1358
 
IWMMXT_OP_ENV(packsq)
1359
 
 
1360
 
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1361
 
{
1362
 
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1363
 
}
1364
 
 
1365
 
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1366
 
{
1367
 
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1368
 
}
1369
 
 
1370
 
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1371
 
{
1372
 
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1373
 
}
1374
 
 
1375
 
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1376
 
{
1377
 
    iwmmxt_load_reg(cpu_V1, rn);
1378
 
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1379
 
}
1380
 
 
1381
 
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1382
 
{
1383
 
    TCGv tmp = tcg_const_i32(shift);
1384
 
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1385
 
}
1386
 
 
1387
 
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1388
 
{
1389
 
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1390
 
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1391
 
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1392
 
}
1393
 
 
1394
 
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1395
 
{
1396
 
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1397
 
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1398
 
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1399
 
}
1400
 
 
1401
 
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1402
 
{
1403
 
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404
 
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1405
 
    if (mask != ~0u)
1406
 
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1407
 
}
1408
 
 
1409
 
static void gen_op_iwmmxt_set_mup(void)
1410
 
{
1411
 
    TCGv tmp;
1412
 
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1413
 
    tcg_gen_ori_i32(tmp, tmp, 2);
1414
 
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1415
 
}
1416
 
 
1417
 
static void gen_op_iwmmxt_set_cup(void)
1418
 
{
1419
 
    TCGv tmp;
1420
 
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1421
 
    tcg_gen_ori_i32(tmp, tmp, 1);
1422
 
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1423
 
}
1424
 
 
1425
 
static void gen_op_iwmmxt_setpsr_nz(void)
1426
 
{
1427
 
    TCGv tmp = new_tmp();
1428
 
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1429
 
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1430
 
}
1431
 
 
1432
 
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1433
 
{
1434
 
    iwmmxt_load_reg(cpu_V1, rn);
1435
 
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1436
 
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1437
 
}
1438
 
 
1439
 
 
1440
 
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1441
 
{
1442
 
    iwmmxt_load_reg(cpu_V0, rn);
1443
 
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1444
 
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1445
 
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1446
 
}
1447
 
 
1448
 
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1449
 
{
1450
 
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1451
 
    iwmmxt_store_reg(cpu_V0, rn);
1452
 
}
1453
 
 
1454
498
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1455
499
{
1456
500
    int rd;
1492
536
        else
1493
537
            gen_op_iwmmxt_movl_T0_wCx(rd);
1494
538
    else
1495
 
        gen_iwmmxt_movl_T0_T1_wRn(rd);
 
539
        gen_op_iwmmxt_movl_T0_T1_wRn(rd);
1496
540
 
1497
541
    gen_op_movl_T1_im(mask);
1498
542
    gen_op_andl_T0_T1();
1505
549
{
1506
550
    int rd, wrd;
1507
551
    int rdhi, rdlo, rd0, rd1, i;
1508
 
    TCGv tmp;
1509
552
 
1510
553
    if ((insn & 0x0e000e00) == 0x0c000000) {
1511
554
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1513
556
            rdlo = (insn >> 12) & 0xf;
1514
557
            rdhi = (insn >> 16) & 0xf;
1515
558
            if (insn & ARM_CP_RW_BIT) {                 /* TMRRC */
1516
 
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
 
559
                gen_op_iwmmxt_movl_T0_T1_wRn(wrd);
1517
560
                gen_movl_reg_T0(s, rdlo);
1518
561
                gen_movl_reg_T1(s, rdhi);
1519
562
            } else {                                    /* TMCRR */
1520
563
                gen_movl_T0_reg(s, rdlo);
1521
564
                gen_movl_T1_reg(s, rdhi);
1522
 
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
 
565
                gen_op_iwmmxt_movl_wRn_T0_T1(wrd);
1523
566
                gen_op_iwmmxt_set_mup();
1524
567
            }
1525
568
            return 0;
1530
573
            return 1;
1531
574
        if (insn & ARM_CP_RW_BIT) {
1532
575
            if ((insn >> 28) == 0xf) {                  /* WLDRW wCx */
1533
 
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1534
 
                tcg_gen_mov_i32(cpu_T[0], tmp);
1535
 
                dead_tmp(tmp);
 
576
                gen_ldst(ldl, s);
1536
577
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1537
578
            } else {
1538
 
                i = 1;
1539
 
                if (insn & (1 << 8)) {
1540
 
                    if (insn & (1 << 22)) {             /* WLDRD */
1541
 
                        tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1542
 
                        i = 0;
1543
 
                    } else {                            /* WLDRW wRd */
1544
 
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
1545
 
                    }
1546
 
                } else {
1547
 
                    if (insn & (1 << 22)) {             /* WLDRH */
1548
 
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1549
 
                    } else {                            /* WLDRB */
1550
 
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1551
 
                    }
1552
 
                }
1553
 
                if (i) {
1554
 
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1555
 
                    dead_tmp(tmp);
1556
 
                }
 
579
                if (insn & (1 << 8))
 
580
                    if (insn & (1 << 22))               /* WLDRD */
 
581
                        gen_ldst(iwmmxt_ldq, s);
 
582
                    else                                /* WLDRW wRd */
 
583
                        gen_ldst(iwmmxt_ldl, s);
 
584
                else
 
585
                    if (insn & (1 << 22))               /* WLDRH */
 
586
                        gen_ldst(iwmmxt_ldw, s);
 
587
                    else                                /* WLDRB */
 
588
                        gen_ldst(iwmmxt_ldb, s);
1557
589
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1558
590
            }
1559
591
        } else {
1560
592
            if ((insn >> 28) == 0xf) {                  /* WSTRW wCx */
1561
593
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1562
 
                tmp = new_tmp();
1563
 
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1564
 
                gen_st32(tmp, cpu_T[1], IS_USER(s));
 
594
                gen_ldst(stl, s);
1565
595
            } else {
1566
596
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1567
 
                tmp = new_tmp();
1568
 
                if (insn & (1 << 8)) {
1569
 
                    if (insn & (1 << 22)) {             /* WSTRD */
1570
 
                        dead_tmp(tmp);
1571
 
                        tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1572
 
                    } else {                            /* WSTRW wRd */
1573
 
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1574
 
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
1575
 
                    }
1576
 
                } else {
1577
 
                    if (insn & (1 << 22)) {             /* WSTRH */
1578
 
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1579
 
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
1580
 
                    } else {                            /* WSTRB */
1581
 
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1582
 
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
1583
 
                    }
1584
 
                }
 
597
                if (insn & (1 << 8))
 
598
                    if (insn & (1 << 22))               /* WSTRD */
 
599
                        gen_ldst(iwmmxt_stq, s);
 
600
                    else                                /* WSTRW wRd */
 
601
                        gen_ldst(iwmmxt_stl, s);
 
602
                else
 
603
                    if (insn & (1 << 22))               /* WSTRH */
 
604
                        gen_ldst(iwmmxt_ldw, s);
 
605
                    else                                /* WSTRB */
 
606
                        gen_ldst(iwmmxt_stb, s);
1585
607
            }
1586
608
        }
1587
609
        return 0;
1656
678
        rd0 = (insn >> 0) & 0xf;
1657
679
        rd1 = (insn >> 16) & 0xf;
1658
680
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1659
 
        tcg_gen_neg_i64(cpu_M0, cpu_M0);
 
681
        gen_op_iwmmxt_negq_M0();
1660
682
        gen_op_iwmmxt_andq_M0_wRn(rd1);
1661
683
        gen_op_iwmmxt_setpsr_nz();
1662
684
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1749
771
        rd0 = (insn >> 16) & 0xf;
1750
772
        rd1 = (insn >> 0) & 0xf;
1751
773
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1752
 
        if (insn & (1 << 21)) {
1753
 
            if (insn & (1 << 20))
1754
 
                gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1755
 
            else
1756
 
                gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1757
 
        } else {
1758
 
            if (insn & (1 << 20))
1759
 
                gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1760
 
            else
1761
 
                gen_op_iwmmxt_mululw_M0_wRn(rd1);
1762
 
        }
 
774
        if (insn & (1 << 21))
 
775
            gen_op_iwmmxt_mulsw_M0_wRn(rd1, (insn & (1 << 20)) ? 16 : 0);
 
776
        else
 
777
            gen_op_iwmmxt_muluw_M0_wRn(rd1, (insn & (1 << 20)) ? 16 : 0);
1763
778
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1764
779
        gen_op_iwmmxt_set_mup();
1765
780
        break;
1773
788
        else
1774
789
            gen_op_iwmmxt_macuw_M0_wRn(rd1);
1775
790
        if (!(insn & (1 << 20))) {
1776
 
            iwmmxt_load_reg(cpu_V1, wrd);
1777
 
            tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
 
791
            if (insn & (1 << 21))
 
792
                gen_op_iwmmxt_addsq_M0_wRn(wrd);
 
793
            else
 
794
                gen_op_iwmmxt_adduq_M0_wRn(wrd);
1778
795
        }
1779
796
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1780
797
        gen_op_iwmmxt_set_mup();
1806
823
        rd0 = (insn >> 16) & 0xf;
1807
824
        rd1 = (insn >> 0) & 0xf;
1808
825
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1809
 
        if (insn & (1 << 22)) {
1810
 
            if (insn & (1 << 20))
1811
 
                gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1812
 
            else
1813
 
                gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1814
 
        } else {
1815
 
            if (insn & (1 << 20))
1816
 
                gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1817
 
            else
1818
 
                gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1819
 
        }
 
826
        if (insn & (1 << 22))
 
827
            gen_op_iwmmxt_avgw_M0_wRn(rd1, (insn >> 20) & 1);
 
828
        else
 
829
            gen_op_iwmmxt_avgb_M0_wRn(rd1, (insn >> 20) & 1);
1820
830
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1821
831
        gen_op_iwmmxt_set_mup();
1822
832
        gen_op_iwmmxt_set_cup();
1868
878
            if (insn & 8)
1869
879
                gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1870
880
            else {
1871
 
                gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
 
881
                gen_op_movl_T1_im(0xff);
 
882
                gen_op_iwmmxt_extru_T0_M0_T1((insn & 7) << 3);
1872
883
            }
1873
884
            break;
1874
885
        case 1:
1875
886
            if (insn & 8)
1876
887
                gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1877
888
            else {
1878
 
                gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
 
889
                gen_op_movl_T1_im(0xffff);
 
890
                gen_op_iwmmxt_extru_T0_M0_T1((insn & 3) << 4);
1879
891
            }
1880
892
            break;
1881
893
        case 2:
1882
 
            gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
 
894
            gen_op_movl_T1_im(0xffffffff);
 
895
            gen_op_iwmmxt_extru_T0_M0_T1((insn & 1) << 5);
1883
896
            break;
1884
897
        case 3:
1885
898
            return 1;
1886
899
        }
1887
 
        gen_movl_reg_T0(s, rd);
 
900
        gen_op_movl_reg_TN[0][rd]();
1888
901
        break;
1889
902
    case 0x117: case 0x517: case 0x917: case 0xd17:     /* TEXTRC */
1890
903
        if ((insn & 0x000ff008) != 0x0003f000)
1904
917
            return 1;
1905
918
        }
1906
919
        gen_op_shll_T1_im(28);
1907
 
        gen_set_nzcv(cpu_T[1]);
 
920
        gen_op_movl_T0_T1();
 
921
        gen_op_movl_cpsr_T0(0xf0000000);
1908
922
        break;
1909
923
    case 0x401: case 0x405: case 0x409: case 0x40d:     /* TBCST */
1910
924
        rd = (insn >> 12) & 0xf;
1912
926
        gen_movl_T0_reg(s, rd);
1913
927
        switch ((insn >> 6) & 3) {
1914
928
        case 0:
1915
 
            gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
 
929
            gen_op_iwmmxt_bcstb_M0_T0();
1916
930
            break;
1917
931
        case 1:
1918
 
            gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
 
932
            gen_op_iwmmxt_bcstw_M0_T0();
1919
933
            break;
1920
934
        case 2:
1921
 
            gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
 
935
            gen_op_iwmmxt_bcstl_M0_T0();
1922
936
            break;
1923
937
        case 3:
1924
938
            return 1;
1950
964
        case 3:
1951
965
            return 1;
1952
966
        }
1953
 
        gen_set_nzcv(cpu_T[0]);
 
967
        gen_op_movl_cpsr_T0(0xf0000000);
1954
968
        break;
1955
969
    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:     /* WACC */
1956
970
        wrd = (insn >> 12) & 0xf;
1958
972
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1959
973
        switch ((insn >> 22) & 3) {
1960
974
        case 0:
1961
 
            gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
 
975
            gen_op_iwmmxt_addcb_M0();
1962
976
            break;
1963
977
        case 1:
1964
 
            gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
 
978
            gen_op_iwmmxt_addcw_M0();
1965
979
            break;
1966
980
        case 2:
1967
 
            gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
 
981
            gen_op_iwmmxt_addcl_M0();
1968
982
            break;
1969
983
        case 3:
1970
984
            return 1;
1996
1010
        case 3:
1997
1011
            return 1;
1998
1012
        }
1999
 
        gen_set_nzcv(cpu_T[0]);
 
1013
        gen_op_movl_T1_im(0xf0000000);
 
1014
        gen_op_andl_T0_T1();
 
1015
        gen_op_movl_cpsr_T0(0xf0000000);
2000
1016
        break;
2001
1017
    case 0x103: case 0x503: case 0x903: case 0xd03:     /* TMOVMSK */
2002
1018
        rd = (insn >> 12) & 0xf;
2006
1022
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2007
1023
        switch ((insn >> 22) & 3) {
2008
1024
        case 0:
2009
 
            gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
 
1025
            gen_op_iwmmxt_msbb_T0_M0();
2010
1026
            break;
2011
1027
        case 1:
2012
 
            gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
 
1028
            gen_op_iwmmxt_msbw_T0_M0();
2013
1029
            break;
2014
1030
        case 2:
2015
 
            gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
 
1031
            gen_op_iwmmxt_msbl_T0_M0();
2016
1032
            break;
2017
1033
        case 3:
2018
1034
            return 1;
2124
1140
        case 0:
2125
1141
            return 1;
2126
1142
        case 1:
2127
 
            gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1143
            gen_op_iwmmxt_srlw_M0_T0();
2128
1144
            break;
2129
1145
        case 2:
2130
 
            gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1146
            gen_op_iwmmxt_srll_M0_T0();
2131
1147
            break;
2132
1148
        case 3:
2133
 
            gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1149
            gen_op_iwmmxt_srlq_M0_T0();
2134
1150
            break;
2135
1151
        }
2136
1152
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2148
1164
        case 0:
2149
1165
            return 1;
2150
1166
        case 1:
2151
 
            gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1167
            gen_op_iwmmxt_sraw_M0_T0();
2152
1168
            break;
2153
1169
        case 2:
2154
 
            gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1170
            gen_op_iwmmxt_sral_M0_T0();
2155
1171
            break;
2156
1172
        case 3:
2157
 
            gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1173
            gen_op_iwmmxt_sraq_M0_T0();
2158
1174
            break;
2159
1175
        }
2160
1176
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2172
1188
        case 0:
2173
1189
            return 1;
2174
1190
        case 1:
2175
 
            gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1191
            gen_op_iwmmxt_sllw_M0_T0();
2176
1192
            break;
2177
1193
        case 2:
2178
 
            gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1194
            gen_op_iwmmxt_slll_M0_T0();
2179
1195
            break;
2180
1196
        case 3:
2181
 
            gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1197
            gen_op_iwmmxt_sllq_M0_T0();
2182
1198
            break;
2183
1199
        }
2184
1200
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2196
1212
        case 1:
2197
1213
            if (gen_iwmmxt_shift(insn, 0xf))
2198
1214
                return 1;
2199
 
            gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1215
            gen_op_iwmmxt_rorw_M0_T0();
2200
1216
            break;
2201
1217
        case 2:
2202
1218
            if (gen_iwmmxt_shift(insn, 0x1f))
2203
1219
                return 1;
2204
 
            gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1220
            gen_op_iwmmxt_rorl_M0_T0();
2205
1221
            break;
2206
1222
        case 3:
2207
1223
            if (gen_iwmmxt_shift(insn, 0x3f))
2208
1224
                return 1;
2209
 
            gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1225
            gen_op_iwmmxt_rorq_M0_T0();
2210
1226
            break;
2211
1227
        }
2212
1228
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2337
1353
        rd0 = (insn >> 16) & 0xf;
2338
1354
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2339
1355
        gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2340
 
        gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
 
1356
        gen_op_iwmmxt_shufh_M0_T0();
2341
1357
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2342
1358
        gen_op_iwmmxt_set_mup();
2343
1359
        gen_op_iwmmxt_set_cup();
2433
1449
        gen_op_iwmmxt_movq_M0_wRn(wrd);
2434
1450
        switch ((insn >> 16) & 0xf) {
2435
1451
        case 0x0:                                       /* TMIA */
2436
 
            gen_movl_T0_reg(s, rd0);
2437
 
            gen_movl_T1_reg(s, rd1);
 
1452
            gen_op_movl_TN_reg[0][rd0]();
 
1453
            gen_op_movl_TN_reg[1][rd1]();
2438
1454
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2439
1455
            break;
2440
1456
        case 0x8:                                       /* TMIAPH */
2441
 
            gen_movl_T0_reg(s, rd0);
2442
 
            gen_movl_T1_reg(s, rd1);
 
1457
            gen_op_movl_TN_reg[0][rd0]();
 
1458
            gen_op_movl_TN_reg[1][rd1]();
2443
1459
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2444
1460
            break;
2445
1461
        case 0xc: case 0xd: case 0xe: case 0xf:         /* TMIAxy */
2446
 
            gen_movl_T1_reg(s, rd0);
 
1462
            gen_op_movl_TN_reg[1][rd0]();
2447
1463
            if (insn & (1 << 16))
2448
1464
                gen_op_shrl_T1_im(16);
2449
1465
            gen_op_movl_T0_T1();
2450
 
            gen_movl_T1_reg(s, rd1);
 
1466
            gen_op_movl_TN_reg[1][rd1]();
2451
1467
            if (insn & (1 << 17))
2452
1468
                gen_op_shrl_T1_im(16);
2453
1469
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2482
1498
 
2483
1499
        switch ((insn >> 16) & 0xf) {
2484
1500
        case 0x0:                                       /* MIA */
2485
 
            gen_movl_T0_reg(s, rd0);
2486
 
            gen_movl_T1_reg(s, rd1);
 
1501
            gen_op_movl_TN_reg[0][rd0]();
 
1502
            gen_op_movl_TN_reg[1][rd1]();
2487
1503
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2488
1504
            break;
2489
1505
        case 0x8:                                       /* MIAPH */
2490
 
            gen_movl_T0_reg(s, rd0);
2491
 
            gen_movl_T1_reg(s, rd1);
 
1506
            gen_op_movl_TN_reg[0][rd0]();
 
1507
            gen_op_movl_TN_reg[1][rd1]();
2492
1508
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2493
1509
            break;
2494
1510
        case 0xc:                                       /* MIABB */
2495
1511
        case 0xd:                                       /* MIABT */
2496
1512
        case 0xe:                                       /* MIATB */
2497
1513
        case 0xf:                                       /* MIATT */
2498
 
            gen_movl_T1_reg(s, rd0);
 
1514
            gen_op_movl_TN_reg[1][rd0]();
2499
1515
            if (insn & (1 << 16))
2500
1516
                gen_op_shrl_T1_im(16);
2501
1517
            gen_op_movl_T0_T1();
2502
 
            gen_movl_T1_reg(s, rd1);
 
1518
            gen_op_movl_TN_reg[1][rd1]();
2503
1519
            if (insn & (1 << 17))
2504
1520
                gen_op_shrl_T1_im(16);
2505
1521
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2522
1538
            return 1;
2523
1539
 
2524
1540
        if (insn & ARM_CP_RW_BIT) {                     /* MRA */
2525
 
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2526
 
            gen_movl_reg_T0(s, rdlo);
 
1541
            gen_op_iwmmxt_movl_T0_T1_wRn(acc);
 
1542
            gen_op_movl_reg_TN[0][rdlo]();
2527
1543
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2528
1544
            gen_op_andl_T0_T1();
2529
 
            gen_movl_reg_T0(s, rdhi);
 
1545
            gen_op_movl_reg_TN[0][rdhi]();
2530
1546
        } else {                                        /* MAR */
2531
 
            gen_movl_T0_reg(s, rdlo);
2532
 
            gen_movl_T1_reg(s, rdhi);
2533
 
            gen_iwmmxt_movl_wRn_T0_T1(acc);
 
1547
            gen_op_movl_TN_reg[0][rdlo]();
 
1548
            gen_op_movl_TN_reg[1][rdhi]();
 
1549
            gen_op_iwmmxt_movl_wRn_T0_T1(acc);
2534
1550
        }
2535
1551
        return 0;
2536
1552
    }
2542
1558
   instruction is not defined.  */
2543
1559
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2544
1560
{
2545
 
    TCGv tmp;
2546
1561
    uint32_t rd = (insn >> 12) & 0xf;
2547
1562
    uint32_t cp = (insn >> 8) & 0xf;
2548
1563
    if (IS_USER(s)) {
2552
1567
    if (insn & ARM_CP_RW_BIT) {
2553
1568
        if (!env->cp[cp].cp_read)
2554
1569
            return 1;
2555
 
        gen_set_pc_im(s->pc);
2556
 
        tmp = new_tmp();
2557
 
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2558
 
        store_reg(s, rd, tmp);
 
1570
        gen_op_movl_T0_im((uint32_t) s->pc);
 
1571
        gen_op_movl_reg_TN[0][15]();
 
1572
        gen_op_movl_T0_cp(insn);
 
1573
        gen_movl_reg_T0(s, rd);
2559
1574
    } else {
2560
1575
        if (!env->cp[cp].cp_write)
2561
1576
            return 1;
2562
 
        gen_set_pc_im(s->pc);
2563
 
        tmp = load_reg(s, rd);
2564
 
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2565
 
        dead_tmp(tmp);
2566
 
    }
2567
 
    return 0;
2568
 
}
2569
 
 
2570
 
static int cp15_user_ok(uint32_t insn)
2571
 
{
2572
 
    int cpn = (insn >> 16) & 0xf;
2573
 
    int cpm = insn & 0xf;
2574
 
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2575
 
 
2576
 
    if (cpn == 13 && cpm == 0) {
2577
 
        /* TLS register.  */
2578
 
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2579
 
            return 1;
2580
 
    }
2581
 
    if (cpn == 7) {
2582
 
        /* ISB, DSB, DMB.  */
2583
 
        if ((cpm == 5 && op == 4)
2584
 
                || (cpm == 10 && (op == 4 || op == 5)))
2585
 
            return 1;
 
1577
        gen_op_movl_T0_im((uint32_t) s->pc);
 
1578
        gen_op_movl_reg_TN[0][15]();
 
1579
        gen_movl_T0_reg(s, rd);
 
1580
        gen_op_movl_cp_T0(insn);
2586
1581
    }
2587
1582
    return 0;
2588
1583
}
2592
1587
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2593
1588
{
2594
1589
    uint32_t rd;
2595
 
    TCGv tmp;
2596
 
 
2597
 
    /* M profile cores use memory mapped registers instead of cp15.  */
2598
 
    if (arm_feature(env, ARM_FEATURE_M))
2599
 
        return 1;
2600
 
 
2601
 
    if ((insn & (1 << 25)) == 0) {
2602
 
        if (insn & (1 << 20)) {
2603
 
            /* mrrc */
2604
 
            return 1;
2605
 
        }
2606
 
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2607
 
        return 0;
2608
 
    }
2609
 
    if ((insn & (1 << 4)) == 0) {
2610
 
        /* cdp */
2611
 
        return 1;
2612
 
    }
2613
 
    if (IS_USER(s) && !cp15_user_ok(insn)) {
 
1590
 
 
1591
    /* ??? Some cp15 registers are accessible from userspace.  */
 
1592
    if (IS_USER(s)) {
2614
1593
        return 1;
2615
1594
    }
2616
1595
    if ((insn & 0x0fff0fff) == 0x0e070f90
2617
1596
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2618
1597
        /* Wait for interrupt.  */
2619
 
        gen_set_pc_im(s->pc);
2620
 
        s->is_jmp = DISAS_WFI;
 
1598
        gen_op_movl_T0_im((long)s->pc);
 
1599
        gen_op_movl_reg_TN[0][15]();
 
1600
        gen_op_wfi();
 
1601
        s->is_jmp = DISAS_JUMP;
2621
1602
        return 0;
2622
1603
    }
2623
1604
    rd = (insn >> 12) & 0xf;
2624
1605
    if (insn & ARM_CP_RW_BIT) {
2625
 
        tmp = new_tmp();
2626
 
        gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
 
1606
        gen_op_movl_T0_cp15(insn);
2627
1607
        /* If the destination register is r15 then sets condition codes.  */
2628
1608
        if (rd != 15)
2629
 
            store_reg(s, rd, tmp);
2630
 
        else
2631
 
            dead_tmp(tmp);
 
1609
            gen_movl_reg_T0(s, rd);
2632
1610
    } else {
2633
 
        tmp = load_reg(s, rd);
2634
 
        gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2635
 
        dead_tmp(tmp);
 
1611
        gen_movl_T0_reg(s, rd);
 
1612
        gen_op_movl_cp15_T0(insn);
2636
1613
        /* Normally we would always end the TB here, but Linux
2637
1614
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2638
1615
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2643
1620
    return 0;
2644
1621
}
2645
1622
 
2646
 
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2647
 
#define VFP_SREG(insn, bigbit, smallbit) \
2648
 
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2649
 
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2650
 
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2651
 
        reg = (((insn) >> (bigbit)) & 0x0f) \
2652
 
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2653
 
    } else { \
2654
 
        if (insn & (1 << (smallbit))) \
2655
 
            return 1; \
2656
 
        reg = ((insn) >> (bigbit)) & 0x0f; \
2657
 
    }} while (0)
2658
 
 
2659
 
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2660
 
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2661
 
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2662
 
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2663
 
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2664
 
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2665
 
 
2666
 
/* Move between integer and VFP cores.  */
2667
 
static TCGv gen_vfp_mrs(void)
2668
 
{
2669
 
    TCGv tmp = new_tmp();
2670
 
    tcg_gen_mov_i32(tmp, cpu_F0s);
2671
 
    return tmp;
2672
 
}
2673
 
 
2674
 
static void gen_vfp_msr(TCGv tmp)
2675
 
{
2676
 
    tcg_gen_mov_i32(cpu_F0s, tmp);
2677
 
    dead_tmp(tmp);
2678
 
}
2679
 
 
2680
 
static inline int
2681
 
vfp_enabled(CPUState * env)
2682
 
{
2683
 
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2684
 
}
2685
 
 
2686
 
static void gen_neon_dup_u8(TCGv var, int shift)
2687
 
{
2688
 
    TCGv tmp = new_tmp();
2689
 
    if (shift)
2690
 
        tcg_gen_shri_i32(var, var, shift);
2691
 
    tcg_gen_ext8u_i32(var, var);
2692
 
    tcg_gen_shli_i32(tmp, var, 8);
2693
 
    tcg_gen_or_i32(var, var, tmp);
2694
 
    tcg_gen_shli_i32(tmp, var, 16);
2695
 
    tcg_gen_or_i32(var, var, tmp);
2696
 
    dead_tmp(tmp);
2697
 
}
2698
 
 
2699
 
static void gen_neon_dup_low16(TCGv var)
2700
 
{
2701
 
    TCGv tmp = new_tmp();
2702
 
    tcg_gen_ext16u_i32(var, var);
2703
 
    tcg_gen_shli_i32(tmp, var, 16);
2704
 
    tcg_gen_or_i32(var, var, tmp);
2705
 
    dead_tmp(tmp);
2706
 
}
2707
 
 
2708
 
static void gen_neon_dup_high16(TCGv var)
2709
 
{
2710
 
    TCGv tmp = new_tmp();
2711
 
    tcg_gen_andi_i32(var, var, 0xffff0000);
2712
 
    tcg_gen_shri_i32(tmp, var, 16);
2713
 
    tcg_gen_or_i32(var, var, tmp);
2714
 
    dead_tmp(tmp);
2715
 
}
2716
 
 
2717
1623
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2718
1624
   (ie. an undefined instruction).  */
2719
1625
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2720
1626
{
2721
1627
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2722
1628
    int dp, veclen;
2723
 
    TCGv tmp;
2724
 
    TCGv tmp2;
2725
1629
 
2726
1630
    if (!arm_feature(env, ARM_FEATURE_VFP))
2727
1631
        return 1;
2728
1632
 
2729
 
    if (!vfp_enabled(env)) {
2730
 
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
 
1633
    if ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) == 0) {
 
1634
        /* VFP disabled.  Only allow fmxr/fmrx to/from fpexc and fpsid.  */
2731
1635
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2732
1636
            return 1;
2733
1637
        rn = (insn >> 16) & 0xf;
2734
 
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2735
 
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
 
1638
        if (rn != 0 && rn != 8)
2736
1639
            return 1;
2737
1640
    }
2738
1641
    dp = ((insn & 0xf00) == 0xb00);
2740
1643
    case 0xe:
2741
1644
        if (insn & (1 << 4)) {
2742
1645
            /* single register transfer */
 
1646
            if ((insn & 0x6f) != 0x00)
 
1647
                return 1;
2743
1648
            rd = (insn >> 12) & 0xf;
2744
1649
            if (dp) {
2745
 
                int size;
2746
 
                int pass;
2747
 
 
2748
 
                VFP_DREG_N(rn, insn);
2749
 
                if (insn & 0xf)
2750
 
                    return 1;
2751
 
                if (insn & 0x00c00060
2752
 
                    && !arm_feature(env, ARM_FEATURE_NEON))
2753
 
                    return 1;
2754
 
 
2755
 
                pass = (insn >> 21) & 1;
2756
 
                if (insn & (1 << 22)) {
2757
 
                    size = 0;
2758
 
                    offset = ((insn >> 5) & 3) * 8;
2759
 
                } else if (insn & (1 << 5)) {
2760
 
                    size = 1;
2761
 
                    offset = (insn & (1 << 6)) ? 16 : 0;
2762
 
                } else {
2763
 
                    size = 2;
2764
 
                    offset = 0;
2765
 
                }
 
1650
                if (insn & 0x80)
 
1651
                    return 1;
 
1652
                rn = (insn >> 16) & 0xf;
 
1653
                /* Get the existing value even for arm->vfp moves because
 
1654
                   we only set half the register.  */
 
1655
                gen_mov_F0_vreg(1, rn);
 
1656
                gen_op_vfp_mrrd();
2766
1657
                if (insn & ARM_CP_RW_BIT) {
2767
1658
                    /* vfp->arm */
2768
 
                    tmp = neon_load_reg(rn, pass);
2769
 
                    switch (size) {
2770
 
                    case 0:
2771
 
                        if (offset)
2772
 
                            tcg_gen_shri_i32(tmp, tmp, offset);
2773
 
                        if (insn & (1 << 23))
2774
 
                            gen_uxtb(tmp);
2775
 
                        else
2776
 
                            gen_sxtb(tmp);
2777
 
                        break;
2778
 
                    case 1:
2779
 
                        if (insn & (1 << 23)) {
2780
 
                            if (offset) {
2781
 
                                tcg_gen_shri_i32(tmp, tmp, 16);
2782
 
                            } else {
2783
 
                                gen_uxth(tmp);
2784
 
                            }
2785
 
                        } else {
2786
 
                            if (offset) {
2787
 
                                tcg_gen_sari_i32(tmp, tmp, 16);
2788
 
                            } else {
2789
 
                                gen_sxth(tmp);
2790
 
                            }
2791
 
                        }
2792
 
                        break;
2793
 
                    case 2:
2794
 
                        break;
2795
 
                    }
2796
 
                    store_reg(s, rd, tmp);
 
1659
                    if (insn & (1 << 21))
 
1660
                        gen_movl_reg_T1(s, rd);
 
1661
                    else
 
1662
                        gen_movl_reg_T0(s, rd);
2797
1663
                } else {
2798
1664
                    /* arm->vfp */
2799
 
                    tmp = load_reg(s, rd);
2800
 
                    if (insn & (1 << 23)) {
2801
 
                        /* VDUP */
2802
 
                        if (size == 0) {
2803
 
                            gen_neon_dup_u8(tmp, 0);
2804
 
                        } else if (size == 1) {
2805
 
                            gen_neon_dup_low16(tmp);
2806
 
                        }
2807
 
                        tmp2 = new_tmp();
2808
 
                        tcg_gen_mov_i32(tmp2, tmp);
2809
 
                        neon_store_reg(rn, 0, tmp2);
2810
 
                        neon_store_reg(rn, 1, tmp);
2811
 
                    } else {
2812
 
                        /* VMOV */
2813
 
                        switch (size) {
2814
 
                        case 0:
2815
 
                            tmp2 = neon_load_reg(rn, pass);
2816
 
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2817
 
                            dead_tmp(tmp2);
2818
 
                            break;
2819
 
                        case 1:
2820
 
                            tmp2 = neon_load_reg(rn, pass);
2821
 
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2822
 
                            dead_tmp(tmp2);
2823
 
                            break;
2824
 
                        case 2:
2825
 
                            break;
2826
 
                        }
2827
 
                        neon_store_reg(rn, pass, tmp);
2828
 
                    }
 
1665
                    if (insn & (1 << 21))
 
1666
                        gen_movl_T1_reg(s, rd);
 
1667
                    else
 
1668
                        gen_movl_T0_reg(s, rd);
 
1669
                    gen_op_vfp_mdrr();
 
1670
                    gen_mov_vreg_F0(dp, rn);
2829
1671
                }
2830
 
            } else { /* !dp */
2831
 
                if ((insn & 0x6f) != 0x00)
2832
 
                    return 1;
2833
 
                rn = VFP_SREG_N(insn);
 
1672
            } else {
 
1673
                rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2834
1674
                if (insn & ARM_CP_RW_BIT) {
2835
1675
                    /* vfp->arm */
2836
1676
                    if (insn & (1 << 21)) {
2837
1677
                        /* system register */
2838
1678
                        rn >>= 1;
2839
 
 
2840
1679
                        switch (rn) {
2841
1680
                        case ARM_VFP_FPSID:
2842
 
                            /* VFP2 allows access to FSID from userspace.
2843
 
                               VFP3 restricts all id registers to privileged
2844
 
                               accesses.  */
2845
 
                            if (IS_USER(s)
2846
 
                                && arm_feature(env, ARM_FEATURE_VFP3))
2847
 
                                return 1;
2848
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
2849
 
                            break;
2850
1681
                        case ARM_VFP_FPEXC:
2851
 
                            if (IS_USER(s))
2852
 
                                return 1;
2853
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
2854
 
                            break;
2855
1682
                        case ARM_VFP_FPINST:
2856
1683
                        case ARM_VFP_FPINST2:
2857
 
                            /* Not present in VFP3.  */
2858
 
                            if (IS_USER(s)
2859
 
                                || arm_feature(env, ARM_FEATURE_VFP3))
2860
 
                                return 1;
2861
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
 
1684
                            gen_op_vfp_movl_T0_xreg(rn);
2862
1685
                            break;
2863
1686
                        case ARM_VFP_FPSCR:
2864
 
                            if (rd == 15) {
2865
 
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2866
 
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2867
 
                            } else {
2868
 
                                tmp = new_tmp();
2869
 
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2870
 
                            }
2871
 
                            break;
2872
 
                        case ARM_VFP_MVFR0:
2873
 
                        case ARM_VFP_MVFR1:
2874
 
                            if (IS_USER(s)
2875
 
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2876
 
                                return 1;
2877
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
 
1687
                            if (rd == 15)
 
1688
                                gen_op_vfp_movl_T0_fpscr_flags();
 
1689
                            else
 
1690
                                gen_op_vfp_movl_T0_fpscr();
2878
1691
                            break;
2879
1692
                        default:
2880
1693
                            return 1;
2881
1694
                        }
2882
1695
                    } else {
2883
1696
                        gen_mov_F0_vreg(0, rn);
2884
 
                        tmp = gen_vfp_mrs();
 
1697
                        gen_op_vfp_mrs();
2885
1698
                    }
2886
1699
                    if (rd == 15) {
2887
1700
                        /* Set the 4 flag bits in the CPSR.  */
2888
 
                        gen_set_nzcv(tmp);
2889
 
                        dead_tmp(tmp);
2890
 
                    } else {
2891
 
                        store_reg(s, rd, tmp);
2892
 
                    }
 
1701
                        gen_op_movl_cpsr_T0(0xf0000000);
 
1702
                    } else
 
1703
                        gen_movl_reg_T0(s, rd);
2893
1704
                } else {
2894
1705
                    /* arm->vfp */
2895
 
                    tmp = load_reg(s, rd);
 
1706
                    gen_movl_T0_reg(s, rd);
2896
1707
                    if (insn & (1 << 21)) {
2897
1708
                        rn >>= 1;
2898
1709
                        /* system register */
2899
1710
                        switch (rn) {
2900
1711
                        case ARM_VFP_FPSID:
2901
 
                        case ARM_VFP_MVFR0:
2902
 
                        case ARM_VFP_MVFR1:
2903
1712
                            /* Writes are ignored.  */
2904
1713
                            break;
2905
1714
                        case ARM_VFP_FPSCR:
2906
 
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2907
 
                            dead_tmp(tmp);
 
1715
                            gen_op_vfp_movl_fpscr_T0();
2908
1716
                            gen_lookup_tb(s);
2909
1717
                            break;
2910
1718
                        case ARM_VFP_FPEXC:
2911
 
                            if (IS_USER(s))
2912
 
                                return 1;
2913
 
                            store_cpu_field(tmp, vfp.xregs[rn]);
 
1719
                            gen_op_vfp_movl_xreg_T0(rn);
2914
1720
                            gen_lookup_tb(s);
2915
1721
                            break;
2916
1722
                        case ARM_VFP_FPINST:
2917
1723
                        case ARM_VFP_FPINST2:
2918
 
                            store_cpu_field(tmp, vfp.xregs[rn]);
 
1724
                            gen_op_vfp_movl_xreg_T0(rn);
2919
1725
                            break;
2920
1726
                        default:
2921
1727
                            return 1;
2922
1728
                        }
2923
1729
                    } else {
2924
 
                        gen_vfp_msr(tmp);
 
1730
                        gen_op_vfp_msr();
2925
1731
                        gen_mov_vreg_F0(0, rn);
2926
1732
                    }
2927
1733
                }
2936
1742
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2937
1743
                } else {
2938
1744
                    /* rn is register number */
2939
 
                    VFP_DREG_N(rn, insn);
 
1745
                    if (insn & (1 << 7))
 
1746
                        return 1;
 
1747
                    rn = (insn >> 16) & 0xf;
2940
1748
                }
2941
1749
 
2942
1750
                if (op == 15 && (rn == 15 || rn > 17)) {
2943
1751
                    /* Integer or single precision destination.  */
2944
 
                    rd = VFP_SREG_D(insn);
 
1752
                    rd = ((insn >> 11) & 0x1e) | ((insn >> 22) & 1);
2945
1753
                } else {
2946
 
                    VFP_DREG_D(rd, insn);
 
1754
                    if (insn & (1 << 22))
 
1755
                        return 1;
 
1756
                    rd = (insn >> 12) & 0xf;
2947
1757
                }
2948
1758
 
2949
1759
                if (op == 15 && (rn == 16 || rn == 17)) {
2950
1760
                    /* Integer source.  */
2951
1761
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2952
1762
                } else {
2953
 
                    VFP_DREG_M(rm, insn);
 
1763
                    if (insn & (1 << 5))
 
1764
                        return 1;
 
1765
                    rm = insn & 0xf;
2954
1766
                }
2955
1767
            } else {
2956
 
                rn = VFP_SREG_N(insn);
 
1768
                rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2957
1769
                if (op == 15 && rn == 15) {
2958
1770
                    /* Double precision destination.  */
2959
 
                    VFP_DREG_D(rd, insn);
2960
 
                } else {
2961
 
                    rd = VFP_SREG_D(insn);
2962
 
                }
2963
 
                rm = VFP_SREG_M(insn);
 
1771
                    if (insn & (1 << 22))
 
1772
                        return 1;
 
1773
                    rd = (insn >> 12) & 0xf;
 
1774
                } else
 
1775
                    rd = ((insn >> 11) & 0x1e) | ((insn >> 22) & 1);
 
1776
                rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2964
1777
            }
2965
1778
 
2966
1779
            veclen = env->vfp.vec_len;
2971
1784
            delta_m = 0;
2972
1785
            delta_d = 0;
2973
1786
            bank_mask = 0;
2974
 
 
 
1787
            
2975
1788
            if (veclen > 0) {
2976
1789
                if (dp)
2977
1790
                    bank_mask = 0xc;
3018
1831
                    gen_mov_F0_vreg(dp, rd);
3019
1832
                    gen_vfp_F1_ld0(dp);
3020
1833
                    break;
3021
 
                case 20:
3022
 
                case 21:
3023
 
                case 22:
3024
 
                case 23:
3025
 
                    /* Source and destination the same.  */
3026
 
                    gen_mov_F0_vreg(dp, rd);
3027
 
                    break;
3028
1834
                default:
3029
1835
                    /* One source operand.  */
3030
1836
                    gen_mov_F0_vreg(dp, rm);
3031
 
                    break;
3032
1837
                }
3033
1838
            } else {
3034
1839
                /* Two source operands.  */
3057
1862
                    break;
3058
1863
                case 3: /* nmsc: -fd - (fn * fm)  */
3059
1864
                    gen_vfp_mul(dp);
 
1865
                    gen_mov_F1_vreg(dp, rd);
 
1866
                    gen_vfp_add(dp);
3060
1867
                    gen_vfp_neg(dp);
3061
 
                    gen_mov_F1_vreg(dp, rd);
3062
 
                    gen_vfp_sub(dp);
3063
1868
                    break;
3064
1869
                case 4: /* mul: fn * fm */
3065
1870
                    gen_vfp_mul(dp);
3077
1882
                case 8: /* div: fn / fm */
3078
1883
                    gen_vfp_div(dp);
3079
1884
                    break;
3080
 
                case 14: /* fconst */
3081
 
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3082
 
                      return 1;
3083
 
 
3084
 
                    n = (insn << 12) & 0x80000000;
3085
 
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3086
 
                    if (dp) {
3087
 
                        if (i & 0x40)
3088
 
                            i |= 0x3f80;
3089
 
                        else
3090
 
                            i |= 0x4000;
3091
 
                        n |= i << 16;
3092
 
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3093
 
                    } else {
3094
 
                        if (i & 0x40)
3095
 
                            i |= 0x780;
3096
 
                        else
3097
 
                            i |= 0x800;
3098
 
                        n |= i << 19;
3099
 
                        tcg_gen_movi_i32(cpu_F0s, n);
3100
 
                    }
3101
 
                    break;
3102
1885
                case 15: /* extension space */
3103
1886
                    switch (rn) {
3104
1887
                    case 0: /* cpy */
3128
1911
                        break;
3129
1912
                    case 15: /* single<->double conversion */
3130
1913
                        if (dp)
3131
 
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
 
1914
                            gen_op_vfp_fcvtsd();
3132
1915
                        else
3133
 
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
 
1916
                            gen_op_vfp_fcvtds();
3134
1917
                        break;
3135
1918
                    case 16: /* fuito */
3136
1919
                        gen_vfp_uito(dp);
3138
1921
                    case 17: /* fsito */
3139
1922
                        gen_vfp_sito(dp);
3140
1923
                        break;
3141
 
                    case 20: /* fshto */
3142
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3143
 
                          return 1;
3144
 
                        gen_vfp_shto(dp, rm);
3145
 
                        break;
3146
 
                    case 21: /* fslto */
3147
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3148
 
                          return 1;
3149
 
                        gen_vfp_slto(dp, rm);
3150
 
                        break;
3151
 
                    case 22: /* fuhto */
3152
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3153
 
                          return 1;
3154
 
                        gen_vfp_uhto(dp, rm);
3155
 
                        break;
3156
 
                    case 23: /* fulto */
3157
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3158
 
                          return 1;
3159
 
                        gen_vfp_ulto(dp, rm);
3160
 
                        break;
3161
1924
                    case 24: /* ftoui */
3162
1925
                        gen_vfp_toui(dp);
3163
1926
                        break;
3170
1933
                    case 27: /* ftosiz */
3171
1934
                        gen_vfp_tosiz(dp);
3172
1935
                        break;
3173
 
                    case 28: /* ftosh */
3174
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3175
 
                          return 1;
3176
 
                        gen_vfp_tosh(dp, rm);
3177
 
                        break;
3178
 
                    case 29: /* ftosl */
3179
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3180
 
                          return 1;
3181
 
                        gen_vfp_tosl(dp, rm);
3182
 
                        break;
3183
 
                    case 30: /* ftouh */
3184
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3185
 
                          return 1;
3186
 
                        gen_vfp_touh(dp, rm);
3187
 
                        break;
3188
 
                    case 31: /* ftoul */
3189
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3190
 
                          return 1;
3191
 
                        gen_vfp_toul(dp, rm);
3192
 
                        break;
3193
1936
                    default: /* undefined */
3194
1937
                        printf ("rn:%d\n", rn);
3195
1938
                        return 1;
3251
1994
        break;
3252
1995
    case 0xc:
3253
1996
    case 0xd:
3254
 
        if (dp && (insn & 0x03e00000) == 0x00400000) {
 
1997
        if (dp && (insn & (1 << 22))) {
3255
1998
            /* two-register transfer */
3256
1999
            rn = (insn >> 16) & 0xf;
3257
2000
            rd = (insn >> 12) & 0xf;
3258
2001
            if (dp) {
3259
 
                VFP_DREG_M(rm, insn);
3260
 
            } else {
3261
 
                rm = VFP_SREG_M(insn);
3262
 
            }
 
2002
                if (insn & (1 << 5))
 
2003
                    return 1;
 
2004
                rm = insn & 0xf;
 
2005
            } else
 
2006
                rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
3263
2007
 
3264
2008
            if (insn & ARM_CP_RW_BIT) {
3265
2009
                /* vfp->arm */
3266
2010
                if (dp) {
3267
 
                    gen_mov_F0_vreg(0, rm * 2);
3268
 
                    tmp = gen_vfp_mrs();
3269
 
                    store_reg(s, rd, tmp);
3270
 
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3271
 
                    tmp = gen_vfp_mrs();
3272
 
                    store_reg(s, rn, tmp);
 
2011
                    gen_mov_F0_vreg(1, rm);
 
2012
                    gen_op_vfp_mrrd();
 
2013
                    gen_movl_reg_T0(s, rd);
 
2014
                    gen_movl_reg_T1(s, rn);
3273
2015
                } else {
3274
2016
                    gen_mov_F0_vreg(0, rm);
3275
 
                    tmp = gen_vfp_mrs();
3276
 
                    store_reg(s, rn, tmp);
 
2017
                    gen_op_vfp_mrs();
 
2018
                    gen_movl_reg_T0(s, rn);
3277
2019
                    gen_mov_F0_vreg(0, rm + 1);
3278
 
                    tmp = gen_vfp_mrs();
3279
 
                    store_reg(s, rd, tmp);
 
2020
                    gen_op_vfp_mrs();
 
2021
                    gen_movl_reg_T0(s, rd);
3280
2022
                }
3281
2023
            } else {
3282
2024
                /* arm->vfp */
3283
2025
                if (dp) {
3284
 
                    tmp = load_reg(s, rd);
3285
 
                    gen_vfp_msr(tmp);
3286
 
                    gen_mov_vreg_F0(0, rm * 2);
3287
 
                    tmp = load_reg(s, rn);
3288
 
                    gen_vfp_msr(tmp);
3289
 
                    gen_mov_vreg_F0(0, rm * 2 + 1);
 
2026
                    gen_movl_T0_reg(s, rd);
 
2027
                    gen_movl_T1_reg(s, rn);
 
2028
                    gen_op_vfp_mdrr();
 
2029
                    gen_mov_vreg_F0(1, rm);
3290
2030
                } else {
3291
 
                    tmp = load_reg(s, rn);
3292
 
                    gen_vfp_msr(tmp);
 
2031
                    gen_movl_T0_reg(s, rn);
 
2032
                    gen_op_vfp_msr();
3293
2033
                    gen_mov_vreg_F0(0, rm);
3294
 
                    tmp = load_reg(s, rd);
3295
 
                    gen_vfp_msr(tmp);
 
2034
                    gen_movl_T0_reg(s, rd);
 
2035
                    gen_op_vfp_msr();
3296
2036
                    gen_mov_vreg_F0(0, rm + 1);
3297
2037
                }
3298
2038
            }
3300
2040
            /* Load/store */
3301
2041
            rn = (insn >> 16) & 0xf;
3302
2042
            if (dp)
3303
 
                VFP_DREG_D(rd, insn);
 
2043
                rd = (insn >> 12) & 0xf;
3304
2044
            else
3305
 
                rd = VFP_SREG_D(insn);
3306
 
            if (s->thumb && rn == 15) {
3307
 
                gen_op_movl_T1_im(s->pc & ~2);
3308
 
            } else {
3309
 
                gen_movl_T1_reg(s, rn);
3310
 
            }
 
2045
                rd = ((insn >> 11) & 0x1e) | ((insn >> 22) & 1);
 
2046
            gen_movl_T1_reg(s, rn);
3311
2047
            if ((insn & 0x01200000) == 0x01000000) {
3312
2048
                /* Single load/store */
3313
2049
                offset = (insn & 0xff) << 2;
3376
2112
 
3377
2113
    tb = s->tb;
3378
2114
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3379
 
        tcg_gen_goto_tb(n);
3380
 
        gen_set_pc_im(dest);
3381
 
        tcg_gen_exit_tb((long)tb + n);
 
2115
        if (n == 0)
 
2116
            gen_op_goto_tb0(TBPARAM(tb));
 
2117
        else
 
2118
            gen_op_goto_tb1(TBPARAM(tb));
 
2119
        gen_op_movl_T0_im(dest);
 
2120
        gen_op_movl_r15_T0();
 
2121
        gen_op_movl_T0_im((long)tb + n);
 
2122
        gen_op_exit_tb();
3382
2123
    } else {
3383
 
        gen_set_pc_im(dest);
3384
 
        tcg_gen_exit_tb(0);
 
2124
        gen_op_movl_T0_im(dest);
 
2125
        gen_op_movl_r15_T0();
 
2126
        gen_op_movl_T0_0();
 
2127
        gen_op_exit_tb();
3385
2128
    }
3386
2129
}
3387
2130
 
3388
2131
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3389
2132
{
3390
 
    if (unlikely(s->singlestep_enabled)) {
 
2133
    if (__builtin_expect(s->singlestep_enabled, 0)) {
3391
2134
        /* An indirect jump so that we still trigger the debug exception.  */
3392
2135
        if (s->thumb)
3393
 
            dest |= 1;
3394
 
        gen_bx_im(s, dest);
 
2136
          dest |= 1;
 
2137
        gen_op_movl_T0_im(dest);
 
2138
        gen_bx(s);
3395
2139
    } else {
3396
2140
        gen_goto_tb(s, 0, dest);
3397
2141
        s->is_jmp = DISAS_TB_JUMP;
3398
2142
    }
3399
2143
}
3400
2144
 
3401
 
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
 
2145
static inline void gen_mulxy(int x, int y)
3402
2146
{
3403
2147
    if (x)
3404
 
        tcg_gen_sari_i32(t0, t0, 16);
 
2148
        gen_op_sarl_T0_im(16);
3405
2149
    else
3406
 
        gen_sxth(t0);
 
2150
        gen_op_sxth_T0();
3407
2151
    if (y)
3408
 
        tcg_gen_sari_i32(t1, t1, 16);
 
2152
        gen_op_sarl_T1_im(16);
3409
2153
    else
3410
 
        gen_sxth(t1);
3411
 
    tcg_gen_mul_i32(t0, t0, t1);
 
2154
        gen_op_sxth_T1();
 
2155
    gen_op_mul_T0_T1();
3412
2156
}
3413
2157
 
3414
2158
/* Return the mask of PSR bits set by a MSR instruction.  */
3415
 
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
 
2159
static uint32_t msr_mask(DisasContext *s, int flags, int spsr) {
3416
2160
    uint32_t mask;
3417
2161
 
3418
2162
    mask = 0;
3424
2168
        mask |= 0xff0000;
3425
2169
    if (flags & (1 << 3))
3426
2170
        mask |= 0xff000000;
3427
 
 
3428
2171
    /* Mask out undefined bits.  */
3429
 
    mask &= ~CPSR_RESERVED;
3430
 
    if (!arm_feature(env, ARM_FEATURE_V6))
3431
 
        mask &= ~(CPSR_E | CPSR_GE);
3432
 
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3433
 
        mask &= ~CPSR_IT;
3434
 
    /* Mask out execution state bits.  */
 
2172
    mask &= 0xf90f03ff;
 
2173
    /* Mask out state bits.  */
3435
2174
    if (!spsr)
3436
 
        mask &= ~CPSR_EXEC;
 
2175
        mask &= ~0x01000020;
3437
2176
    /* Mask out privileged bits.  */
3438
2177
    if (IS_USER(s))
3439
 
        mask &= CPSR_USER;
 
2178
        mask &= 0xf80f0200;
3440
2179
    return mask;
3441
2180
}
3442
2181
 
3443
2182
/* Returns nonzero if access to the PSR is not permitted.  */
3444
2183
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3445
2184
{
3446
 
    TCGv tmp;
3447
2185
    if (spsr) {
3448
2186
        /* ??? This is also undefined in system mode.  */
3449
2187
        if (IS_USER(s))
3450
2188
            return 1;
3451
 
 
3452
 
        tmp = load_cpu_field(spsr);
3453
 
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3454
 
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3455
 
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3456
 
        store_cpu_field(tmp, spsr);
 
2189
        gen_op_movl_spsr_T0(mask);
3457
2190
    } else {
3458
 
        gen_set_cpsr(cpu_T[0], mask);
 
2191
        gen_op_movl_cpsr_T0(mask);
3459
2192
    }
3460
2193
    gen_lookup_tb(s);
3461
2194
    return 0;
3462
2195
}
3463
2196
 
3464
 
/* Generate an old-style exception return.  */
3465
2197
static void gen_exception_return(DisasContext *s)
3466
2198
{
3467
 
    TCGv tmp;
3468
 
    gen_movl_reg_T0(s, 15);
3469
 
    tmp = load_cpu_field(spsr);
3470
 
    gen_set_cpsr(tmp, 0xffffffff);
3471
 
    dead_tmp(tmp);
3472
 
    s->is_jmp = DISAS_UPDATE;
3473
 
}
3474
 
 
3475
 
/* Generate a v6 exception return.  Marks both values as dead.  */
3476
 
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3477
 
{
3478
 
    gen_set_cpsr(cpsr, 0xffffffff);
3479
 
    dead_tmp(cpsr);
3480
 
    store_reg(s, 15, pc);
3481
 
    s->is_jmp = DISAS_UPDATE;
3482
 
}
3483
 
 
3484
 
static inline void
3485
 
gen_set_condexec (DisasContext *s)
3486
 
{
3487
 
    if (s->condexec_mask) {
3488
 
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3489
 
        TCGv tmp = new_tmp();
3490
 
        tcg_gen_movi_i32(tmp, val);
3491
 
        store_cpu_field(tmp, condexec_bits);
3492
 
    }
3493
 
}
3494
 
 
3495
 
static void gen_nop_hint(DisasContext *s, int val)
3496
 
{
3497
 
    switch (val) {
3498
 
    case 3: /* wfi */
3499
 
        gen_set_pc_im(s->pc);
3500
 
        s->is_jmp = DISAS_WFI;
3501
 
        break;
3502
 
    case 2: /* wfe */
3503
 
    case 4: /* sev */
3504
 
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3505
 
    default: /* nop */
3506
 
        break;
3507
 
    }
3508
 
}
3509
 
 
3510
 
/* These macros help make the code more readable when migrating from the
3511
 
   old dyngen helpers.  They should probably be removed when
3512
 
   T0/T1 are removed.  */
3513
 
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3514
 
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3515
 
 
3516
 
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3517
 
 
3518
 
static inline int gen_neon_add(int size)
3519
 
{
3520
 
    switch (size) {
3521
 
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3522
 
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3523
 
    case 2: gen_op_addl_T0_T1(); break;
3524
 
    default: return 1;
3525
 
    }
3526
 
    return 0;
3527
 
}
3528
 
 
3529
 
static inline void gen_neon_rsb(int size)
3530
 
{
3531
 
    switch (size) {
3532
 
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3533
 
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3534
 
    case 2: gen_op_rsbl_T0_T1(); break;
3535
 
    default: return;
3536
 
    }
3537
 
}
3538
 
 
3539
 
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3540
 
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3541
 
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3542
 
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3543
 
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3544
 
 
3545
 
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3546
 
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3547
 
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3548
 
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3549
 
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3550
 
 
3551
 
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3552
 
    switch ((size << 1) | u) { \
3553
 
    case 0: \
3554
 
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3555
 
        break; \
3556
 
    case 1: \
3557
 
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3558
 
        break; \
3559
 
    case 2: \
3560
 
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3561
 
        break; \
3562
 
    case 3: \
3563
 
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3564
 
        break; \
3565
 
    case 4: \
3566
 
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3567
 
        break; \
3568
 
    case 5: \
3569
 
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3570
 
        break; \
3571
 
    default: return 1; \
3572
 
    }} while (0)
3573
 
 
3574
 
#define GEN_NEON_INTEGER_OP(name) do { \
3575
 
    switch ((size << 1) | u) { \
3576
 
    case 0: \
3577
 
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3578
 
        break; \
3579
 
    case 1: \
3580
 
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3581
 
        break; \
3582
 
    case 2: \
3583
 
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3584
 
        break; \
3585
 
    case 3: \
3586
 
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3587
 
        break; \
3588
 
    case 4: \
3589
 
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3590
 
        break; \
3591
 
    case 5: \
3592
 
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3593
 
        break; \
3594
 
    default: return 1; \
3595
 
    }} while (0)
3596
 
 
3597
 
static inline void
3598
 
gen_neon_movl_scratch_T0(int scratch)
3599
 
{
3600
 
  uint32_t offset;
3601
 
 
3602
 
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3603
 
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3604
 
}
3605
 
 
3606
 
static inline void
3607
 
gen_neon_movl_scratch_T1(int scratch)
3608
 
{
3609
 
  uint32_t offset;
3610
 
 
3611
 
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3612
 
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3613
 
}
3614
 
 
3615
 
static inline void
3616
 
gen_neon_movl_T0_scratch(int scratch)
3617
 
{
3618
 
  uint32_t offset;
3619
 
 
3620
 
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3621
 
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3622
 
}
3623
 
 
3624
 
static inline void
3625
 
gen_neon_movl_T1_scratch(int scratch)
3626
 
{
3627
 
  uint32_t offset;
3628
 
 
3629
 
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3630
 
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3631
 
}
3632
 
 
3633
 
static inline void gen_neon_get_scalar(int size, int reg)
3634
 
{
3635
 
    if (size == 1) {
3636
 
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3637
 
    } else {
3638
 
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3639
 
        if (reg & 1)
3640
 
            gen_neon_dup_low16(cpu_T[0]);
3641
 
        else
3642
 
            gen_neon_dup_high16(cpu_T[0]);
3643
 
    }
3644
 
}
3645
 
 
3646
 
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3647
 
{
3648
 
    int n;
3649
 
 
3650
 
    for (n = 0; n < q + 1; n += 2) {
3651
 
        NEON_GET_REG(T0, reg, n);
3652
 
        NEON_GET_REG(T0, reg, n + n);
3653
 
        switch (size) {
3654
 
        case 0: gen_helper_neon_unzip_u8(); break;
3655
 
        case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
3656
 
        case 2: /* no-op */; break;
3657
 
        default: abort();
3658
 
        }
3659
 
        gen_neon_movl_scratch_T0(tmp + n);
3660
 
        gen_neon_movl_scratch_T1(tmp + n + 1);
3661
 
    }
3662
 
}
3663
 
 
3664
 
static struct {
3665
 
    int nregs;
3666
 
    int interleave;
3667
 
    int spacing;
3668
 
} neon_ls_element_type[11] = {
3669
 
    {4, 4, 1},
3670
 
    {4, 4, 2},
3671
 
    {4, 1, 1},
3672
 
    {4, 2, 1},
3673
 
    {3, 3, 1},
3674
 
    {3, 3, 2},
3675
 
    {3, 1, 1},
3676
 
    {1, 1, 1},
3677
 
    {2, 2, 1},
3678
 
    {2, 2, 2},
3679
 
    {2, 1, 1}
3680
 
};
3681
 
 
3682
 
/* Translate a NEON load/store element instruction.  Return nonzero if the
3683
 
   instruction is invalid.  */
3684
 
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3685
 
{
3686
 
    int rd, rn, rm;
3687
 
    int op;
3688
 
    int nregs;
3689
 
    int interleave;
3690
 
    int stride;
3691
 
    int size;
3692
 
    int reg;
3693
 
    int pass;
3694
 
    int load;
3695
 
    int shift;
3696
 
    int n;
3697
 
    TCGv tmp;
3698
 
    TCGv tmp2;
3699
 
 
3700
 
    if (!vfp_enabled(env))
3701
 
      return 1;
3702
 
    VFP_DREG_D(rd, insn);
3703
 
    rn = (insn >> 16) & 0xf;
3704
 
    rm = insn & 0xf;
3705
 
    load = (insn & (1 << 21)) != 0;
3706
 
    if ((insn & (1 << 23)) == 0) {
3707
 
        /* Load store all elements.  */
3708
 
        op = (insn >> 8) & 0xf;
3709
 
        size = (insn >> 6) & 3;
3710
 
        if (op > 10 || size == 3)
3711
 
            return 1;
3712
 
        nregs = neon_ls_element_type[op].nregs;
3713
 
        interleave = neon_ls_element_type[op].interleave;
3714
 
        gen_movl_T1_reg(s, rn);
3715
 
        stride = (1 << size) * interleave;
3716
 
        for (reg = 0; reg < nregs; reg++) {
3717
 
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3718
 
                gen_movl_T1_reg(s, rn);
3719
 
                gen_op_addl_T1_im((1 << size) * reg);
3720
 
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3721
 
                gen_movl_T1_reg(s, rn);
3722
 
                gen_op_addl_T1_im(1 << size);
3723
 
            }
3724
 
            for (pass = 0; pass < 2; pass++) {
3725
 
                if (size == 2) {
3726
 
                    if (load) {
3727
 
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3728
 
                        neon_store_reg(rd, pass, tmp);
3729
 
                    } else {
3730
 
                        tmp = neon_load_reg(rd, pass);
3731
 
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3732
 
                    }
3733
 
                    gen_op_addl_T1_im(stride);
3734
 
                } else if (size == 1) {
3735
 
                    if (load) {
3736
 
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3737
 
                        gen_op_addl_T1_im(stride);
3738
 
                        tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3739
 
                        gen_op_addl_T1_im(stride);
3740
 
                        gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3741
 
                        dead_tmp(tmp2);
3742
 
                        neon_store_reg(rd, pass, tmp);
3743
 
                    } else {
3744
 
                        tmp = neon_load_reg(rd, pass);
3745
 
                        tmp2 = new_tmp();
3746
 
                        tcg_gen_shri_i32(tmp2, tmp, 16);
3747
 
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3748
 
                        gen_op_addl_T1_im(stride);
3749
 
                        gen_st16(tmp2, cpu_T[1], IS_USER(s));
3750
 
                        gen_op_addl_T1_im(stride);
3751
 
                    }
3752
 
                } else /* size == 0 */ {
3753
 
                    if (load) {
3754
 
                        TCGV_UNUSED(tmp2);
3755
 
                        for (n = 0; n < 4; n++) {
3756
 
                            tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3757
 
                            gen_op_addl_T1_im(stride);
3758
 
                            if (n == 0) {
3759
 
                                tmp2 = tmp;
3760
 
                            } else {
3761
 
                                gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3762
 
                                dead_tmp(tmp);
3763
 
                            }
3764
 
                        }
3765
 
                        neon_store_reg(rd, pass, tmp2);
3766
 
                    } else {
3767
 
                        tmp2 = neon_load_reg(rd, pass);
3768
 
                        for (n = 0; n < 4; n++) {
3769
 
                            tmp = new_tmp();
3770
 
                            if (n == 0) {
3771
 
                                tcg_gen_mov_i32(tmp, tmp2);
3772
 
                            } else {
3773
 
                                tcg_gen_shri_i32(tmp, tmp2, n * 8);
3774
 
                            }
3775
 
                            gen_st8(tmp, cpu_T[1], IS_USER(s));
3776
 
                            gen_op_addl_T1_im(stride);
3777
 
                        }
3778
 
                        dead_tmp(tmp2);
3779
 
                    }
3780
 
                }
3781
 
            }
3782
 
            rd += neon_ls_element_type[op].spacing;
3783
 
        }
3784
 
        stride = nregs * 8;
3785
 
    } else {
3786
 
        size = (insn >> 10) & 3;
3787
 
        if (size == 3) {
3788
 
            /* Load single element to all lanes.  */
3789
 
            if (!load)
3790
 
                return 1;
3791
 
            size = (insn >> 6) & 3;
3792
 
            nregs = ((insn >> 8) & 3) + 1;
3793
 
            stride = (insn & (1 << 5)) ? 2 : 1;
3794
 
            gen_movl_T1_reg(s, rn);
3795
 
            for (reg = 0; reg < nregs; reg++) {
3796
 
                switch (size) {
3797
 
                case 0:
3798
 
                    tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3799
 
                    gen_neon_dup_u8(tmp, 0);
3800
 
                    break;
3801
 
                case 1:
3802
 
                    tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3803
 
                    gen_neon_dup_low16(tmp);
3804
 
                    break;
3805
 
                case 2:
3806
 
                    tmp = gen_ld32(cpu_T[0], IS_USER(s));
3807
 
                    break;
3808
 
                case 3:
3809
 
                    return 1;
3810
 
                default: /* Avoid compiler warnings.  */
3811
 
                    abort();
3812
 
                }
3813
 
                gen_op_addl_T1_im(1 << size);
3814
 
                tmp2 = new_tmp();
3815
 
                tcg_gen_mov_i32(tmp2, tmp);
3816
 
                neon_store_reg(rd, 0, tmp2);
3817
 
                neon_store_reg(rd, 1, tmp);
3818
 
                rd += stride;
3819
 
            }
3820
 
            stride = (1 << size) * nregs;
3821
 
        } else {
3822
 
            /* Single element.  */
3823
 
            pass = (insn >> 7) & 1;
3824
 
            switch (size) {
3825
 
            case 0:
3826
 
                shift = ((insn >> 5) & 3) * 8;
3827
 
                stride = 1;
3828
 
                break;
3829
 
            case 1:
3830
 
                shift = ((insn >> 6) & 1) * 16;
3831
 
                stride = (insn & (1 << 5)) ? 2 : 1;
3832
 
                break;
3833
 
            case 2:
3834
 
                shift = 0;
3835
 
                stride = (insn & (1 << 6)) ? 2 : 1;
3836
 
                break;
3837
 
            default:
3838
 
                abort();
3839
 
            }
3840
 
            nregs = ((insn >> 8) & 3) + 1;
3841
 
            gen_movl_T1_reg(s, rn);
3842
 
            for (reg = 0; reg < nregs; reg++) {
3843
 
                if (load) {
3844
 
                    switch (size) {
3845
 
                    case 0:
3846
 
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3847
 
                        break;
3848
 
                    case 1:
3849
 
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3850
 
                        break;
3851
 
                    case 2:
3852
 
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3853
 
                        break;
3854
 
                    default: /* Avoid compiler warnings.  */
3855
 
                        abort();
3856
 
                    }
3857
 
                    if (size != 2) {
3858
 
                        tmp2 = neon_load_reg(rd, pass);
3859
 
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3860
 
                        dead_tmp(tmp2);
3861
 
                    }
3862
 
                    neon_store_reg(rd, pass, tmp);
3863
 
                } else { /* Store */
3864
 
                    tmp = neon_load_reg(rd, pass);
3865
 
                    if (shift)
3866
 
                        tcg_gen_shri_i32(tmp, tmp, shift);
3867
 
                    switch (size) {
3868
 
                    case 0:
3869
 
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
3870
 
                        break;
3871
 
                    case 1:
3872
 
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3873
 
                        break;
3874
 
                    case 2:
3875
 
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3876
 
                        break;
3877
 
                    }
3878
 
                }
3879
 
                rd += stride;
3880
 
                gen_op_addl_T1_im(1 << size);
3881
 
            }
3882
 
            stride = nregs * (1 << size);
3883
 
        }
3884
 
    }
3885
 
    if (rm != 15) {
3886
 
        TCGv base;
3887
 
 
3888
 
        base = load_reg(s, rn);
3889
 
        if (rm == 13) {
3890
 
            tcg_gen_addi_i32(base, base, stride);
3891
 
        } else {
3892
 
            TCGv index;
3893
 
            index = load_reg(s, rm);
3894
 
            tcg_gen_add_i32(base, base, index);
3895
 
            dead_tmp(index);
3896
 
        }
3897
 
        store_reg(s, rn, base);
3898
 
    }
3899
 
    return 0;
3900
 
}
3901
 
 
3902
 
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3903
 
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3904
 
{
3905
 
    tcg_gen_and_i32(t, t, c);
3906
 
    tcg_gen_bic_i32(f, f, c);
3907
 
    tcg_gen_or_i32(dest, t, f);
3908
 
}
3909
 
 
3910
 
static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3911
 
{
3912
 
    switch (size) {
3913
 
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3914
 
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3915
 
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3916
 
    default: abort();
3917
 
    }
3918
 
}
3919
 
 
3920
 
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3921
 
{
3922
 
    switch (size) {
3923
 
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3924
 
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3925
 
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3926
 
    default: abort();
3927
 
    }
3928
 
}
3929
 
 
3930
 
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3931
 
{
3932
 
    switch (size) {
3933
 
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3934
 
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3935
 
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3936
 
    default: abort();
3937
 
    }
3938
 
}
3939
 
 
3940
 
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3941
 
                                         int q, int u)
3942
 
{
3943
 
    if (q) {
3944
 
        if (u) {
3945
 
            switch (size) {
3946
 
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3947
 
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3948
 
            default: abort();
3949
 
            }
3950
 
        } else {
3951
 
            switch (size) {
3952
 
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3953
 
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3954
 
            default: abort();
3955
 
            }
3956
 
        }
3957
 
    } else {
3958
 
        if (u) {
3959
 
            switch (size) {
3960
 
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3961
 
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3962
 
            default: abort();
3963
 
            }
3964
 
        } else {
3965
 
            switch (size) {
3966
 
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3967
 
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3968
 
            default: abort();
3969
 
            }
3970
 
        }
3971
 
    }
3972
 
}
3973
 
 
3974
 
static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3975
 
{
3976
 
    if (u) {
3977
 
        switch (size) {
3978
 
        case 0: gen_helper_neon_widen_u8(dest, src); break;
3979
 
        case 1: gen_helper_neon_widen_u16(dest, src); break;
3980
 
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
3981
 
        default: abort();
3982
 
        }
3983
 
    } else {
3984
 
        switch (size) {
3985
 
        case 0: gen_helper_neon_widen_s8(dest, src); break;
3986
 
        case 1: gen_helper_neon_widen_s16(dest, src); break;
3987
 
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
3988
 
        default: abort();
3989
 
        }
3990
 
    }
3991
 
    dead_tmp(src);
3992
 
}
3993
 
 
3994
 
static inline void gen_neon_addl(int size)
3995
 
{
3996
 
    switch (size) {
3997
 
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3998
 
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3999
 
    case 2: tcg_gen_add_i64(CPU_V001); break;
4000
 
    default: abort();
4001
 
    }
4002
 
}
4003
 
 
4004
 
static inline void gen_neon_subl(int size)
4005
 
{
4006
 
    switch (size) {
4007
 
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4008
 
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4009
 
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4010
 
    default: abort();
4011
 
    }
4012
 
}
4013
 
 
4014
 
static inline void gen_neon_negl(TCGv var, int size)
4015
 
{
4016
 
    switch (size) {
4017
 
    case 0: gen_helper_neon_negl_u16(var, var); break;
4018
 
    case 1: gen_helper_neon_negl_u32(var, var); break;
4019
 
    case 2: gen_helper_neon_negl_u64(var, var); break;
4020
 
    default: abort();
4021
 
    }
4022
 
}
4023
 
 
4024
 
static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4025
 
{
4026
 
    switch (size) {
4027
 
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4028
 
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4029
 
    default: abort();
4030
 
    }
4031
 
}
4032
 
 
4033
 
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4034
 
{
4035
 
    TCGv tmp;
4036
 
 
4037
 
    switch ((size << 1) | u) {
4038
 
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4039
 
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4040
 
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4041
 
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4042
 
    case 4:
4043
 
        tmp = gen_muls_i64_i32(a, b);
4044
 
        tcg_gen_mov_i64(dest, tmp);
4045
 
        break;
4046
 
    case 5:
4047
 
        tmp = gen_mulu_i64_i32(a, b);
4048
 
        tcg_gen_mov_i64(dest, tmp);
4049
 
        break;
4050
 
    default: abort();
4051
 
    }
4052
 
    if (size < 2) {
4053
 
        dead_tmp(b);
4054
 
        dead_tmp(a);
4055
 
    }
4056
 
}
4057
 
 
4058
 
/* Translate a NEON data processing instruction.  Return nonzero if the
4059
 
   instruction is invalid.
4060
 
   We process data in a mixture of 32-bit and 64-bit chunks.
4061
 
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4062
 
 
4063
 
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4064
 
{
4065
 
    int op;
4066
 
    int q;
4067
 
    int rd, rn, rm;
4068
 
    int size;
4069
 
    int shift;
4070
 
    int pass;
4071
 
    int count;
4072
 
    int pairwise;
4073
 
    int u;
4074
 
    int n;
4075
 
    uint32_t imm;
4076
 
    TCGv tmp;
4077
 
    TCGv tmp2;
4078
 
    TCGv tmp3;
4079
 
 
4080
 
    if (!vfp_enabled(env))
4081
 
      return 1;
4082
 
    q = (insn & (1 << 6)) != 0;
4083
 
    u = (insn >> 24) & 1;
4084
 
    VFP_DREG_D(rd, insn);
4085
 
    VFP_DREG_N(rn, insn);
4086
 
    VFP_DREG_M(rm, insn);
4087
 
    size = (insn >> 20) & 3;
4088
 
    if ((insn & (1 << 23)) == 0) {
4089
 
        /* Three register same length.  */
4090
 
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4091
 
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4092
 
                          || op == 10 || op  == 11 || op == 16)) {
4093
 
            /* 64-bit element instructions.  */
4094
 
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4095
 
                neon_load_reg64(cpu_V0, rn + pass);
4096
 
                neon_load_reg64(cpu_V1, rm + pass);
4097
 
                switch (op) {
4098
 
                case 1: /* VQADD */
4099
 
                    if (u) {
4100
 
                        gen_helper_neon_add_saturate_u64(CPU_V001);
4101
 
                    } else {
4102
 
                        gen_helper_neon_add_saturate_s64(CPU_V001);
4103
 
                    }
4104
 
                    break;
4105
 
                case 5: /* VQSUB */
4106
 
                    if (u) {
4107
 
                        gen_helper_neon_sub_saturate_u64(CPU_V001);
4108
 
                    } else {
4109
 
                        gen_helper_neon_sub_saturate_s64(CPU_V001);
4110
 
                    }
4111
 
                    break;
4112
 
                case 8: /* VSHL */
4113
 
                    if (u) {
4114
 
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4115
 
                    } else {
4116
 
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4117
 
                    }
4118
 
                    break;
4119
 
                case 9: /* VQSHL */
4120
 
                    if (u) {
4121
 
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4122
 
                                                 cpu_V0, cpu_V0);
4123
 
                    } else {
4124
 
                        gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4125
 
                                                 cpu_V1, cpu_V0);
4126
 
                    }
4127
 
                    break;
4128
 
                case 10: /* VRSHL */
4129
 
                    if (u) {
4130
 
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4131
 
                    } else {
4132
 
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4133
 
                    }
4134
 
                    break;
4135
 
                case 11: /* VQRSHL */
4136
 
                    if (u) {
4137
 
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4138
 
                                                  cpu_V1, cpu_V0);
4139
 
                    } else {
4140
 
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4141
 
                                                  cpu_V1, cpu_V0);
4142
 
                    }
4143
 
                    break;
4144
 
                case 16:
4145
 
                    if (u) {
4146
 
                        tcg_gen_sub_i64(CPU_V001);
4147
 
                    } else {
4148
 
                        tcg_gen_add_i64(CPU_V001);
4149
 
                    }
4150
 
                    break;
4151
 
                default:
4152
 
                    abort();
4153
 
                }
4154
 
                neon_store_reg64(cpu_V0, rd + pass);
4155
 
            }
4156
 
            return 0;
4157
 
        }
4158
 
        switch (op) {
4159
 
        case 8: /* VSHL */
4160
 
        case 9: /* VQSHL */
4161
 
        case 10: /* VRSHL */
4162
 
        case 11: /* VQRSHL */
4163
 
            {
4164
 
                int rtmp;
4165
 
                /* Shift instruction operands are reversed.  */
4166
 
                rtmp = rn;
4167
 
                rn = rm;
4168
 
                rm = rtmp;
4169
 
                pairwise = 0;
4170
 
            }
4171
 
            break;
4172
 
        case 20: /* VPMAX */
4173
 
        case 21: /* VPMIN */
4174
 
        case 23: /* VPADD */
4175
 
            pairwise = 1;
4176
 
            break;
4177
 
        case 26: /* VPADD (float) */
4178
 
            pairwise = (u && size < 2);
4179
 
            break;
4180
 
        case 30: /* VPMIN/VPMAX (float) */
4181
 
            pairwise = u;
4182
 
            break;
4183
 
        default:
4184
 
            pairwise = 0;
4185
 
            break;
4186
 
        }
4187
 
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4188
 
 
4189
 
        if (pairwise) {
4190
 
            /* Pairwise.  */
4191
 
            if (q)
4192
 
                n = (pass & 1) * 2;
4193
 
            else
4194
 
                n = 0;
4195
 
            if (pass < q + 1) {
4196
 
                NEON_GET_REG(T0, rn, n);
4197
 
                NEON_GET_REG(T1, rn, n + 1);
4198
 
            } else {
4199
 
                NEON_GET_REG(T0, rm, n);
4200
 
                NEON_GET_REG(T1, rm, n + 1);
4201
 
            }
4202
 
        } else {
4203
 
            /* Elementwise.  */
4204
 
            NEON_GET_REG(T0, rn, pass);
4205
 
            NEON_GET_REG(T1, rm, pass);
4206
 
        }
4207
 
        switch (op) {
4208
 
        case 0: /* VHADD */
4209
 
            GEN_NEON_INTEGER_OP(hadd);
4210
 
            break;
4211
 
        case 1: /* VQADD */
4212
 
            GEN_NEON_INTEGER_OP_ENV(qadd);
4213
 
            break;
4214
 
        case 2: /* VRHADD */
4215
 
            GEN_NEON_INTEGER_OP(rhadd);
4216
 
            break;
4217
 
        case 3: /* Logic ops.  */
4218
 
            switch ((u << 2) | size) {
4219
 
            case 0: /* VAND */
4220
 
                gen_op_andl_T0_T1();
4221
 
                break;
4222
 
            case 1: /* BIC */
4223
 
                gen_op_bicl_T0_T1();
4224
 
                break;
4225
 
            case 2: /* VORR */
4226
 
                gen_op_orl_T0_T1();
4227
 
                break;
4228
 
            case 3: /* VORN */
4229
 
                gen_op_notl_T1();
4230
 
                gen_op_orl_T0_T1();
4231
 
                break;
4232
 
            case 4: /* VEOR */
4233
 
                gen_op_xorl_T0_T1();
4234
 
                break;
4235
 
            case 5: /* VBSL */
4236
 
                tmp = neon_load_reg(rd, pass);
4237
 
                gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4238
 
                dead_tmp(tmp);
4239
 
                break;
4240
 
            case 6: /* VBIT */
4241
 
                tmp = neon_load_reg(rd, pass);
4242
 
                gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4243
 
                dead_tmp(tmp);
4244
 
                break;
4245
 
            case 7: /* VBIF */
4246
 
                tmp = neon_load_reg(rd, pass);
4247
 
                gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4248
 
                dead_tmp(tmp);
4249
 
                break;
4250
 
            }
4251
 
            break;
4252
 
        case 4: /* VHSUB */
4253
 
            GEN_NEON_INTEGER_OP(hsub);
4254
 
            break;
4255
 
        case 5: /* VQSUB */
4256
 
            GEN_NEON_INTEGER_OP_ENV(qsub);
4257
 
            break;
4258
 
        case 6: /* VCGT */
4259
 
            GEN_NEON_INTEGER_OP(cgt);
4260
 
            break;
4261
 
        case 7: /* VCGE */
4262
 
            GEN_NEON_INTEGER_OP(cge);
4263
 
            break;
4264
 
        case 8: /* VSHL */
4265
 
            GEN_NEON_INTEGER_OP(shl);
4266
 
            break;
4267
 
        case 9: /* VQSHL */
4268
 
            GEN_NEON_INTEGER_OP_ENV(qshl);
4269
 
            break;
4270
 
        case 10: /* VRSHL */
4271
 
            GEN_NEON_INTEGER_OP(rshl);
4272
 
            break;
4273
 
        case 11: /* VQRSHL */
4274
 
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4275
 
            break;
4276
 
        case 12: /* VMAX */
4277
 
            GEN_NEON_INTEGER_OP(max);
4278
 
            break;
4279
 
        case 13: /* VMIN */
4280
 
            GEN_NEON_INTEGER_OP(min);
4281
 
            break;
4282
 
        case 14: /* VABD */
4283
 
            GEN_NEON_INTEGER_OP(abd);
4284
 
            break;
4285
 
        case 15: /* VABA */
4286
 
            GEN_NEON_INTEGER_OP(abd);
4287
 
            NEON_GET_REG(T1, rd, pass);
4288
 
            gen_neon_add(size);
4289
 
            break;
4290
 
        case 16:
4291
 
            if (!u) { /* VADD */
4292
 
                if (gen_neon_add(size))
4293
 
                    return 1;
4294
 
            } else { /* VSUB */
4295
 
                switch (size) {
4296
 
                case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4297
 
                case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4298
 
                case 2: gen_op_subl_T0_T1(); break;
4299
 
                default: return 1;
4300
 
                }
4301
 
            }
4302
 
            break;
4303
 
        case 17:
4304
 
            if (!u) { /* VTST */
4305
 
                switch (size) {
4306
 
                case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4307
 
                case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4308
 
                case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4309
 
                default: return 1;
4310
 
                }
4311
 
            } else { /* VCEQ */
4312
 
                switch (size) {
4313
 
                case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4314
 
                case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4315
 
                case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4316
 
                default: return 1;
4317
 
                }
4318
 
            }
4319
 
            break;
4320
 
        case 18: /* Multiply.  */
4321
 
            switch (size) {
4322
 
            case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4323
 
            case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4324
 
            case 2: gen_op_mul_T0_T1(); break;
4325
 
            default: return 1;
4326
 
            }
4327
 
            NEON_GET_REG(T1, rd, pass);
4328
 
            if (u) { /* VMLS */
4329
 
                gen_neon_rsb(size);
4330
 
            } else { /* VMLA */
4331
 
                gen_neon_add(size);
4332
 
            }
4333
 
            break;
4334
 
        case 19: /* VMUL */
4335
 
            if (u) { /* polynomial */
4336
 
                gen_helper_neon_mul_p8(CPU_T001);
4337
 
            } else { /* Integer */
4338
 
                switch (size) {
4339
 
                case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4340
 
                case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4341
 
                case 2: gen_op_mul_T0_T1(); break;
4342
 
                default: return 1;
4343
 
                }
4344
 
            }
4345
 
            break;
4346
 
        case 20: /* VPMAX */
4347
 
            GEN_NEON_INTEGER_OP(pmax);
4348
 
            break;
4349
 
        case 21: /* VPMIN */
4350
 
            GEN_NEON_INTEGER_OP(pmin);
4351
 
            break;
4352
 
        case 22: /* Hultiply high.  */
4353
 
            if (!u) { /* VQDMULH */
4354
 
                switch (size) {
4355
 
                case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4356
 
                case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4357
 
                default: return 1;
4358
 
                }
4359
 
            } else { /* VQRDHMUL */
4360
 
                switch (size) {
4361
 
                case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4362
 
                case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4363
 
                default: return 1;
4364
 
                }
4365
 
            }
4366
 
            break;
4367
 
        case 23: /* VPADD */
4368
 
            if (u)
4369
 
                return 1;
4370
 
            switch (size) {
4371
 
            case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4372
 
            case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4373
 
            case 2: gen_op_addl_T0_T1(); break;
4374
 
            default: return 1;
4375
 
            }
4376
 
            break;
4377
 
        case 26: /* Floating point arithnetic.  */
4378
 
            switch ((u << 2) | size) {
4379
 
            case 0: /* VADD */
4380
 
                gen_helper_neon_add_f32(CPU_T001);
4381
 
                break;
4382
 
            case 2: /* VSUB */
4383
 
                gen_helper_neon_sub_f32(CPU_T001);
4384
 
                break;
4385
 
            case 4: /* VPADD */
4386
 
                gen_helper_neon_add_f32(CPU_T001);
4387
 
                break;
4388
 
            case 6: /* VABD */
4389
 
                gen_helper_neon_abd_f32(CPU_T001);
4390
 
                break;
4391
 
            default:
4392
 
                return 1;
4393
 
            }
4394
 
            break;
4395
 
        case 27: /* Float multiply.  */
4396
 
            gen_helper_neon_mul_f32(CPU_T001);
4397
 
            if (!u) {
4398
 
                NEON_GET_REG(T1, rd, pass);
4399
 
                if (size == 0) {
4400
 
                    gen_helper_neon_add_f32(CPU_T001);
4401
 
                } else {
4402
 
                    gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4403
 
                }
4404
 
            }
4405
 
            break;
4406
 
        case 28: /* Float compare.  */
4407
 
            if (!u) {
4408
 
                gen_helper_neon_ceq_f32(CPU_T001);
4409
 
            } else {
4410
 
                if (size == 0)
4411
 
                    gen_helper_neon_cge_f32(CPU_T001);
4412
 
                else
4413
 
                    gen_helper_neon_cgt_f32(CPU_T001);
4414
 
            }
4415
 
            break;
4416
 
        case 29: /* Float compare absolute.  */
4417
 
            if (!u)
4418
 
                return 1;
4419
 
            if (size == 0)
4420
 
                gen_helper_neon_acge_f32(CPU_T001);
4421
 
            else
4422
 
                gen_helper_neon_acgt_f32(CPU_T001);
4423
 
            break;
4424
 
        case 30: /* Float min/max.  */
4425
 
            if (size == 0)
4426
 
                gen_helper_neon_max_f32(CPU_T001);
4427
 
            else
4428
 
                gen_helper_neon_min_f32(CPU_T001);
4429
 
            break;
4430
 
        case 31:
4431
 
            if (size == 0)
4432
 
                gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4433
 
            else
4434
 
                gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4435
 
            break;
4436
 
        default:
4437
 
            abort();
4438
 
        }
4439
 
        /* Save the result.  For elementwise operations we can put it
4440
 
           straight into the destination register.  For pairwise operations
4441
 
           we have to be careful to avoid clobbering the source operands.  */
4442
 
        if (pairwise && rd == rm) {
4443
 
            gen_neon_movl_scratch_T0(pass);
4444
 
        } else {
4445
 
            NEON_SET_REG(T0, rd, pass);
4446
 
        }
4447
 
 
4448
 
        } /* for pass */
4449
 
        if (pairwise && rd == rm) {
4450
 
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4451
 
                gen_neon_movl_T0_scratch(pass);
4452
 
                NEON_SET_REG(T0, rd, pass);
4453
 
            }
4454
 
        }
4455
 
        /* End of 3 register same size operations.  */
4456
 
    } else if (insn & (1 << 4)) {
4457
 
        if ((insn & 0x00380080) != 0) {
4458
 
            /* Two registers and shift.  */
4459
 
            op = (insn >> 8) & 0xf;
4460
 
            if (insn & (1 << 7)) {
4461
 
                /* 64-bit shift.   */
4462
 
                size = 3;
4463
 
            } else {
4464
 
                size = 2;
4465
 
                while ((insn & (1 << (size + 19))) == 0)
4466
 
                    size--;
4467
 
            }
4468
 
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4469
 
            /* To avoid excessive dumplication of ops we implement shift
4470
 
               by immediate using the variable shift operations.  */
4471
 
            if (op < 8) {
4472
 
                /* Shift by immediate:
4473
 
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4474
 
                /* Right shifts are encoded as N - shift, where N is the
4475
 
                   element size in bits.  */
4476
 
                if (op <= 4)
4477
 
                    shift = shift - (1 << (size + 3));
4478
 
                if (size == 3) {
4479
 
                    count = q + 1;
4480
 
                } else {
4481
 
                    count = q ? 4: 2;
4482
 
                }
4483
 
                switch (size) {
4484
 
                case 0:
4485
 
                    imm = (uint8_t) shift;
4486
 
                    imm |= imm << 8;
4487
 
                    imm |= imm << 16;
4488
 
                    break;
4489
 
                case 1:
4490
 
                    imm = (uint16_t) shift;
4491
 
                    imm |= imm << 16;
4492
 
                    break;
4493
 
                case 2:
4494
 
                case 3:
4495
 
                    imm = shift;
4496
 
                    break;
4497
 
                default:
4498
 
                    abort();
4499
 
                }
4500
 
 
4501
 
                for (pass = 0; pass < count; pass++) {
4502
 
                    if (size == 3) {
4503
 
                        neon_load_reg64(cpu_V0, rm + pass);
4504
 
                        tcg_gen_movi_i64(cpu_V1, imm);
4505
 
                        switch (op) {
4506
 
                        case 0:  /* VSHR */
4507
 
                        case 1:  /* VSRA */
4508
 
                            if (u)
4509
 
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4510
 
                            else
4511
 
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4512
 
                            break;
4513
 
                        case 2: /* VRSHR */
4514
 
                        case 3: /* VRSRA */
4515
 
                            if (u)
4516
 
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4517
 
                            else
4518
 
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4519
 
                            break;
4520
 
                        case 4: /* VSRI */
4521
 
                            if (!u)
4522
 
                                return 1;
4523
 
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4524
 
                            break;
4525
 
                        case 5: /* VSHL, VSLI */
4526
 
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4527
 
                            break;
4528
 
                        case 6: /* VQSHL */
4529
 
                            if (u)
4530
 
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4531
 
                            else
4532
 
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4533
 
                            break;
4534
 
                        case 7: /* VQSHLU */
4535
 
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4536
 
                            break;
4537
 
                        }
4538
 
                        if (op == 1 || op == 3) {
4539
 
                            /* Accumulate.  */
4540
 
                            neon_load_reg64(cpu_V0, rd + pass);
4541
 
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4542
 
                        } else if (op == 4 || (op == 5 && u)) {
4543
 
                            /* Insert */
4544
 
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4545
 
                        }
4546
 
                        neon_store_reg64(cpu_V0, rd + pass);
4547
 
                    } else { /* size < 3 */
4548
 
                        /* Operands in T0 and T1.  */
4549
 
                        gen_op_movl_T1_im(imm);
4550
 
                        NEON_GET_REG(T0, rm, pass);
4551
 
                        switch (op) {
4552
 
                        case 0:  /* VSHR */
4553
 
                        case 1:  /* VSRA */
4554
 
                            GEN_NEON_INTEGER_OP(shl);
4555
 
                            break;
4556
 
                        case 2: /* VRSHR */
4557
 
                        case 3: /* VRSRA */
4558
 
                            GEN_NEON_INTEGER_OP(rshl);
4559
 
                            break;
4560
 
                        case 4: /* VSRI */
4561
 
                            if (!u)
4562
 
                                return 1;
4563
 
                            GEN_NEON_INTEGER_OP(shl);
4564
 
                            break;
4565
 
                        case 5: /* VSHL, VSLI */
4566
 
                            switch (size) {
4567
 
                            case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4568
 
                            case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4569
 
                            case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4570
 
                            default: return 1;
4571
 
                            }
4572
 
                            break;
4573
 
                        case 6: /* VQSHL */
4574
 
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4575
 
                            break;
4576
 
                        case 7: /* VQSHLU */
4577
 
                            switch (size) {
4578
 
                            case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4579
 
                            case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4580
 
                            case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4581
 
                            default: return 1;
4582
 
                            }
4583
 
                            break;
4584
 
                        }
4585
 
 
4586
 
                        if (op == 1 || op == 3) {
4587
 
                            /* Accumulate.  */
4588
 
                            NEON_GET_REG(T1, rd, pass);
4589
 
                            gen_neon_add(size);
4590
 
                        } else if (op == 4 || (op == 5 && u)) {
4591
 
                            /* Insert */
4592
 
                            switch (size) {
4593
 
                            case 0:
4594
 
                                if (op == 4)
4595
 
                                    imm = 0xff >> -shift;
4596
 
                                else
4597
 
                                    imm = (uint8_t)(0xff << shift);
4598
 
                                imm |= imm << 8;
4599
 
                                imm |= imm << 16;
4600
 
                                break;
4601
 
                            case 1:
4602
 
                                if (op == 4)
4603
 
                                    imm = 0xffff >> -shift;
4604
 
                                else
4605
 
                                    imm = (uint16_t)(0xffff << shift);
4606
 
                                imm |= imm << 16;
4607
 
                                break;
4608
 
                            case 2:
4609
 
                                if (op == 4)
4610
 
                                    imm = 0xffffffffu >> -shift;
4611
 
                                else
4612
 
                                    imm = 0xffffffffu << shift;
4613
 
                                break;
4614
 
                            default:
4615
 
                                abort();
4616
 
                            }
4617
 
                            tmp = neon_load_reg(rd, pass);
4618
 
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4619
 
                            tcg_gen_andi_i32(tmp, tmp, ~imm);
4620
 
                            tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4621
 
                        }
4622
 
                        NEON_SET_REG(T0, rd, pass);
4623
 
                    }
4624
 
                } /* for pass */
4625
 
            } else if (op < 10) {
4626
 
                /* Shift by immediate and narrow:
4627
 
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4628
 
                shift = shift - (1 << (size + 3));
4629
 
                size++;
4630
 
                switch (size) {
4631
 
                case 1:
4632
 
                    imm = (uint16_t)shift;
4633
 
                    imm |= imm << 16;
4634
 
                    tmp2 = tcg_const_i32(imm);
4635
 
                    break;
4636
 
                case 2:
4637
 
                    imm = (uint32_t)shift;
4638
 
                    tmp2 = tcg_const_i32(imm);
4639
 
                case 3:
4640
 
                    tmp2 = tcg_const_i64(shift);
4641
 
                    break;
4642
 
                default:
4643
 
                    abort();
4644
 
                }
4645
 
 
4646
 
                for (pass = 0; pass < 2; pass++) {
4647
 
                    if (size == 3) {
4648
 
                        neon_load_reg64(cpu_V0, rm + pass);
4649
 
                        if (q) {
4650
 
                          if (u)
4651
 
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4652
 
                          else
4653
 
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4654
 
                        } else {
4655
 
                          if (u)
4656
 
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4657
 
                          else
4658
 
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4659
 
                        }
4660
 
                    } else {
4661
 
                        tmp = neon_load_reg(rm + pass, 0);
4662
 
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4663
 
                        tmp3 = neon_load_reg(rm + pass, 1);
4664
 
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4665
 
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4666
 
                        dead_tmp(tmp);
4667
 
                        dead_tmp(tmp3);
4668
 
                    }
4669
 
                    tmp = new_tmp();
4670
 
                    if (op == 8 && !u) {
4671
 
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4672
 
                    } else {
4673
 
                        if (op == 8)
4674
 
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4675
 
                        else
4676
 
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4677
 
                    }
4678
 
                    if (pass == 0) {
4679
 
                        tmp2 = tmp;
4680
 
                    } else {
4681
 
                        neon_store_reg(rd, 0, tmp2);
4682
 
                        neon_store_reg(rd, 1, tmp);
4683
 
                    }
4684
 
                } /* for pass */
4685
 
            } else if (op == 10) {
4686
 
                /* VSHLL */
4687
 
                if (q || size == 3)
4688
 
                    return 1;
4689
 
                tmp = neon_load_reg(rm, 0);
4690
 
                tmp2 = neon_load_reg(rm, 1);
4691
 
                for (pass = 0; pass < 2; pass++) {
4692
 
                    if (pass == 1)
4693
 
                        tmp = tmp2;
4694
 
 
4695
 
                    gen_neon_widen(cpu_V0, tmp, size, u);
4696
 
 
4697
 
                    if (shift != 0) {
4698
 
                        /* The shift is less than the width of the source
4699
 
                           type, so we can just shift the whole register.  */
4700
 
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4701
 
                        if (size < 2 || !u) {
4702
 
                            uint64_t imm64;
4703
 
                            if (size == 0) {
4704
 
                                imm = (0xffu >> (8 - shift));
4705
 
                                imm |= imm << 16;
4706
 
                            } else {
4707
 
                                imm = 0xffff >> (16 - shift);
4708
 
                            }
4709
 
                            imm64 = imm | (((uint64_t)imm) << 32);
4710
 
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4711
 
                        }
4712
 
                    }
4713
 
                    neon_store_reg64(cpu_V0, rd + pass);
4714
 
                }
4715
 
            } else if (op == 15 || op == 16) {
4716
 
                /* VCVT fixed-point.  */
4717
 
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4718
 
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4719
 
                    if (op & 1) {
4720
 
                        if (u)
4721
 
                            gen_vfp_ulto(0, shift);
4722
 
                        else
4723
 
                            gen_vfp_slto(0, shift);
4724
 
                    } else {
4725
 
                        if (u)
4726
 
                            gen_vfp_toul(0, shift);
4727
 
                        else
4728
 
                            gen_vfp_tosl(0, shift);
4729
 
                    }
4730
 
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4731
 
                }
4732
 
            } else {
4733
 
                return 1;
4734
 
            }
4735
 
        } else { /* (insn & 0x00380080) == 0 */
4736
 
            int invert;
4737
 
 
4738
 
            op = (insn >> 8) & 0xf;
4739
 
            /* One register and immediate.  */
4740
 
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4741
 
            invert = (insn & (1 << 5)) != 0;
4742
 
            switch (op) {
4743
 
            case 0: case 1:
4744
 
                /* no-op */
4745
 
                break;
4746
 
            case 2: case 3:
4747
 
                imm <<= 8;
4748
 
                break;
4749
 
            case 4: case 5:
4750
 
                imm <<= 16;
4751
 
                break;
4752
 
            case 6: case 7:
4753
 
                imm <<= 24;
4754
 
                break;
4755
 
            case 8: case 9:
4756
 
                imm |= imm << 16;
4757
 
                break;
4758
 
            case 10: case 11:
4759
 
                imm = (imm << 8) | (imm << 24);
4760
 
                break;
4761
 
            case 12:
4762
 
                imm = (imm < 8) | 0xff;
4763
 
                break;
4764
 
            case 13:
4765
 
                imm = (imm << 16) | 0xffff;
4766
 
                break;
4767
 
            case 14:
4768
 
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4769
 
                if (invert)
4770
 
                    imm = ~imm;
4771
 
                break;
4772
 
            case 15:
4773
 
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4774
 
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4775
 
                break;
4776
 
            }
4777
 
            if (invert)
4778
 
                imm = ~imm;
4779
 
 
4780
 
            if (op != 14 || !invert)
4781
 
                gen_op_movl_T1_im(imm);
4782
 
 
4783
 
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4784
 
                if (op & 1 && op < 12) {
4785
 
                    tmp = neon_load_reg(rd, pass);
4786
 
                    if (invert) {
4787
 
                        /* The immediate value has already been inverted, so
4788
 
                           BIC becomes AND.  */
4789
 
                        tcg_gen_andi_i32(tmp, tmp, imm);
4790
 
                    } else {
4791
 
                        tcg_gen_ori_i32(tmp, tmp, imm);
4792
 
                    }
4793
 
                } else {
4794
 
                    /* VMOV, VMVN.  */
4795
 
                    tmp = new_tmp();
4796
 
                    if (op == 14 && invert) {
4797
 
                        uint32_t val;
4798
 
                        val = 0;
4799
 
                        for (n = 0; n < 4; n++) {
4800
 
                            if (imm & (1 << (n + (pass & 1) * 4)))
4801
 
                                val |= 0xff << (n * 8);
4802
 
                        }
4803
 
                        tcg_gen_movi_i32(tmp, val);
4804
 
                    } else {
4805
 
                        tcg_gen_movi_i32(tmp, imm);
4806
 
                    }
4807
 
                }
4808
 
                neon_store_reg(rd, pass, tmp);
4809
 
            }
4810
 
        }
4811
 
    } else { /* (insn & 0x00800010 == 0x00800000) */
4812
 
        if (size != 3) {
4813
 
            op = (insn >> 8) & 0xf;
4814
 
            if ((insn & (1 << 6)) == 0) {
4815
 
                /* Three registers of different lengths.  */
4816
 
                int src1_wide;
4817
 
                int src2_wide;
4818
 
                int prewiden;
4819
 
                /* prewiden, src1_wide, src2_wide */
4820
 
                static const int neon_3reg_wide[16][3] = {
4821
 
                    {1, 0, 0}, /* VADDL */
4822
 
                    {1, 1, 0}, /* VADDW */
4823
 
                    {1, 0, 0}, /* VSUBL */
4824
 
                    {1, 1, 0}, /* VSUBW */
4825
 
                    {0, 1, 1}, /* VADDHN */
4826
 
                    {0, 0, 0}, /* VABAL */
4827
 
                    {0, 1, 1}, /* VSUBHN */
4828
 
                    {0, 0, 0}, /* VABDL */
4829
 
                    {0, 0, 0}, /* VMLAL */
4830
 
                    {0, 0, 0}, /* VQDMLAL */
4831
 
                    {0, 0, 0}, /* VMLSL */
4832
 
                    {0, 0, 0}, /* VQDMLSL */
4833
 
                    {0, 0, 0}, /* Integer VMULL */
4834
 
                    {0, 0, 0}, /* VQDMULL */
4835
 
                    {0, 0, 0}  /* Polynomial VMULL */
4836
 
                };
4837
 
 
4838
 
                prewiden = neon_3reg_wide[op][0];
4839
 
                src1_wide = neon_3reg_wide[op][1];
4840
 
                src2_wide = neon_3reg_wide[op][2];
4841
 
 
4842
 
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4843
 
                    return 1;
4844
 
 
4845
 
                /* Avoid overlapping operands.  Wide source operands are
4846
 
                   always aligned so will never overlap with wide
4847
 
                   destinations in problematic ways.  */
4848
 
                if (rd == rm && !src2_wide) {
4849
 
                    NEON_GET_REG(T0, rm, 1);
4850
 
                    gen_neon_movl_scratch_T0(2);
4851
 
                } else if (rd == rn && !src1_wide) {
4852
 
                    NEON_GET_REG(T0, rn, 1);
4853
 
                    gen_neon_movl_scratch_T0(2);
4854
 
                }
4855
 
                TCGV_UNUSED(tmp3);
4856
 
                for (pass = 0; pass < 2; pass++) {
4857
 
                    if (src1_wide) {
4858
 
                        neon_load_reg64(cpu_V0, rn + pass);
4859
 
                        TCGV_UNUSED(tmp);
4860
 
                    } else {
4861
 
                        if (pass == 1 && rd == rn) {
4862
 
                            gen_neon_movl_T0_scratch(2);
4863
 
                            tmp = new_tmp();
4864
 
                            tcg_gen_mov_i32(tmp, cpu_T[0]);
4865
 
                        } else {
4866
 
                            tmp = neon_load_reg(rn, pass);
4867
 
                        }
4868
 
                        if (prewiden) {
4869
 
                            gen_neon_widen(cpu_V0, tmp, size, u);
4870
 
                        }
4871
 
                    }
4872
 
                    if (src2_wide) {
4873
 
                        neon_load_reg64(cpu_V1, rm + pass);
4874
 
                        TCGV_UNUSED(tmp2);
4875
 
                    } else {
4876
 
                        if (pass == 1 && rd == rm) {
4877
 
                            gen_neon_movl_T0_scratch(2);
4878
 
                            tmp2 = new_tmp();
4879
 
                            tcg_gen_mov_i32(tmp2, cpu_T[0]);
4880
 
                        } else {
4881
 
                            tmp2 = neon_load_reg(rm, pass);
4882
 
                        }
4883
 
                        if (prewiden) {
4884
 
                            gen_neon_widen(cpu_V1, tmp2, size, u);
4885
 
                        }
4886
 
                    }
4887
 
                    switch (op) {
4888
 
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4889
 
                        gen_neon_addl(size);
4890
 
                        break;
4891
 
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4892
 
                        gen_neon_subl(size);
4893
 
                        break;
4894
 
                    case 5: case 7: /* VABAL, VABDL */
4895
 
                        switch ((size << 1) | u) {
4896
 
                        case 0:
4897
 
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4898
 
                            break;
4899
 
                        case 1:
4900
 
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4901
 
                            break;
4902
 
                        case 2:
4903
 
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4904
 
                            break;
4905
 
                        case 3:
4906
 
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4907
 
                            break;
4908
 
                        case 4:
4909
 
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4910
 
                            break;
4911
 
                        case 5:
4912
 
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4913
 
                            break;
4914
 
                        default: abort();
4915
 
                        }
4916
 
                        dead_tmp(tmp2);
4917
 
                        dead_tmp(tmp);
4918
 
                        break;
4919
 
                    case 8: case 9: case 10: case 11: case 12: case 13:
4920
 
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4921
 
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4922
 
                        break;
4923
 
                    case 14: /* Polynomial VMULL */
4924
 
                        cpu_abort(env, "Polynomial VMULL not implemented");
4925
 
 
4926
 
                    default: /* 15 is RESERVED.  */
4927
 
                        return 1;
4928
 
                    }
4929
 
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4930
 
                        /* Accumulate.  */
4931
 
                        if (op == 10 || op == 11) {
4932
 
                            gen_neon_negl(cpu_V0, size);
4933
 
                        }
4934
 
 
4935
 
                        if (op != 13) {
4936
 
                            neon_load_reg64(cpu_V1, rd + pass);
4937
 
                        }
4938
 
 
4939
 
                        switch (op) {
4940
 
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4941
 
                            gen_neon_addl(size);
4942
 
                            break;
4943
 
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
4944
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4945
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4946
 
                            break;
4947
 
                            /* Fall through.  */
4948
 
                        case 13: /* VQDMULL */
4949
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4950
 
                            break;
4951
 
                        default:
4952
 
                            abort();
4953
 
                        }
4954
 
                        neon_store_reg64(cpu_V0, rd + pass);
4955
 
                    } else if (op == 4 || op == 6) {
4956
 
                        /* Narrowing operation.  */
4957
 
                        tmp = new_tmp();
4958
 
                        if (u) {
4959
 
                            switch (size) {
4960
 
                            case 0:
4961
 
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4962
 
                                break;
4963
 
                            case 1:
4964
 
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4965
 
                                break;
4966
 
                            case 2:
4967
 
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4968
 
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4969
 
                                break;
4970
 
                            default: abort();
4971
 
                            }
4972
 
                        } else {
4973
 
                            switch (size) {
4974
 
                            case 0:
4975
 
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4976
 
                                break;
4977
 
                            case 1:
4978
 
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4979
 
                                break;
4980
 
                            case 2:
4981
 
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4982
 
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4983
 
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4984
 
                                break;
4985
 
                            default: abort();
4986
 
                            }
4987
 
                        }
4988
 
                        if (pass == 0) {
4989
 
                            tmp3 = tmp;
4990
 
                        } else {
4991
 
                            neon_store_reg(rd, 0, tmp3);
4992
 
                            neon_store_reg(rd, 1, tmp);
4993
 
                        }
4994
 
                    } else {
4995
 
                        /* Write back the result.  */
4996
 
                        neon_store_reg64(cpu_V0, rd + pass);
4997
 
                    }
4998
 
                }
4999
 
            } else {
5000
 
                /* Two registers and a scalar.  */
5001
 
                switch (op) {
5002
 
                case 0: /* Integer VMLA scalar */
5003
 
                case 1: /* Float VMLA scalar */
5004
 
                case 4: /* Integer VMLS scalar */
5005
 
                case 5: /* Floating point VMLS scalar */
5006
 
                case 8: /* Integer VMUL scalar */
5007
 
                case 9: /* Floating point VMUL scalar */
5008
 
                case 12: /* VQDMULH scalar */
5009
 
                case 13: /* VQRDMULH scalar */
5010
 
                    gen_neon_get_scalar(size, rm);
5011
 
                    gen_neon_movl_scratch_T0(0);
5012
 
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5013
 
                        if (pass != 0)
5014
 
                            gen_neon_movl_T0_scratch(0);
5015
 
                        NEON_GET_REG(T1, rn, pass);
5016
 
                        if (op == 12) {
5017
 
                            if (size == 1) {
5018
 
                                gen_helper_neon_qdmulh_s16(CPU_T0E01);
5019
 
                            } else {
5020
 
                                gen_helper_neon_qdmulh_s32(CPU_T0E01);
5021
 
                            }
5022
 
                        } else if (op == 13) {
5023
 
                            if (size == 1) {
5024
 
                                gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5025
 
                            } else {
5026
 
                                gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5027
 
                            }
5028
 
                        } else if (op & 1) {
5029
 
                            gen_helper_neon_mul_f32(CPU_T001);
5030
 
                        } else {
5031
 
                            switch (size) {
5032
 
                            case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5033
 
                            case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5034
 
                            case 2: gen_op_mul_T0_T1(); break;
5035
 
                            default: return 1;
5036
 
                            }
5037
 
                        }
5038
 
                        if (op < 8) {
5039
 
                            /* Accumulate.  */
5040
 
                            NEON_GET_REG(T1, rd, pass);
5041
 
                            switch (op) {
5042
 
                            case 0:
5043
 
                                gen_neon_add(size);
5044
 
                                break;
5045
 
                            case 1:
5046
 
                                gen_helper_neon_add_f32(CPU_T001);
5047
 
                                break;
5048
 
                            case 4:
5049
 
                                gen_neon_rsb(size);
5050
 
                                break;
5051
 
                            case 5:
5052
 
                                gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5053
 
                                break;
5054
 
                            default:
5055
 
                                abort();
5056
 
                            }
5057
 
                        }
5058
 
                        NEON_SET_REG(T0, rd, pass);
5059
 
                    }
5060
 
                    break;
5061
 
                case 2: /* VMLAL sclar */
5062
 
                case 3: /* VQDMLAL scalar */
5063
 
                case 6: /* VMLSL scalar */
5064
 
                case 7: /* VQDMLSL scalar */
5065
 
                case 10: /* VMULL scalar */
5066
 
                case 11: /* VQDMULL scalar */
5067
 
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5068
 
                        return 1;
5069
 
 
5070
 
                    gen_neon_get_scalar(size, rm);
5071
 
                    NEON_GET_REG(T1, rn, 1);
5072
 
 
5073
 
                    for (pass = 0; pass < 2; pass++) {
5074
 
                        if (pass == 0) {
5075
 
                            tmp = neon_load_reg(rn, 0);
5076
 
                        } else {
5077
 
                            tmp = new_tmp();
5078
 
                            tcg_gen_mov_i32(tmp, cpu_T[1]);
5079
 
                        }
5080
 
                        tmp2 = new_tmp();
5081
 
                        tcg_gen_mov_i32(tmp2, cpu_T[0]);
5082
 
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5083
 
                        if (op == 6 || op == 7) {
5084
 
                            gen_neon_negl(cpu_V0, size);
5085
 
                        }
5086
 
                        if (op != 11) {
5087
 
                            neon_load_reg64(cpu_V1, rd + pass);
5088
 
                        }
5089
 
                        switch (op) {
5090
 
                        case 2: case 6:
5091
 
                            gen_neon_addl(size);
5092
 
                            break;
5093
 
                        case 3: case 7:
5094
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5095
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5096
 
                            break;
5097
 
                        case 10:
5098
 
                            /* no-op */
5099
 
                            break;
5100
 
                        case 11:
5101
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5102
 
                            break;
5103
 
                        default:
5104
 
                            abort();
5105
 
                        }
5106
 
                        neon_store_reg64(cpu_V0, rd + pass);
5107
 
                    }
5108
 
                    break;
5109
 
                default: /* 14 and 15 are RESERVED */
5110
 
                    return 1;
5111
 
                }
5112
 
            }
5113
 
        } else { /* size == 3 */
5114
 
            if (!u) {
5115
 
                /* Extract.  */
5116
 
                imm = (insn >> 8) & 0xf;
5117
 
                count = q + 1;
5118
 
 
5119
 
                if (imm > 7 && !q)
5120
 
                    return 1;
5121
 
 
5122
 
                if (imm == 0) {
5123
 
                    neon_load_reg64(cpu_V0, rn);
5124
 
                    if (q) {
5125
 
                        neon_load_reg64(cpu_V1, rn + 1);
5126
 
                    }
5127
 
                } else if (imm == 8) {
5128
 
                    neon_load_reg64(cpu_V0, rn + 1);
5129
 
                    if (q) {
5130
 
                        neon_load_reg64(cpu_V1, rm);
5131
 
                    }
5132
 
                } else if (q) {
5133
 
                    tmp = tcg_temp_new(TCG_TYPE_I64);
5134
 
                    if (imm < 8) {
5135
 
                        neon_load_reg64(cpu_V0, rn);
5136
 
                        neon_load_reg64(tmp, rn + 1);
5137
 
                    } else {
5138
 
                        neon_load_reg64(cpu_V0, rn + 1);
5139
 
                        neon_load_reg64(tmp, rm);
5140
 
                    }
5141
 
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5142
 
                    tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
5143
 
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5144
 
                    if (imm < 8) {
5145
 
                        neon_load_reg64(cpu_V1, rm);
5146
 
                    } else {
5147
 
                        neon_load_reg64(cpu_V1, rm + 1);
5148
 
                        imm -= 8;
5149
 
                    }
5150
 
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5151
 
                    tcg_gen_shri_i64(tmp, tmp, imm * 8);
5152
 
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
5153
 
                } else {
5154
 
                    neon_load_reg64(cpu_V0, rn);
5155
 
                    tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
5156
 
                    neon_load_reg64(cpu_V1, rm);
5157
 
                    tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
5158
 
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5159
 
                }
5160
 
                neon_store_reg64(cpu_V0, rd);
5161
 
                if (q) {
5162
 
                    neon_store_reg64(cpu_V1, rd + 1);
5163
 
                }
5164
 
            } else if ((insn & (1 << 11)) == 0) {
5165
 
                /* Two register misc.  */
5166
 
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5167
 
                size = (insn >> 18) & 3;
5168
 
                switch (op) {
5169
 
                case 0: /* VREV64 */
5170
 
                    if (size == 3)
5171
 
                        return 1;
5172
 
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5173
 
                        NEON_GET_REG(T0, rm, pass * 2);
5174
 
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
5175
 
                        switch (size) {
5176
 
                        case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5177
 
                        case 1: gen_swap_half(cpu_T[0]); break;
5178
 
                        case 2: /* no-op */ break;
5179
 
                        default: abort();
5180
 
                        }
5181
 
                        NEON_SET_REG(T0, rd, pass * 2 + 1);
5182
 
                        if (size == 2) {
5183
 
                            NEON_SET_REG(T1, rd, pass * 2);
5184
 
                        } else {
5185
 
                            gen_op_movl_T0_T1();
5186
 
                            switch (size) {
5187
 
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5188
 
                            case 1: gen_swap_half(cpu_T[0]); break;
5189
 
                            default: abort();
5190
 
                            }
5191
 
                            NEON_SET_REG(T0, rd, pass * 2);
5192
 
                        }
5193
 
                    }
5194
 
                    break;
5195
 
                case 4: case 5: /* VPADDL */
5196
 
                case 12: case 13: /* VPADAL */
5197
 
                    if (size == 3)
5198
 
                        return 1;
5199
 
                    for (pass = 0; pass < q + 1; pass++) {
5200
 
                        tmp = neon_load_reg(rm, pass * 2);
5201
 
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5202
 
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5203
 
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5204
 
                        switch (size) {
5205
 
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5206
 
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5207
 
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5208
 
                        default: abort();
5209
 
                        }
5210
 
                        if (op >= 12) {
5211
 
                            /* Accumulate.  */
5212
 
                            neon_load_reg64(cpu_V1, rd + pass);
5213
 
                            gen_neon_addl(size);
5214
 
                        }
5215
 
                        neon_store_reg64(cpu_V0, rd + pass);
5216
 
                    }
5217
 
                    break;
5218
 
                case 33: /* VTRN */
5219
 
                    if (size == 2) {
5220
 
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5221
 
                            NEON_GET_REG(T0, rm, n);
5222
 
                            NEON_GET_REG(T1, rd, n + 1);
5223
 
                            NEON_SET_REG(T1, rm, n);
5224
 
                            NEON_SET_REG(T0, rd, n + 1);
5225
 
                        }
5226
 
                    } else {
5227
 
                        goto elementwise;
5228
 
                    }
5229
 
                    break;
5230
 
                case 34: /* VUZP */
5231
 
                    /* Reg  Before       After
5232
 
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
5233
 
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
5234
 
                     */
5235
 
                    if (size == 3)
5236
 
                        return 1;
5237
 
                    gen_neon_unzip(rd, q, 0, size);
5238
 
                    gen_neon_unzip(rm, q, 4, size);
5239
 
                    if (q) {
5240
 
                        static int unzip_order_q[8] =
5241
 
                            {0, 2, 4, 6, 1, 3, 5, 7};
5242
 
                        for (n = 0; n < 8; n++) {
5243
 
                            int reg = (n < 4) ? rd : rm;
5244
 
                            gen_neon_movl_T0_scratch(unzip_order_q[n]);
5245
 
                            NEON_SET_REG(T0, reg, n % 4);
5246
 
                        }
5247
 
                    } else {
5248
 
                        static int unzip_order[4] =
5249
 
                            {0, 4, 1, 5};
5250
 
                        for (n = 0; n < 4; n++) {
5251
 
                            int reg = (n < 2) ? rd : rm;
5252
 
                            gen_neon_movl_T0_scratch(unzip_order[n]);
5253
 
                            NEON_SET_REG(T0, reg, n % 2);
5254
 
                        }
5255
 
                    }
5256
 
                    break;
5257
 
                case 35: /* VZIP */
5258
 
                    /* Reg  Before       After
5259
 
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
5260
 
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
5261
 
                     */
5262
 
                    if (size == 3)
5263
 
                        return 1;
5264
 
                    count = (q ? 4 : 2);
5265
 
                    for (n = 0; n < count; n++) {
5266
 
                        NEON_GET_REG(T0, rd, n);
5267
 
                        NEON_GET_REG(T1, rd, n);
5268
 
                        switch (size) {
5269
 
                        case 0: gen_helper_neon_zip_u8(); break;
5270
 
                        case 1: gen_helper_neon_zip_u16(); break;
5271
 
                        case 2: /* no-op */; break;
5272
 
                        default: abort();
5273
 
                        }
5274
 
                        gen_neon_movl_scratch_T0(n * 2);
5275
 
                        gen_neon_movl_scratch_T1(n * 2 + 1);
5276
 
                    }
5277
 
                    for (n = 0; n < count * 2; n++) {
5278
 
                        int reg = (n < count) ? rd : rm;
5279
 
                        gen_neon_movl_T0_scratch(n);
5280
 
                        NEON_SET_REG(T0, reg, n % count);
5281
 
                    }
5282
 
                    break;
5283
 
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5284
 
                    if (size == 3)
5285
 
                        return 1;
5286
 
                    TCGV_UNUSED(tmp2);
5287
 
                    for (pass = 0; pass < 2; pass++) {
5288
 
                        neon_load_reg64(cpu_V0, rm + pass);
5289
 
                        tmp = new_tmp();
5290
 
                        if (op == 36 && q == 0) {
5291
 
                            gen_neon_narrow(size, tmp, cpu_V0);
5292
 
                        } else if (q) {
5293
 
                            gen_neon_narrow_satu(size, tmp, cpu_V0);
5294
 
                        } else {
5295
 
                            gen_neon_narrow_sats(size, tmp, cpu_V0);
5296
 
                        }
5297
 
                        if (pass == 0) {
5298
 
                            tmp2 = tmp;
5299
 
                        } else {
5300
 
                            neon_store_reg(rd, 0, tmp2);
5301
 
                            neon_store_reg(rd, 1, tmp);
5302
 
                        }
5303
 
                    }
5304
 
                    break;
5305
 
                case 38: /* VSHLL */
5306
 
                    if (q || size == 3)
5307
 
                        return 1;
5308
 
                    tmp = neon_load_reg(rm, 0);
5309
 
                    tmp2 = neon_load_reg(rm, 1);
5310
 
                    for (pass = 0; pass < 2; pass++) {
5311
 
                        if (pass == 1)
5312
 
                            tmp = tmp2;
5313
 
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5314
 
                        neon_store_reg64(cpu_V0, rd + pass);
5315
 
                    }
5316
 
                    break;
5317
 
                default:
5318
 
                elementwise:
5319
 
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5320
 
                        if (op == 30 || op == 31 || op >= 58) {
5321
 
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5322
 
                                           neon_reg_offset(rm, pass));
5323
 
                        } else {
5324
 
                            NEON_GET_REG(T0, rm, pass);
5325
 
                        }
5326
 
                        switch (op) {
5327
 
                        case 1: /* VREV32 */
5328
 
                            switch (size) {
5329
 
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5330
 
                            case 1: gen_swap_half(cpu_T[0]); break;
5331
 
                            default: return 1;
5332
 
                            }
5333
 
                            break;
5334
 
                        case 2: /* VREV16 */
5335
 
                            if (size != 0)
5336
 
                                return 1;
5337
 
                            gen_rev16(cpu_T[0]);
5338
 
                            break;
5339
 
                        case 8: /* CLS */
5340
 
                            switch (size) {
5341
 
                            case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5342
 
                            case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5343
 
                            case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5344
 
                            default: return 1;
5345
 
                            }
5346
 
                            break;
5347
 
                        case 9: /* CLZ */
5348
 
                            switch (size) {
5349
 
                            case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5350
 
                            case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5351
 
                            case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5352
 
                            default: return 1;
5353
 
                            }
5354
 
                            break;
5355
 
                        case 10: /* CNT */
5356
 
                            if (size != 0)
5357
 
                                return 1;
5358
 
                            gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5359
 
                            break;
5360
 
                        case 11: /* VNOT */
5361
 
                            if (size != 0)
5362
 
                                return 1;
5363
 
                            gen_op_notl_T0();
5364
 
                            break;
5365
 
                        case 14: /* VQABS */
5366
 
                            switch (size) {
5367
 
                            case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5368
 
                            case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5369
 
                            case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5370
 
                            default: return 1;
5371
 
                            }
5372
 
                            break;
5373
 
                        case 15: /* VQNEG */
5374
 
                            switch (size) {
5375
 
                            case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5376
 
                            case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5377
 
                            case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5378
 
                            default: return 1;
5379
 
                            }
5380
 
                            break;
5381
 
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5382
 
                            gen_op_movl_T1_im(0);
5383
 
                            switch(size) {
5384
 
                            case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5385
 
                            case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5386
 
                            case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5387
 
                            default: return 1;
5388
 
                            }
5389
 
                            if (op == 19)
5390
 
                                gen_op_notl_T0();
5391
 
                            break;
5392
 
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5393
 
                            gen_op_movl_T1_im(0);
5394
 
                            switch(size) {
5395
 
                            case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5396
 
                            case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5397
 
                            case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5398
 
                            default: return 1;
5399
 
                            }
5400
 
                            if (op == 20)
5401
 
                                gen_op_notl_T0();
5402
 
                            break;
5403
 
                        case 18: /* VCEQ #0 */
5404
 
                            gen_op_movl_T1_im(0);
5405
 
                            switch(size) {
5406
 
                            case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5407
 
                            case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5408
 
                            case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5409
 
                            default: return 1;
5410
 
                            }
5411
 
                            break;
5412
 
                        case 22: /* VABS */
5413
 
                            switch(size) {
5414
 
                            case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5415
 
                            case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5416
 
                            case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5417
 
                            default: return 1;
5418
 
                            }
5419
 
                            break;
5420
 
                        case 23: /* VNEG */
5421
 
                            gen_op_movl_T1_im(0);
5422
 
                            if (size == 3)
5423
 
                                return 1;
5424
 
                            gen_neon_rsb(size);
5425
 
                            break;
5426
 
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5427
 
                            gen_op_movl_T1_im(0);
5428
 
                            gen_helper_neon_cgt_f32(CPU_T001);
5429
 
                            if (op == 27)
5430
 
                                gen_op_notl_T0();
5431
 
                            break;
5432
 
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5433
 
                            gen_op_movl_T1_im(0);
5434
 
                            gen_helper_neon_cge_f32(CPU_T001);
5435
 
                            if (op == 28)
5436
 
                                gen_op_notl_T0();
5437
 
                            break;
5438
 
                        case 26: /* Float VCEQ #0 */
5439
 
                            gen_op_movl_T1_im(0);
5440
 
                            gen_helper_neon_ceq_f32(CPU_T001);
5441
 
                            break;
5442
 
                        case 30: /* Float VABS */
5443
 
                            gen_vfp_abs(0);
5444
 
                            break;
5445
 
                        case 31: /* Float VNEG */
5446
 
                            gen_vfp_neg(0);
5447
 
                            break;
5448
 
                        case 32: /* VSWP */
5449
 
                            NEON_GET_REG(T1, rd, pass);
5450
 
                            NEON_SET_REG(T1, rm, pass);
5451
 
                            break;
5452
 
                        case 33: /* VTRN */
5453
 
                            NEON_GET_REG(T1, rd, pass);
5454
 
                            switch (size) {
5455
 
                            case 0: gen_helper_neon_trn_u8(); break;
5456
 
                            case 1: gen_helper_neon_trn_u16(); break;
5457
 
                            case 2: abort();
5458
 
                            default: return 1;
5459
 
                            }
5460
 
                            NEON_SET_REG(T1, rm, pass);
5461
 
                            break;
5462
 
                        case 56: /* Integer VRECPE */
5463
 
                            gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5464
 
                            break;
5465
 
                        case 57: /* Integer VRSQRTE */
5466
 
                            gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5467
 
                            break;
5468
 
                        case 58: /* Float VRECPE */
5469
 
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5470
 
                            break;
5471
 
                        case 59: /* Float VRSQRTE */
5472
 
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5473
 
                            break;
5474
 
                        case 60: /* VCVT.F32.S32 */
5475
 
                            gen_vfp_tosiz(0);
5476
 
                            break;
5477
 
                        case 61: /* VCVT.F32.U32 */
5478
 
                            gen_vfp_touiz(0);
5479
 
                            break;
5480
 
                        case 62: /* VCVT.S32.F32 */
5481
 
                            gen_vfp_sito(0);
5482
 
                            break;
5483
 
                        case 63: /* VCVT.U32.F32 */
5484
 
                            gen_vfp_uito(0);
5485
 
                            break;
5486
 
                        default:
5487
 
                            /* Reserved: 21, 29, 39-56 */
5488
 
                            return 1;
5489
 
                        }
5490
 
                        if (op == 30 || op == 31 || op >= 58) {
5491
 
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5492
 
                                           neon_reg_offset(rd, pass));
5493
 
                        } else {
5494
 
                            NEON_SET_REG(T0, rd, pass);
5495
 
                        }
5496
 
                    }
5497
 
                    break;
5498
 
                }
5499
 
            } else if ((insn & (1 << 10)) == 0) {
5500
 
                /* VTBL, VTBX.  */
5501
 
                n = ((insn >> 5) & 0x18) + 8;
5502
 
                if (insn & (1 << 6)) {
5503
 
                    tmp = neon_load_reg(rd, 0);
5504
 
                } else {
5505
 
                    tmp = new_tmp();
5506
 
                    tcg_gen_movi_i32(tmp, 0);
5507
 
                }
5508
 
                tmp2 = neon_load_reg(rm, 0);
5509
 
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5510
 
                                    tcg_const_i32(n));
5511
 
                dead_tmp(tmp);
5512
 
                if (insn & (1 << 6)) {
5513
 
                    tmp = neon_load_reg(rd, 1);
5514
 
                } else {
5515
 
                    tmp = new_tmp();
5516
 
                    tcg_gen_movi_i32(tmp, 0);
5517
 
                }
5518
 
                tmp3 = neon_load_reg(rm, 1);
5519
 
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5520
 
                                    tcg_const_i32(n));
5521
 
                neon_store_reg(rd, 0, tmp2);
5522
 
                neon_store_reg(rd, 1, tmp3);
5523
 
                dead_tmp(tmp);
5524
 
            } else if ((insn & 0x380) == 0) {
5525
 
                /* VDUP */
5526
 
                if (insn & (1 << 19)) {
5527
 
                    NEON_SET_REG(T0, rm, 1);
5528
 
                } else {
5529
 
                    NEON_SET_REG(T0, rm, 0);
5530
 
                }
5531
 
                if (insn & (1 << 16)) {
5532
 
                    gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5533
 
                } else if (insn & (1 << 17)) {
5534
 
                    if ((insn >> 18) & 1)
5535
 
                        gen_neon_dup_high16(cpu_T[0]);
5536
 
                    else
5537
 
                        gen_neon_dup_low16(cpu_T[0]);
5538
 
                }
5539
 
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5540
 
                    NEON_SET_REG(T0, rd, pass);
5541
 
                }
5542
 
            } else {
5543
 
                return 1;
5544
 
            }
5545
 
        }
5546
 
    }
5547
 
    return 0;
5548
 
}
5549
 
 
5550
 
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5551
 
{
5552
 
    int cpnum;
5553
 
 
5554
 
    cpnum = (insn >> 8) & 0xf;
5555
 
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5556
 
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5557
 
        return 1;
5558
 
 
5559
 
    switch (cpnum) {
5560
 
      case 0:
5561
 
      case 1:
5562
 
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5563
 
            return disas_iwmmxt_insn(env, s, insn);
5564
 
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5565
 
            return disas_dsp_insn(env, s, insn);
5566
 
        }
5567
 
        return 1;
5568
 
    case 10:
5569
 
    case 11:
5570
 
        return disas_vfp_insn (env, s, insn);
5571
 
    case 15:
5572
 
        return disas_cp15_insn (env, s, insn);
5573
 
    default:
5574
 
        /* Unknown coprocessor.  See if the board has hooked it.  */
5575
 
        return disas_cp_insn (env, s, insn);
5576
 
    }
5577
 
}
5578
 
 
5579
 
 
5580
 
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5581
 
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5582
 
{
5583
 
    TCGv tmp;
5584
 
    tmp = new_tmp();
5585
 
    tcg_gen_trunc_i64_i32(tmp, val);
5586
 
    store_reg(s, rlow, tmp);
5587
 
    tmp = new_tmp();
5588
 
    tcg_gen_shri_i64(val, val, 32);
5589
 
    tcg_gen_trunc_i64_i32(tmp, val);
5590
 
    store_reg(s, rhigh, tmp);
5591
 
}
5592
 
 
5593
 
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5594
 
static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5595
 
{
5596
 
    TCGv tmp;
5597
 
    TCGv tmp2;
5598
 
 
5599
 
    /* Load value and extend to 64 bits.  */
5600
 
    tmp = tcg_temp_new(TCG_TYPE_I64);
5601
 
    tmp2 = load_reg(s, rlow);
5602
 
    tcg_gen_extu_i32_i64(tmp, tmp2);
5603
 
    dead_tmp(tmp2);
5604
 
    tcg_gen_add_i64(val, val, tmp);
5605
 
}
5606
 
 
5607
 
/* load and add a 64-bit value from a register pair.  */
5608
 
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5609
 
{
5610
 
    TCGv tmp;
5611
 
    TCGv tmpl;
5612
 
    TCGv tmph;
5613
 
 
5614
 
    /* Load 64-bit value rd:rn.  */
5615
 
    tmpl = load_reg(s, rlow);
5616
 
    tmph = load_reg(s, rhigh);
5617
 
    tmp = tcg_temp_new(TCG_TYPE_I64);
5618
 
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5619
 
    dead_tmp(tmpl);
5620
 
    dead_tmp(tmph);
5621
 
    tcg_gen_add_i64(val, val, tmp);
5622
 
}
5623
 
 
5624
 
/* Set N and Z flags from a 64-bit value.  */
5625
 
static void gen_logicq_cc(TCGv val)
5626
 
{
5627
 
    TCGv tmp = new_tmp();
5628
 
    gen_helper_logicq_cc(tmp, val);
5629
 
    gen_logic_CC(tmp);
5630
 
    dead_tmp(tmp);
 
2199
    gen_op_movl_reg_TN[0][15]();
 
2200
    gen_op_movl_T0_spsr();
 
2201
    gen_op_movl_cpsr_T0(0xffffffff);
 
2202
    s->is_jmp = DISAS_UPDATE;
5631
2203
}
5632
2204
 
5633
2205
static void disas_arm_insn(CPUState * env, DisasContext *s)
5634
2206
{
5635
2207
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5636
 
    TCGv tmp;
5637
 
    TCGv tmp2;
5638
 
    TCGv tmp3;
5639
 
    TCGv addr;
5640
 
 
 
2208
    
5641
2209
    insn = ldl_code(s->pc);
5642
2210
    s->pc += 4;
5643
 
 
5644
 
    /* M variants do not implement ARM mode.  */
5645
 
    if (IS_M(env))
5646
 
        goto illegal_op;
 
2211
    
5647
2212
    cond = insn >> 28;
5648
2213
    if (cond == 0xf){
5649
2214
        /* Unconditional instructions.  */
5650
 
        if (((insn >> 25) & 7) == 1) {
5651
 
            /* NEON Data processing.  */
5652
 
            if (!arm_feature(env, ARM_FEATURE_NEON))
5653
 
                goto illegal_op;
5654
 
 
5655
 
            if (disas_neon_data_insn(env, s, insn))
5656
 
                goto illegal_op;
5657
 
            return;
5658
 
        }
5659
 
        if ((insn & 0x0f100000) == 0x04000000) {
5660
 
            /* NEON load/store.  */
5661
 
            if (!arm_feature(env, ARM_FEATURE_NEON))
5662
 
                goto illegal_op;
5663
 
 
5664
 
            if (disas_neon_ls_insn(env, s, insn))
5665
 
                goto illegal_op;
5666
 
            return;
5667
 
        }
5668
2215
        if ((insn & 0x0d70f000) == 0x0550f000)
5669
2216
            return; /* PLD */
5670
 
        else if ((insn & 0x0ffffdff) == 0x01010000) {
5671
 
            ARCH(6);
5672
 
            /* setend */
5673
 
            if (insn & (1 << 9)) {
5674
 
                /* BE8 mode not implemented.  */
5675
 
                goto illegal_op;
5676
 
            }
5677
 
            return;
5678
 
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
5679
 
            switch ((insn >> 4) & 0xf) {
5680
 
            case 1: /* clrex */
5681
 
                ARCH(6K);
5682
 
                gen_helper_clrex(cpu_env);
5683
 
                return;
5684
 
            case 4: /* dsb */
5685
 
            case 5: /* dmb */
5686
 
            case 6: /* isb */
5687
 
                ARCH(7);
5688
 
                /* We don't emulate caches so these are a no-op.  */
5689
 
                return;
5690
 
            default:
5691
 
                goto illegal_op;
5692
 
            }
5693
 
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5694
 
            /* srs */
5695
 
            uint32_t offset;
5696
 
            if (IS_USER(s))
5697
 
                goto illegal_op;
5698
 
            ARCH(6);
5699
 
            op1 = (insn & 0x1f);
5700
 
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5701
 
                addr = load_reg(s, 13);
5702
 
            } else {
5703
 
                addr = new_tmp();
5704
 
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5705
 
            }
5706
 
            i = (insn >> 23) & 3;
5707
 
            switch (i) {
5708
 
            case 0: offset = -4; break; /* DA */
5709
 
            case 1: offset = -8; break; /* DB */
5710
 
            case 2: offset = 0; break; /* IA */
5711
 
            case 3: offset = 4; break; /* IB */
5712
 
            default: abort();
5713
 
            }
5714
 
            if (offset)
5715
 
                tcg_gen_addi_i32(addr, addr, offset);
5716
 
            tmp = load_reg(s, 14);
5717
 
            gen_st32(tmp, addr, 0);
5718
 
            tmp = new_tmp();
5719
 
            gen_helper_cpsr_read(tmp);
5720
 
            tcg_gen_addi_i32(addr, addr, 4);
5721
 
            gen_st32(tmp, addr, 0);
5722
 
            if (insn & (1 << 21)) {
5723
 
                /* Base writeback.  */
5724
 
                switch (i) {
5725
 
                case 0: offset = -8; break;
5726
 
                case 1: offset = -4; break;
5727
 
                case 2: offset = 4; break;
5728
 
                case 3: offset = 0; break;
5729
 
                default: abort();
5730
 
                }
5731
 
                if (offset)
5732
 
                    tcg_gen_addi_i32(addr, tmp, offset);
5733
 
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5734
 
                    gen_movl_reg_T1(s, 13);
5735
 
                } else {
5736
 
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5737
 
                }
5738
 
            } else {
5739
 
                dead_tmp(addr);
5740
 
            }
5741
 
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5742
 
            /* rfe */
5743
 
            uint32_t offset;
5744
 
            if (IS_USER(s))
5745
 
                goto illegal_op;
5746
 
            ARCH(6);
5747
 
            rn = (insn >> 16) & 0xf;
5748
 
            addr = load_reg(s, rn);
5749
 
            i = (insn >> 23) & 3;
5750
 
            switch (i) {
5751
 
            case 0: offset = -4; break; /* DA */
5752
 
            case 1: offset = -8; break; /* DB */
5753
 
            case 2: offset = 0; break; /* IA */
5754
 
            case 3: offset = 4; break; /* IB */
5755
 
            default: abort();
5756
 
            }
5757
 
            if (offset)
5758
 
                tcg_gen_addi_i32(addr, addr, offset);
5759
 
            /* Load PC into tmp and CPSR into tmp2.  */
5760
 
            tmp = gen_ld32(addr, 0);
5761
 
            tcg_gen_addi_i32(addr, addr, 4);
5762
 
            tmp2 = gen_ld32(addr, 0);
5763
 
            if (insn & (1 << 21)) {
5764
 
                /* Base writeback.  */
5765
 
                switch (i) {
5766
 
                case 0: offset = -8; break;
5767
 
                case 1: offset = -4; break;
5768
 
                case 2: offset = 4; break;
5769
 
                case 3: offset = 0; break;
5770
 
                default: abort();
5771
 
                }
5772
 
                if (offset)
5773
 
                    tcg_gen_addi_i32(addr, addr, offset);
5774
 
                store_reg(s, rn, addr);
5775
 
            } else {
5776
 
                dead_tmp(addr);
5777
 
            }
5778
 
            gen_rfe(s, tmp, tmp2);
5779
 
        } else if ((insn & 0x0e000000) == 0x0a000000) {
 
2217
        else if ((insn & 0x0e000000) == 0x0a000000) {
5780
2218
            /* branch link and change to thumb (blx <offset>) */
5781
2219
            int32_t offset;
5782
2220
 
5783
2221
            val = (uint32_t)s->pc;
5784
 
            tmp = new_tmp();
5785
 
            tcg_gen_movi_i32(tmp, val);
5786
 
            store_reg(s, 14, tmp);
 
2222
            gen_op_movl_T0_im(val);
 
2223
            gen_movl_reg_T0(s, 14);
5787
2224
            /* Sign-extend the 24-bit offset */
5788
2225
            offset = (((int32_t)insn) << 8) >> 8;
5789
2226
            /* offset * 4 + bit24 * 2 + (thumb bit) */
5790
2227
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
5791
2228
            /* pipeline offset */
5792
2229
            val += 4;
5793
 
            gen_bx_im(s, val);
 
2230
            gen_op_movl_T0_im(val);
 
2231
            gen_bx(s);
5794
2232
            return;
5795
 
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
5796
 
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5797
 
                /* iWMMXt register transfer.  */
5798
 
                if (env->cp15.c15_cpar & (1 << 1))
5799
 
                    if (!disas_iwmmxt_insn(env, s, insn))
5800
 
                        return;
5801
 
            }
5802
2233
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
5803
2234
            /* Coprocessor double register transfer.  */
5804
2235
        } else if ((insn & 0x0f000010) == 0x0e000010) {
5805
2236
            /* Additional coprocessor register transfer.  */
5806
 
        } else if ((insn & 0x0ff10020) == 0x01000000) {
5807
 
            uint32_t mask;
5808
 
            uint32_t val;
 
2237
        } else if ((insn & 0x0ff10010) == 0x01000000) {
5809
2238
            /* cps (privileged) */
5810
 
            if (IS_USER(s))
5811
 
                return;
5812
 
            mask = val = 0;
5813
 
            if (insn & (1 << 19)) {
5814
 
                if (insn & (1 << 8))
5815
 
                    mask |= CPSR_A;
5816
 
                if (insn & (1 << 7))
5817
 
                    mask |= CPSR_I;
5818
 
                if (insn & (1 << 6))
5819
 
                    mask |= CPSR_F;
5820
 
                if (insn & (1 << 18))
5821
 
                    val |= mask;
5822
 
            }
5823
 
            if (insn & (1 << 17)) {
5824
 
                mask |= CPSR_M;
5825
 
                val |= (insn & 0x1f);
5826
 
            }
5827
 
            if (mask) {
5828
 
                gen_op_movl_T0_im(val);
5829
 
                gen_set_psr_T0(s, mask, 0);
 
2239
        } else if ((insn & 0x0ffffdff) == 0x01010000) {
 
2240
            /* setend */
 
2241
            if (insn & (1 << 9)) {
 
2242
                /* BE8 mode not implemented.  */
 
2243
                goto illegal_op;
5830
2244
            }
5831
2245
            return;
5832
2246
        }
5836
2250
        /* if not always execute, we generate a conditional jump to
5837
2251
           next instruction */
5838
2252
        s->condlabel = gen_new_label();
5839
 
        gen_test_cc(cond ^ 1, s->condlabel);
 
2253
        gen_test_cc[cond ^ 1](s->condlabel);
5840
2254
        s->condjmp = 1;
 
2255
        //gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
 
2256
        //s->is_jmp = DISAS_JUMP_NEXT;
5841
2257
    }
5842
2258
    if ((insn & 0x0f900000) == 0x03000000) {
5843
 
        if ((insn & (1 << 21)) == 0) {
5844
 
            ARCH(6T2);
5845
 
            rd = (insn >> 12) & 0xf;
5846
 
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5847
 
            if ((insn & (1 << 22)) == 0) {
5848
 
                /* MOVW */
5849
 
                tmp = new_tmp();
5850
 
                tcg_gen_movi_i32(tmp, val);
5851
 
            } else {
5852
 
                /* MOVT */
5853
 
                tmp = load_reg(s, rd);
5854
 
                tcg_gen_ext16u_i32(tmp, tmp);
5855
 
                tcg_gen_ori_i32(tmp, tmp, val << 16);
5856
 
            }
5857
 
            store_reg(s, rd, tmp);
5858
 
        } else {
5859
 
            if (((insn >> 12) & 0xf) != 0xf)
5860
 
                goto illegal_op;
5861
 
            if (((insn >> 16) & 0xf) == 0) {
5862
 
                gen_nop_hint(s, insn & 0xff);
5863
 
            } else {
5864
 
                /* CPSR = immediate */
5865
 
                val = insn & 0xff;
5866
 
                shift = ((insn >> 8) & 0xf) * 2;
5867
 
                if (shift)
5868
 
                    val = (val >> shift) | (val << (32 - shift));
5869
 
                gen_op_movl_T0_im(val);
5870
 
                i = ((insn & (1 << 22)) != 0);
5871
 
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5872
 
                    goto illegal_op;
5873
 
            }
5874
 
        }
 
2259
        if ((insn & 0x0fb0f000) != 0x0320f000)
 
2260
            goto illegal_op;
 
2261
        /* CPSR = immediate */
 
2262
        val = insn & 0xff;
 
2263
        shift = ((insn >> 8) & 0xf) * 2;
 
2264
        if (shift)
 
2265
            val = (val >> shift) | (val << (32 - shift));
 
2266
        gen_op_movl_T0_im(val);
 
2267
        i = ((insn & (1 << 22)) != 0);
 
2268
        if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))
 
2269
            goto illegal_op;
5875
2270
    } else if ((insn & 0x0f900000) == 0x01000000
5876
2271
               && (insn & 0x00000090) != 0x00000090) {
5877
2272
        /* miscellaneous instructions */
5884
2279
                /* PSR = reg */
5885
2280
                gen_movl_T0_reg(s, rm);
5886
2281
                i = ((op1 & 2) != 0);
5887
 
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
 
2282
                if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))
5888
2283
                    goto illegal_op;
5889
2284
            } else {
5890
2285
                /* reg = PSR */
5892
2287
                if (op1 & 2) {
5893
2288
                    if (IS_USER(s))
5894
2289
                        goto illegal_op;
5895
 
                    tmp = load_cpu_field(spsr);
 
2290
                    gen_op_movl_T0_spsr();
5896
2291
                } else {
5897
 
                    tmp = new_tmp();
5898
 
                    gen_helper_cpsr_read(tmp);
 
2292
                    gen_op_movl_T0_cpsr();
5899
2293
                }
5900
 
                store_reg(s, rd, tmp);
 
2294
                gen_movl_reg_T0(s, rd);
5901
2295
            }
5902
2296
            break;
5903
2297
        case 0x1:
5904
2298
            if (op1 == 1) {
5905
2299
                /* branch/exchange thumb (bx).  */
5906
 
                tmp = load_reg(s, rm);
5907
 
                gen_bx(s, tmp);
 
2300
                gen_movl_T0_reg(s, rm);
 
2301
                gen_bx(s);
5908
2302
            } else if (op1 == 3) {
5909
2303
                /* clz */
5910
2304
                rd = (insn >> 12) & 0xf;
5911
 
                tmp = load_reg(s, rm);
5912
 
                gen_helper_clz(tmp, tmp);
5913
 
                store_reg(s, rd, tmp);
 
2305
                gen_movl_T0_reg(s, rm);
 
2306
                gen_op_clz_T0();
 
2307
                gen_movl_reg_T0(s, rd);
5914
2308
            } else {
5915
2309
                goto illegal_op;
5916
2310
            }
5919
2313
            if (op1 == 1) {
5920
2314
                ARCH(5J); /* bxj */
5921
2315
                /* Trivial implementation equivalent to bx.  */
5922
 
                tmp = load_reg(s, rm);
5923
 
                gen_bx(s, tmp);
 
2316
                gen_movl_T0_reg(s, rm);
 
2317
                gen_bx(s);
5924
2318
            } else {
5925
2319
                goto illegal_op;
5926
2320
            }
5930
2324
              goto illegal_op;
5931
2325
 
5932
2326
            /* branch link/exchange thumb (blx) */
5933
 
            tmp = load_reg(s, rm);
5934
 
            tmp2 = new_tmp();
5935
 
            tcg_gen_movi_i32(tmp2, s->pc);
5936
 
            store_reg(s, 14, tmp2);
5937
 
            gen_bx(s, tmp);
 
2327
            val = (uint32_t)s->pc;
 
2328
            gen_op_movl_T0_im(val);
 
2329
            gen_movl_reg_T0(s, 14);
 
2330
            gen_movl_T0_reg(s, rm);
 
2331
            gen_bx(s);
5938
2332
            break;
5939
2333
        case 0x5: /* saturating add/subtract */
5940
2334
            rd = (insn >> 12) & 0xf;
5941
2335
            rn = (insn >> 16) & 0xf;
5942
 
            tmp = load_reg(s, rm);
5943
 
            tmp2 = load_reg(s, rn);
 
2336
            gen_movl_T0_reg(s, rm);
 
2337
            gen_movl_T1_reg(s, rn);
5944
2338
            if (op1 & 2)
5945
 
                gen_helper_double_saturate(tmp2, tmp2);
 
2339
                gen_op_double_T1_saturate();
5946
2340
            if (op1 & 1)
5947
 
                gen_helper_sub_saturate(tmp, tmp, tmp2);
 
2341
                gen_op_subl_T0_T1_saturate();
5948
2342
            else
5949
 
                gen_helper_add_saturate(tmp, tmp, tmp2);
5950
 
            dead_tmp(tmp2);
5951
 
            store_reg(s, rd, tmp);
 
2343
                gen_op_addl_T0_T1_saturate();
 
2344
            gen_movl_reg_T0(s, rd);
5952
2345
            break;
5953
2346
        case 7: /* bkpt */
5954
 
            gen_set_condexec(s);
5955
 
            gen_set_pc_im(s->pc - 4);
5956
 
            gen_exception(EXCP_BKPT);
 
2347
            gen_op_movl_T0_im((long)s->pc - 4);
 
2348
            gen_op_movl_reg_TN[0][15]();
 
2349
            gen_op_bkpt();
5957
2350
            s->is_jmp = DISAS_JUMP;
5958
2351
            break;
5959
2352
        case 0x8: /* signed multiply */
5965
2358
            rd = (insn >> 16) & 0xf;
5966
2359
            if (op1 == 1) {
5967
2360
                /* (32 * 16) >> 16 */
5968
 
                tmp = load_reg(s, rm);
5969
 
                tmp2 = load_reg(s, rs);
 
2361
                gen_movl_T0_reg(s, rm);
 
2362
                gen_movl_T1_reg(s, rs);
5970
2363
                if (sh & 4)
5971
 
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
 
2364
                    gen_op_sarl_T1_im(16);
5972
2365
                else
5973
 
                    gen_sxth(tmp2);
5974
 
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
5975
 
                tcg_gen_shri_i64(tmp2, tmp2, 16);
5976
 
                tmp = new_tmp();
5977
 
                tcg_gen_trunc_i64_i32(tmp, tmp2);
 
2366
                    gen_op_sxth_T1();
 
2367
                gen_op_imulw_T0_T1();
5978
2368
                if ((sh & 2) == 0) {
5979
 
                    tmp2 = load_reg(s, rn);
5980
 
                    gen_helper_add_setq(tmp, tmp, tmp2);
5981
 
                    dead_tmp(tmp2);
 
2369
                    gen_movl_T1_reg(s, rn);
 
2370
                    gen_op_addl_T0_T1_setq();
5982
2371
                }
5983
 
                store_reg(s, rd, tmp);
 
2372
                gen_movl_reg_T0(s, rd);
5984
2373
            } else {
5985
2374
                /* 16 * 16 */
5986
 
                tmp = load_reg(s, rm);
5987
 
                tmp2 = load_reg(s, rs);
5988
 
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5989
 
                dead_tmp(tmp2);
 
2375
                gen_movl_T0_reg(s, rm);
 
2376
                gen_movl_T1_reg(s, rs);
 
2377
                gen_mulxy(sh & 2, sh & 4);
5990
2378
                if (op1 == 2) {
5991
 
                    tmp2 = tcg_temp_new(TCG_TYPE_I64);
5992
 
                    tcg_gen_ext_i32_i64(tmp2, tmp);
5993
 
                    dead_tmp(tmp);
5994
 
                    gen_addq(s, tmp2, rn, rd);
5995
 
                    gen_storeq_reg(s, rn, rd, tmp2);
 
2379
                    gen_op_signbit_T1_T0();
 
2380
                    gen_op_addq_T0_T1(rn, rd);
 
2381
                    gen_movl_reg_T0(s, rn);
 
2382
                    gen_movl_reg_T1(s, rd);
5996
2383
                } else {
5997
2384
                    if (op1 == 0) {
5998
 
                        tmp2 = load_reg(s, rn);
5999
 
                        gen_helper_add_setq(tmp, tmp, tmp2);
6000
 
                        dead_tmp(tmp2);
 
2385
                        gen_movl_T1_reg(s, rn);
 
2386
                        gen_op_addl_T0_T1_setq();
6001
2387
                    }
6002
 
                    store_reg(s, rd, tmp);
 
2388
                    gen_movl_reg_T0(s, rd);
6003
2389
                }
6004
2390
            }
6005
2391
            break;
6010
2396
                (insn & 0x00000090) != 0x90) ||
6011
2397
               ((insn & 0x0e000000) == (1 << 25))) {
6012
2398
        int set_cc, logic_cc, shiftop;
6013
 
 
 
2399
        
6014
2400
        op1 = (insn >> 21) & 0xf;
6015
2401
        set_cc = (insn >> 20) & 1;
6016
2402
        logic_cc = table_logic_cc[op1] & set_cc;
6024
2410
                val = (val >> shift) | (val << (32 - shift));
6025
2411
            gen_op_movl_T1_im(val);
6026
2412
            if (logic_cc && shift)
6027
 
                gen_set_CF_bit31(cpu_T[1]);
 
2413
                gen_op_mov_CF_T1();
6028
2414
        } else {
6029
2415
            /* register */
6030
2416
            rm = (insn) & 0xf;
6032
2418
            shiftop = (insn >> 5) & 3;
6033
2419
            if (!(insn & (1 << 4))) {
6034
2420
                shift = (insn >> 7) & 0x1f;
6035
 
                gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
 
2421
                if (shift != 0) {
 
2422
                    if (logic_cc) {
 
2423
                        gen_shift_T1_im_cc[shiftop](shift);
 
2424
                    } else {
 
2425
                        gen_shift_T1_im[shiftop](shift);
 
2426
                    }
 
2427
                } else if (shiftop != 0) {
 
2428
                    if (logic_cc) {
 
2429
                        gen_shift_T1_0_cc[shiftop]();
 
2430
                    } else {
 
2431
                        gen_shift_T1_0[shiftop]();
 
2432
                    }
 
2433
                }
6036
2434
            } else {
6037
2435
                rs = (insn >> 8) & 0xf;
6038
 
                tmp = load_reg(s, rs);
6039
 
                gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
 
2436
                gen_movl_T0_reg(s, rs);
 
2437
                if (logic_cc) {
 
2438
                    gen_shift_T1_T0_cc[shiftop]();
 
2439
                } else {
 
2440
                    gen_shift_T1_T0[shiftop]();
 
2441
                }
6040
2442
            }
6041
2443
        }
6042
2444
        if (op1 != 0x0f && op1 != 0x0d) {
6090
2492
            if (set_cc)
6091
2493
                gen_op_adcl_T0_T1_cc();
6092
2494
            else
6093
 
                gen_adc_T0_T1();
 
2495
                gen_op_adcl_T0_T1();
6094
2496
            gen_movl_reg_T0(s, rd);
6095
2497
            break;
6096
2498
        case 0x06:
6097
2499
            if (set_cc)
6098
2500
                gen_op_sbcl_T0_T1_cc();
6099
2501
            else
6100
 
                gen_sbc_T0_T1();
 
2502
                gen_op_sbcl_T0_T1();
6101
2503
            gen_movl_reg_T0(s, rd);
6102
2504
            break;
6103
2505
        case 0x07:
6104
2506
            if (set_cc)
6105
2507
                gen_op_rscl_T0_T1_cc();
6106
2508
            else
6107
 
                gen_rsc_T0_T1();
 
2509
                gen_op_rscl_T0_T1();
6108
2510
            gen_movl_reg_T0(s, rd);
6109
2511
            break;
6110
2512
        case 0x08:
6176
2578
                    rn = (insn >> 12) & 0xf;
6177
2579
                    rs = (insn >> 8) & 0xf;
6178
2580
                    rm = (insn) & 0xf;
6179
 
                    op1 = (insn >> 20) & 0xf;
6180
 
                    switch (op1) {
6181
 
                    case 0: case 1: case 2: case 3: case 6:
 
2581
                    if (((insn >> 22) & 3) == 0) {
6182
2582
                        /* 32 bit mul */
6183
 
                        tmp = load_reg(s, rs);
6184
 
                        tmp2 = load_reg(s, rm);
6185
 
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6186
 
                        dead_tmp(tmp2);
6187
 
                        if (insn & (1 << 22)) {
6188
 
                            /* Subtract (mls) */
6189
 
                            ARCH(6T2);
6190
 
                            tmp2 = load_reg(s, rn);
6191
 
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6192
 
                            dead_tmp(tmp2);
6193
 
                        } else if (insn & (1 << 21)) {
6194
 
                            /* Add */
6195
 
                            tmp2 = load_reg(s, rn);
6196
 
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6197
 
                            dead_tmp(tmp2);
 
2583
                        gen_movl_T0_reg(s, rs);
 
2584
                        gen_movl_T1_reg(s, rm);
 
2585
                        gen_op_mul_T0_T1();
 
2586
                        if (insn & (1 << 21)) {
 
2587
                            gen_movl_T1_reg(s, rn);
 
2588
                            gen_op_addl_T0_T1();
6198
2589
                        }
6199
 
                        if (insn & (1 << 20))
6200
 
                            gen_logic_CC(tmp);
6201
 
                        store_reg(s, rd, tmp);
6202
 
                        break;
6203
 
                    default:
 
2590
                        if (insn & (1 << 20)) 
 
2591
                            gen_op_logic_T0_cc();
 
2592
                        gen_movl_reg_T0(s, rd);
 
2593
                    } else {
6204
2594
                        /* 64 bit mul */
6205
 
                        tmp = load_reg(s, rs);
6206
 
                        tmp2 = load_reg(s, rm);
6207
 
                        if (insn & (1 << 22))
6208
 
                            tmp = gen_muls_i64_i32(tmp, tmp2);
 
2595
                        gen_movl_T0_reg(s, rs);
 
2596
                        gen_movl_T1_reg(s, rm);
 
2597
                        if (insn & (1 << 22)) 
 
2598
                            gen_op_imull_T0_T1();
6209
2599
                        else
6210
 
                            tmp = gen_mulu_i64_i32(tmp, tmp2);
 
2600
                            gen_op_mull_T0_T1();
6211
2601
                        if (insn & (1 << 21)) /* mult accumulate */
6212
 
                            gen_addq(s, tmp, rn, rd);
 
2602
                            gen_op_addq_T0_T1(rn, rd);
6213
2603
                        if (!(insn & (1 << 23))) { /* double accumulate */
6214
2604
                            ARCH(6);
6215
 
                            gen_addq_lo(s, tmp, rn);
6216
 
                            gen_addq_lo(s, tmp, rd);
 
2605
                            gen_op_addq_lo_T0_T1(rn);
 
2606
                            gen_op_addq_lo_T0_T1(rd);
6217
2607
                        }
6218
 
                        if (insn & (1 << 20))
6219
 
                            gen_logicq_cc(tmp);
6220
 
                        gen_storeq_reg(s, rn, rd, tmp);
6221
 
                        break;
 
2608
                        if (insn & (1 << 20)) 
 
2609
                            gen_op_logicq_cc();
 
2610
                        gen_movl_reg_T0(s, rn);
 
2611
                        gen_movl_reg_T1(s, rd);
6222
2612
                    }
6223
2613
                } else {
6224
2614
                    rn = (insn >> 16) & 0xf;
6225
2615
                    rd = (insn >> 12) & 0xf;
6226
2616
                    if (insn & (1 << 23)) {
6227
2617
                        /* load/store exclusive */
6228
 
                        op1 = (insn >> 21) & 0x3;
6229
 
                        if (op1)
6230
 
                            ARCH(6K);
6231
 
                        else
6232
 
                            ARCH(6);
6233
 
                        gen_movl_T1_reg(s, rn);
6234
 
                        addr = cpu_T[1];
6235
 
                        if (insn & (1 << 20)) {
6236
 
                            gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6237
 
                            switch (op1) {
6238
 
                            case 0: /* ldrex */
6239
 
                                tmp = gen_ld32(addr, IS_USER(s));
6240
 
                                break;
6241
 
                            case 1: /* ldrexd */
6242
 
                                tmp = gen_ld32(addr, IS_USER(s));
6243
 
                                store_reg(s, rd, tmp);
6244
 
                                tcg_gen_addi_i32(addr, addr, 4);
6245
 
                                tmp = gen_ld32(addr, IS_USER(s));
6246
 
                                rd++;
6247
 
                                break;
6248
 
                            case 2: /* ldrexb */
6249
 
                                tmp = gen_ld8u(addr, IS_USER(s));
6250
 
                                break;
6251
 
                            case 3: /* ldrexh */
6252
 
                                tmp = gen_ld16u(addr, IS_USER(s));
6253
 
                                break;
6254
 
                            default:
6255
 
                                abort();
6256
 
                            }
6257
 
                            store_reg(s, rd, tmp);
6258
 
                        } else {
6259
 
                            int label = gen_new_label();
6260
 
                            rm = insn & 0xf;
6261
 
                            gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6262
 
                            tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6263
 
                                                0, label);
6264
 
                            tmp = load_reg(s,rm);
6265
 
                            switch (op1) {
6266
 
                            case 0:  /*  strex */
6267
 
                                gen_st32(tmp, addr, IS_USER(s));
6268
 
                                break;
6269
 
                            case 1: /*  strexd */
6270
 
                                gen_st32(tmp, addr, IS_USER(s));
6271
 
                                tcg_gen_addi_i32(addr, addr, 4);
6272
 
                                tmp = load_reg(s, rm + 1);
6273
 
                                gen_st32(tmp, addr, IS_USER(s));
6274
 
                                break;
6275
 
                            case 2: /*  strexb */
6276
 
                                gen_st8(tmp, addr, IS_USER(s));
6277
 
                                break;
6278
 
                            case 3: /* strexh */
6279
 
                                gen_st16(tmp, addr, IS_USER(s));
6280
 
                                break;
6281
 
                            default:
6282
 
                                abort();
6283
 
                            }
6284
 
                            gen_set_label(label);
6285
 
                            gen_movl_reg_T0(s, rd);
6286
 
                        }
 
2618
                        goto illegal_op;
6287
2619
                    } else {
6288
2620
                        /* SWP instruction */
6289
2621
                        rm = (insn) & 0xf;
6290
 
 
6291
 
                        /* ??? This is not really atomic.  However we know
6292
 
                           we never have multiple CPUs running in parallel,
6293
 
                           so it is good enough.  */
6294
 
                        addr = load_reg(s, rn);
6295
 
                        tmp = load_reg(s, rm);
 
2622
                        
 
2623
                        gen_movl_T0_reg(s, rm);
 
2624
                        gen_movl_T1_reg(s, rn);
6296
2625
                        if (insn & (1 << 22)) {
6297
 
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6298
 
                            gen_st8(tmp, addr, IS_USER(s));
 
2626
                            gen_ldst(swpb, s);
6299
2627
                        } else {
6300
 
                            tmp2 = gen_ld32(addr, IS_USER(s));
6301
 
                            gen_st32(tmp, addr, IS_USER(s));
 
2628
                            gen_ldst(swpl, s);
6302
2629
                        }
6303
 
                        dead_tmp(addr);
6304
 
                        store_reg(s, rd, tmp2);
 
2630
                        gen_movl_reg_T0(s, rd);
6305
2631
                    }
6306
2632
                }
6307
2633
            } else {
6310
2636
                /* Misc load/store */
6311
2637
                rn = (insn >> 16) & 0xf;
6312
2638
                rd = (insn >> 12) & 0xf;
6313
 
                addr = load_reg(s, rn);
 
2639
                gen_movl_T1_reg(s, rn);
6314
2640
                if (insn & (1 << 24))
6315
 
                    gen_add_datah_offset(s, insn, 0, addr);
 
2641
                    gen_add_datah_offset(s, insn, 0);
6316
2642
                address_offset = 0;
6317
2643
                if (insn & (1 << 20)) {
6318
2644
                    /* load */
6319
2645
                    switch(sh) {
6320
2646
                    case 1:
6321
 
                        tmp = gen_ld16u(addr, IS_USER(s));
 
2647
                        gen_ldst(lduw, s);
6322
2648
                        break;
6323
2649
                    case 2:
6324
 
                        tmp = gen_ld8s(addr, IS_USER(s));
 
2650
                        gen_ldst(ldsb, s);
6325
2651
                        break;
6326
2652
                    default:
6327
2653
                    case 3:
6328
 
                        tmp = gen_ld16s(addr, IS_USER(s));
 
2654
                        gen_ldst(ldsw, s);
6329
2655
                        break;
6330
2656
                    }
6331
2657
                    load = 1;
6333
2659
                    /* doubleword */
6334
2660
                    if (sh & 1) {
6335
2661
                        /* store */
6336
 
                        tmp = load_reg(s, rd);
6337
 
                        gen_st32(tmp, addr, IS_USER(s));
6338
 
                        tcg_gen_addi_i32(addr, addr, 4);
6339
 
                        tmp = load_reg(s, rd + 1);
6340
 
                        gen_st32(tmp, addr, IS_USER(s));
 
2662
                        gen_movl_T0_reg(s, rd);
 
2663
                        gen_ldst(stl, s);
 
2664
                        gen_op_addl_T1_im(4);
 
2665
                        gen_movl_T0_reg(s, rd + 1);
 
2666
                        gen_ldst(stl, s);
6341
2667
                        load = 0;
6342
2668
                    } else {
6343
2669
                        /* load */
6344
 
                        tmp = gen_ld32(addr, IS_USER(s));
6345
 
                        store_reg(s, rd, tmp);
6346
 
                        tcg_gen_addi_i32(addr, addr, 4);
6347
 
                        tmp = gen_ld32(addr, IS_USER(s));
 
2670
                        gen_ldst(ldl, s);
 
2671
                        gen_movl_reg_T0(s, rd);
 
2672
                        gen_op_addl_T1_im(4);
 
2673
                        gen_ldst(ldl, s);
6348
2674
                        rd++;
6349
2675
                        load = 1;
6350
2676
                    }
6351
2677
                    address_offset = -4;
6352
2678
                } else {
6353
2679
                    /* store */
6354
 
                    tmp = load_reg(s, rd);
6355
 
                    gen_st16(tmp, addr, IS_USER(s));
 
2680
                    gen_movl_T0_reg(s, rd);
 
2681
                    gen_ldst(stw, s);
6356
2682
                    load = 0;
6357
2683
                }
6358
2684
                /* Perform base writeback before the loaded value to
6360
2686
                   ldrd with base writeback is is undefined if the
6361
2687
                   destination and index registers overlap.  */
6362
2688
                if (!(insn & (1 << 24))) {
6363
 
                    gen_add_datah_offset(s, insn, address_offset, addr);
6364
 
                    store_reg(s, rn, addr);
 
2689
                    gen_add_datah_offset(s, insn, address_offset);
 
2690
                    gen_movl_reg_T1(s, rn);
6365
2691
                } else if (insn & (1 << 21)) {
6366
2692
                    if (address_offset)
6367
 
                        tcg_gen_addi_i32(addr, addr, address_offset);
6368
 
                    store_reg(s, rn, addr);
6369
 
                } else {
6370
 
                    dead_tmp(addr);
 
2693
                        gen_op_addl_T1_im(address_offset);
 
2694
                    gen_movl_reg_T1(s, rn);
6371
2695
                }
6372
2696
                if (load) {
6373
2697
                    /* Complete the load.  */
6374
 
                    store_reg(s, rd, tmp);
 
2698
                    gen_movl_reg_T0(s, rd);
6375
2699
                }
6376
2700
            }
6377
2701
            break;
6378
2702
        case 0x4:
6379
2703
        case 0x5:
6380
 
            goto do_ldst;
6381
2704
        case 0x6:
6382
2705
        case 0x7:
6383
 
            if (insn & (1 << 4)) {
6384
 
                ARCH(6);
6385
 
                /* Armv6 Media instructions.  */
6386
 
                rm = insn & 0xf;
6387
 
                rn = (insn >> 16) & 0xf;
6388
 
                rd = (insn >> 12) & 0xf;
6389
 
                rs = (insn >> 8) & 0xf;
6390
 
                switch ((insn >> 23) & 3) {
6391
 
                case 0: /* Parallel add/subtract.  */
6392
 
                    op1 = (insn >> 20) & 7;
6393
 
                    tmp = load_reg(s, rn);
6394
 
                    tmp2 = load_reg(s, rm);
6395
 
                    sh = (insn >> 5) & 7;
6396
 
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6397
 
                        goto illegal_op;
6398
 
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6399
 
                    dead_tmp(tmp2);
6400
 
                    store_reg(s, rd, tmp);
6401
 
                    break;
6402
 
                case 1:
6403
 
                    if ((insn & 0x00700020) == 0) {
6404
 
                        /* Halfword pack.  */
6405
 
                        tmp = load_reg(s, rn);
6406
 
                        tmp2 = load_reg(s, rm);
6407
 
                        shift = (insn >> 7) & 0x1f;
6408
 
                        if (insn & (1 << 6)) {
6409
 
                            /* pkhtb */
6410
 
                            if (shift == 0)
6411
 
                                shift = 31;
6412
 
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6413
 
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6414
 
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6415
 
                        } else {
6416
 
                            /* pkhbt */
6417
 
                            if (shift)
6418
 
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6419
 
                            tcg_gen_ext16u_i32(tmp, tmp);
6420
 
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6421
 
                        }
6422
 
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6423
 
                        dead_tmp(tmp2);
6424
 
                        store_reg(s, rd, tmp);
6425
 
                    } else if ((insn & 0x00200020) == 0x00200000) {
6426
 
                        /* [us]sat */
6427
 
                        tmp = load_reg(s, rm);
6428
 
                        shift = (insn >> 7) & 0x1f;
6429
 
                        if (insn & (1 << 6)) {
6430
 
                            if (shift == 0)
6431
 
                                shift = 31;
6432
 
                            tcg_gen_sari_i32(tmp, tmp, shift);
6433
 
                        } else {
6434
 
                            tcg_gen_shli_i32(tmp, tmp, shift);
6435
 
                        }
6436
 
                        sh = (insn >> 16) & 0x1f;
6437
 
                        if (sh != 0) {
6438
 
                            if (insn & (1 << 22))
6439
 
                                gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6440
 
                            else
6441
 
                                gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6442
 
                        }
6443
 
                        store_reg(s, rd, tmp);
6444
 
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6445
 
                        /* [us]sat16 */
6446
 
                        tmp = load_reg(s, rm);
6447
 
                        sh = (insn >> 16) & 0x1f;
6448
 
                        if (sh != 0) {
6449
 
                            if (insn & (1 << 22))
6450
 
                                gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6451
 
                            else
6452
 
                                gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6453
 
                        }
6454
 
                        store_reg(s, rd, tmp);
6455
 
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6456
 
                        /* Select bytes.  */
6457
 
                        tmp = load_reg(s, rn);
6458
 
                        tmp2 = load_reg(s, rm);
6459
 
                        tmp3 = new_tmp();
6460
 
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6461
 
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6462
 
                        dead_tmp(tmp3);
6463
 
                        dead_tmp(tmp2);
6464
 
                        store_reg(s, rd, tmp);
6465
 
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6466
 
                        tmp = load_reg(s, rm);
6467
 
                        shift = (insn >> 10) & 3;
6468
 
                        /* ??? In many cases it's not neccessary to do a
6469
 
                           rotate, a shift is sufficient.  */
6470
 
                        if (shift != 0)
6471
 
                            tcg_gen_rori_i32(tmp, tmp, shift * 8);
6472
 
                        op1 = (insn >> 20) & 7;
6473
 
                        switch (op1) {
6474
 
                        case 0: gen_sxtb16(tmp);  break;
6475
 
                        case 2: gen_sxtb(tmp);    break;
6476
 
                        case 3: gen_sxth(tmp);    break;
6477
 
                        case 4: gen_uxtb16(tmp);  break;
6478
 
                        case 6: gen_uxtb(tmp);    break;
6479
 
                        case 7: gen_uxth(tmp);    break;
6480
 
                        default: goto illegal_op;
6481
 
                        }
6482
 
                        if (rn != 15) {
6483
 
                            tmp2 = load_reg(s, rn);
6484
 
                            if ((op1 & 3) == 0) {
6485
 
                                gen_add16(tmp, tmp2);
6486
 
                            } else {
6487
 
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6488
 
                                dead_tmp(tmp2);
6489
 
                            }
6490
 
                        }
6491
 
                        store_reg(s, rd, tmp);
6492
 
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6493
 
                        /* rev */
6494
 
                        tmp = load_reg(s, rm);
6495
 
                        if (insn & (1 << 22)) {
6496
 
                            if (insn & (1 << 7)) {
6497
 
                                gen_revsh(tmp);
6498
 
                            } else {
6499
 
                                ARCH(6T2);
6500
 
                                gen_helper_rbit(tmp, tmp);
6501
 
                            }
6502
 
                        } else {
6503
 
                            if (insn & (1 << 7))
6504
 
                                gen_rev16(tmp);
6505
 
                            else
6506
 
                                tcg_gen_bswap_i32(tmp, tmp);
6507
 
                        }
6508
 
                        store_reg(s, rd, tmp);
6509
 
                    } else {
6510
 
                        goto illegal_op;
6511
 
                    }
6512
 
                    break;
6513
 
                case 2: /* Multiplies (Type 3).  */
6514
 
                    tmp = load_reg(s, rm);
6515
 
                    tmp2 = load_reg(s, rs);
6516
 
                    if (insn & (1 << 20)) {
6517
 
                        /* Signed multiply most significant [accumulate].  */
6518
 
                        tmp2 = gen_muls_i64_i32(tmp, tmp2);
6519
 
                        if (insn & (1 << 5))
6520
 
                            tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6521
 
                        tcg_gen_shri_i64(tmp2, tmp2, 32);
6522
 
                        tmp = new_tmp();
6523
 
                        tcg_gen_trunc_i64_i32(tmp, tmp2);
6524
 
                        if (rn != 15) {
6525
 
                            tmp2 = load_reg(s, rn);
6526
 
                            if (insn & (1 << 6)) {
6527
 
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6528
 
                            } else {
6529
 
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6530
 
                            }
6531
 
                            dead_tmp(tmp2);
6532
 
                        }
6533
 
                        store_reg(s, rd, tmp);
6534
 
                    } else {
6535
 
                        if (insn & (1 << 5))
6536
 
                            gen_swap_half(tmp2);
6537
 
                        gen_smul_dual(tmp, tmp2);
6538
 
                        /* This addition cannot overflow.  */
6539
 
                        if (insn & (1 << 6)) {
6540
 
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6541
 
                        } else {
6542
 
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6543
 
                        }
6544
 
                        dead_tmp(tmp2);
6545
 
                        if (insn & (1 << 22)) {
6546
 
                            /* smlald, smlsld */
6547
 
                            tmp2 = tcg_temp_new(TCG_TYPE_I64);
6548
 
                            tcg_gen_ext_i32_i64(tmp2, tmp);
6549
 
                            dead_tmp(tmp);
6550
 
                            gen_addq(s, tmp2, rd, rn);
6551
 
                            gen_storeq_reg(s, rd, rn, tmp2);
6552
 
                        } else {
6553
 
                            /* smuad, smusd, smlad, smlsd */
6554
 
                            if (rd != 15)
6555
 
                              {
6556
 
                                tmp2 = load_reg(s, rd);
6557
 
                                gen_helper_add_setq(tmp, tmp, tmp2);
6558
 
                                dead_tmp(tmp2);
6559
 
                              }
6560
 
                            store_reg(s, rn, tmp);
6561
 
                        }
6562
 
                    }
6563
 
                    break;
6564
 
                case 3:
6565
 
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6566
 
                    switch (op1) {
6567
 
                    case 0: /* Unsigned sum of absolute differences.  */
6568
 
                        ARCH(6);
6569
 
                        tmp = load_reg(s, rm);
6570
 
                        tmp2 = load_reg(s, rs);
6571
 
                        gen_helper_usad8(tmp, tmp, tmp2);
6572
 
                        dead_tmp(tmp2);
6573
 
                        if (rn != 15) {
6574
 
                            tmp2 = load_reg(s, rn);
6575
 
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6576
 
                            dead_tmp(tmp2);
6577
 
                        }
6578
 
                        store_reg(s, rd, tmp);
6579
 
                        break;
6580
 
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6581
 
                        /* Bitfield insert/clear.  */
6582
 
                        ARCH(6T2);
6583
 
                        shift = (insn >> 7) & 0x1f;
6584
 
                        i = (insn >> 16) & 0x1f;
6585
 
                        i = i + 1 - shift;
6586
 
                        if (rm == 15) {
6587
 
                            tmp = new_tmp();
6588
 
                            tcg_gen_movi_i32(tmp, 0);
6589
 
                        } else {
6590
 
                            tmp = load_reg(s, rm);
6591
 
                        }
6592
 
                        if (i != 32) {
6593
 
                            tmp2 = load_reg(s, rd);
6594
 
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6595
 
                            dead_tmp(tmp2);
6596
 
                        }
6597
 
                        store_reg(s, rd, tmp);
6598
 
                        break;
6599
 
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6600
 
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6601
 
                        tmp = load_reg(s, rm);
6602
 
                        shift = (insn >> 7) & 0x1f;
6603
 
                        i = ((insn >> 16) & 0x1f) + 1;
6604
 
                        if (shift + i > 32)
6605
 
                            goto illegal_op;
6606
 
                        if (i < 32) {
6607
 
                            if (op1 & 0x20) {
6608
 
                                gen_ubfx(tmp, shift, (1u << i) - 1);
6609
 
                            } else {
6610
 
                                gen_sbfx(tmp, shift, i);
6611
 
                            }
6612
 
                        }
6613
 
                        store_reg(s, rd, tmp);
6614
 
                        break;
6615
 
                    default:
6616
 
                        goto illegal_op;
6617
 
                    }
6618
 
                    break;
6619
 
                }
6620
 
                break;
6621
 
            }
6622
 
        do_ldst:
6623
2706
            /* Check for undefined extension instructions
6624
2707
             * per the ARM Bible IE:
6625
2708
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
6632
2715
            /* load/store byte/word */
6633
2716
            rn = (insn >> 16) & 0xf;
6634
2717
            rd = (insn >> 12) & 0xf;
6635
 
            tmp2 = load_reg(s, rn);
 
2718
            gen_movl_T1_reg(s, rn);
6636
2719
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6637
2720
            if (insn & (1 << 24))
6638
 
                gen_add_data_offset(s, insn, tmp2);
 
2721
                gen_add_data_offset(s, insn);
6639
2722
            if (insn & (1 << 20)) {
6640
2723
                /* load */
6641
2724
                s->is_mem = 1;
 
2725
#if defined(CONFIG_USER_ONLY)
 
2726
                if (insn & (1 << 22))
 
2727
                    gen_op_ldub_raw();
 
2728
                else
 
2729
                    gen_op_ldl_raw();
 
2730
#else
6642
2731
                if (insn & (1 << 22)) {
6643
 
                    tmp = gen_ld8u(tmp2, i);
 
2732
                    if (i)
 
2733
                        gen_op_ldub_user();
 
2734
                    else
 
2735
                        gen_op_ldub_kernel();
6644
2736
                } else {
6645
 
                    tmp = gen_ld32(tmp2, i);
 
2737
                    if (i)
 
2738
                        gen_op_ldl_user();
 
2739
                    else
 
2740
                        gen_op_ldl_kernel();
6646
2741
                }
 
2742
#endif
6647
2743
            } else {
6648
2744
                /* store */
6649
 
                tmp = load_reg(s, rd);
 
2745
                gen_movl_T0_reg(s, rd);
 
2746
#if defined(CONFIG_USER_ONLY)
6650
2747
                if (insn & (1 << 22))
6651
 
                    gen_st8(tmp, tmp2, i);
 
2748
                    gen_op_stb_raw();
6652
2749
                else
6653
 
                    gen_st32(tmp, tmp2, i);
 
2750
                    gen_op_stl_raw();
 
2751
#else
 
2752
                if (insn & (1 << 22)) {
 
2753
                    if (i)
 
2754
                        gen_op_stb_user();
 
2755
                    else
 
2756
                        gen_op_stb_kernel();
 
2757
                } else {
 
2758
                    if (i)
 
2759
                        gen_op_stl_user();
 
2760
                    else
 
2761
                        gen_op_stl_kernel();
 
2762
                }
 
2763
#endif
6654
2764
            }
6655
2765
            if (!(insn & (1 << 24))) {
6656
 
                gen_add_data_offset(s, insn, tmp2);
6657
 
                store_reg(s, rn, tmp2);
6658
 
            } else if (insn & (1 << 21)) {
6659
 
                store_reg(s, rn, tmp2);
6660
 
            } else {
6661
 
                dead_tmp(tmp2);
 
2766
                gen_add_data_offset(s, insn);
 
2767
                gen_movl_reg_T1(s, rn);
 
2768
            } else if (insn & (1 << 21))
 
2769
                gen_movl_reg_T1(s, rn); {
6662
2770
            }
6663
2771
            if (insn & (1 << 20)) {
6664
2772
                /* Complete the load.  */
6665
2773
                if (rd == 15)
6666
 
                    gen_bx(s, tmp);
 
2774
                    gen_bx(s);
6667
2775
                else
6668
 
                    store_reg(s, rd, tmp);
 
2776
                    gen_movl_reg_T0(s, rd);
6669
2777
            }
6670
2778
            break;
6671
2779
        case 0x08:
6672
2780
        case 0x09:
6673
2781
            {
6674
2782
                int j, n, user, loaded_base;
6675
 
                TCGv loaded_var;
6676
2783
                /* load/store multiple words */
6677
2784
                /* XXX: store correct base if write back */
6678
2785
                user = 0;
6684
2791
                        user = 1;
6685
2792
                }
6686
2793
                rn = (insn >> 16) & 0xf;
6687
 
                addr = load_reg(s, rn);
6688
 
 
 
2794
                gen_movl_T1_reg(s, rn);
 
2795
                
6689
2796
                /* compute total size */
6690
2797
                loaded_base = 0;
6691
 
                TCGV_UNUSED(loaded_var);
6692
2798
                n = 0;
6693
2799
                for(i=0;i<16;i++) {
6694
2800
                    if (insn & (1 << i))
6698
2804
                if (insn & (1 << 23)) {
6699
2805
                    if (insn & (1 << 24)) {
6700
2806
                        /* pre increment */
6701
 
                        tcg_gen_addi_i32(addr, addr, 4);
 
2807
                        gen_op_addl_T1_im(4);
6702
2808
                    } else {
6703
2809
                        /* post increment */
6704
2810
                    }
6705
2811
                } else {
6706
2812
                    if (insn & (1 << 24)) {
6707
2813
                        /* pre decrement */
6708
 
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
 
2814
                        gen_op_addl_T1_im(-(n * 4));
6709
2815
                    } else {
6710
2816
                        /* post decrement */
6711
2817
                        if (n != 1)
6712
 
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
 
2818
                            gen_op_addl_T1_im(-((n - 1) * 4));
6713
2819
                    }
6714
2820
                }
6715
2821
                j = 0;
6717
2823
                    if (insn & (1 << i)) {
6718
2824
                        if (insn & (1 << 20)) {
6719
2825
                            /* load */
6720
 
                            tmp = gen_ld32(addr, IS_USER(s));
 
2826
                            gen_ldst(ldl, s);
6721
2827
                            if (i == 15) {
6722
 
                                gen_bx(s, tmp);
 
2828
                                gen_bx(s);
6723
2829
                            } else if (user) {
6724
 
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6725
 
                                dead_tmp(tmp);
 
2830
                                gen_op_movl_user_T0(i);
6726
2831
                            } else if (i == rn) {
6727
 
                                loaded_var = tmp;
 
2832
                                gen_op_movl_T2_T0();
6728
2833
                                loaded_base = 1;
6729
2834
                            } else {
6730
 
                                store_reg(s, i, tmp);
 
2835
                                gen_movl_reg_T0(s, i);
6731
2836
                            }
6732
2837
                        } else {
6733
2838
                            /* store */
6734
2839
                            if (i == 15) {
6735
 
                                /* special case: r15 = PC + 8 */
6736
 
                                val = (long)s->pc + 4;
6737
 
                                tmp = new_tmp();
6738
 
                                tcg_gen_movi_i32(tmp, val);
 
2840
                                /* special case: r15 = PC + 12 */
 
2841
                                val = (long)s->pc + 8;
 
2842
                                gen_op_movl_TN_im[0](val);
6739
2843
                            } else if (user) {
6740
 
                                tmp = new_tmp();
6741
 
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
 
2844
                                gen_op_movl_T0_user(i);
6742
2845
                            } else {
6743
 
                                tmp = load_reg(s, i);
 
2846
                                gen_movl_T0_reg(s, i);
6744
2847
                            }
6745
 
                            gen_st32(tmp, addr, IS_USER(s));
 
2848
                            gen_ldst(stl, s);
6746
2849
                        }
6747
2850
                        j++;
6748
2851
                        /* no need to add after the last transfer */
6749
2852
                        if (j != n)
6750
 
                            tcg_gen_addi_i32(addr, addr, 4);
 
2853
                            gen_op_addl_T1_im(4);
6751
2854
                    }
6752
2855
                }
6753
2856
                if (insn & (1 << 21)) {
6757
2860
                            /* pre increment */
6758
2861
                        } else {
6759
2862
                            /* post increment */
6760
 
                            tcg_gen_addi_i32(addr, addr, 4);
 
2863
                            gen_op_addl_T1_im(4);
6761
2864
                        }
6762
2865
                    } else {
6763
2866
                        if (insn & (1 << 24)) {
6764
2867
                            /* pre decrement */
6765
2868
                            if (n != 1)
6766
 
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
 
2869
                                gen_op_addl_T1_im(-((n - 1) * 4));
6767
2870
                        } else {
6768
2871
                            /* post decrement */
6769
 
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
 
2872
                            gen_op_addl_T1_im(-(n * 4));
6770
2873
                        }
6771
2874
                    }
6772
 
                    store_reg(s, rn, addr);
6773
 
                } else {
6774
 
                    dead_tmp(addr);
 
2875
                    gen_movl_reg_T1(s, rn);
6775
2876
                }
6776
2877
                if (loaded_base) {
6777
 
                    store_reg(s, rn, loaded_var);
 
2878
                    gen_op_movl_T0_T2();
 
2879
                    gen_movl_reg_T0(s, rn);
6778
2880
                }
6779
2881
                if ((insn & (1 << 22)) && !user) {
6780
2882
                    /* Restore CPSR from SPSR.  */
6781
 
                    tmp = load_cpu_field(spsr);
6782
 
                    gen_set_cpsr(tmp, 0xffffffff);
6783
 
                    dead_tmp(tmp);
 
2883
                    gen_op_movl_T0_spsr();
 
2884
                    gen_op_movl_cpsr_T0(0xffffffff);
6784
2885
                    s->is_jmp = DISAS_UPDATE;
6785
2886
                }
6786
2887
            }
6789
2890
        case 0xb:
6790
2891
            {
6791
2892
                int32_t offset;
6792
 
 
 
2893
                
6793
2894
                /* branch (and link) */
6794
2895
                val = (int32_t)s->pc;
6795
2896
                if (insn & (1 << 24)) {
6796
 
                    tmp = new_tmp();
6797
 
                    tcg_gen_movi_i32(tmp, val);
6798
 
                    store_reg(s, 14, tmp);
 
2897
                    gen_op_movl_T0_im(val);
 
2898
                    gen_op_movl_reg_TN[0][14]();
6799
2899
                }
6800
2900
                offset = (((int32_t)insn << 8) >> 8);
6801
2901
                val += (offset << 2) + 4;
6806
2906
        case 0xd:
6807
2907
        case 0xe:
6808
2908
            /* Coprocessor.  */
6809
 
            if (disas_coproc_insn(env, s, insn))
6810
 
                goto illegal_op;
 
2909
            op1 = (insn >> 8) & 0xf;
 
2910
            if (arm_feature(env, ARM_FEATURE_XSCALE) &&
 
2911
                    ((env->cp15.c15_cpar ^ 0x3fff) & (1 << op1)))
 
2912
                goto illegal_op;
 
2913
            switch (op1) {
 
2914
            case 0 ... 1:
 
2915
                if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 
2916
                    if (disas_iwmmxt_insn(env, s, insn))
 
2917
                        goto illegal_op;
 
2918
                } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
 
2919
                    if (disas_dsp_insn(env, s, insn))
 
2920
                        goto illegal_op;
 
2921
                } else
 
2922
                    goto illegal_op;
 
2923
                break;
 
2924
            case 2 ... 9:
 
2925
            case 12 ... 14:
 
2926
                if (disas_cp_insn (env, s, insn))
 
2927
                    goto illegal_op;
 
2928
                break;
 
2929
            case 10:
 
2930
            case 11:
 
2931
                if (disas_vfp_insn (env, s, insn))
 
2932
                    goto illegal_op;
 
2933
                break;
 
2934
            case 15:
 
2935
                if (disas_cp15_insn (env, s, insn))
 
2936
                    goto illegal_op;
 
2937
                break;
 
2938
            default:
 
2939
                /* unknown coprocessor.  */
 
2940
                goto illegal_op;
 
2941
            }
6811
2942
            break;
6812
2943
        case 0xf:
6813
2944
            /* swi */
6814
 
            gen_set_pc_im(s->pc);
6815
 
            s->is_jmp = DISAS_SWI;
 
2945
            gen_op_movl_T0_im((long)s->pc);
 
2946
            gen_op_movl_reg_TN[0][15]();
 
2947
            gen_op_swi();
 
2948
            s->is_jmp = DISAS_JUMP;
6816
2949
            break;
6817
2950
        default:
6818
2951
        illegal_op:
6819
 
            gen_set_condexec(s);
6820
 
            gen_set_pc_im(s->pc - 4);
6821
 
            gen_exception(EXCP_UDEF);
 
2952
            gen_op_movl_T0_im((long)s->pc - 4);
 
2953
            gen_op_movl_reg_TN[0][15]();
 
2954
            gen_op_undef_insn();
6822
2955
            s->is_jmp = DISAS_JUMP;
6823
2956
            break;
6824
2957
        }
6825
2958
    }
6826
2959
}
6827
2960
 
6828
 
/* Return true if this is a Thumb-2 logical op.  */
6829
 
static int
6830
 
thumb2_logic_op(int op)
6831
 
{
6832
 
    return (op < 8);
6833
 
}
6834
 
 
6835
 
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6836
 
   then set condition code flags based on the result of the operation.
6837
 
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6838
 
   to the high bit of T1.
6839
 
   Returns zero if the opcode is valid.  */
6840
 
 
6841
 
static int
6842
 
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6843
 
{
6844
 
    int logic_cc;
6845
 
 
6846
 
    logic_cc = 0;
6847
 
    switch (op) {
6848
 
    case 0: /* and */
6849
 
        gen_op_andl_T0_T1();
6850
 
        logic_cc = conds;
6851
 
        break;
6852
 
    case 1: /* bic */
6853
 
        gen_op_bicl_T0_T1();
6854
 
        logic_cc = conds;
6855
 
        break;
6856
 
    case 2: /* orr */
6857
 
        gen_op_orl_T0_T1();
6858
 
        logic_cc = conds;
6859
 
        break;
6860
 
    case 3: /* orn */
6861
 
        gen_op_notl_T1();
6862
 
        gen_op_orl_T0_T1();
6863
 
        logic_cc = conds;
6864
 
        break;
6865
 
    case 4: /* eor */
6866
 
        gen_op_xorl_T0_T1();
6867
 
        logic_cc = conds;
6868
 
        break;
6869
 
    case 8: /* add */
6870
 
        if (conds)
6871
 
            gen_op_addl_T0_T1_cc();
6872
 
        else
6873
 
            gen_op_addl_T0_T1();
6874
 
        break;
6875
 
    case 10: /* adc */
6876
 
        if (conds)
6877
 
            gen_op_adcl_T0_T1_cc();
6878
 
        else
6879
 
            gen_adc_T0_T1();
6880
 
        break;
6881
 
    case 11: /* sbc */
6882
 
        if (conds)
6883
 
            gen_op_sbcl_T0_T1_cc();
6884
 
        else
6885
 
            gen_sbc_T0_T1();
6886
 
        break;
6887
 
    case 13: /* sub */
6888
 
        if (conds)
6889
 
            gen_op_subl_T0_T1_cc();
6890
 
        else
6891
 
            gen_op_subl_T0_T1();
6892
 
        break;
6893
 
    case 14: /* rsb */
6894
 
        if (conds)
6895
 
            gen_op_rsbl_T0_T1_cc();
6896
 
        else
6897
 
            gen_op_rsbl_T0_T1();
6898
 
        break;
6899
 
    default: /* 5, 6, 7, 9, 12, 15. */
6900
 
        return 1;
6901
 
    }
6902
 
    if (logic_cc) {
6903
 
        gen_op_logic_T0_cc();
6904
 
        if (shifter_out)
6905
 
            gen_set_CF_bit31(cpu_T[1]);
6906
 
    }
6907
 
    return 0;
6908
 
}
6909
 
 
6910
 
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6911
 
   is not legal.  */
6912
 
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6913
 
{
6914
 
    uint32_t insn, imm, shift, offset;
6915
 
    uint32_t rd, rn, rm, rs;
6916
 
    TCGv tmp;
6917
 
    TCGv tmp2;
6918
 
    TCGv tmp3;
6919
 
    TCGv addr;
6920
 
    int op;
6921
 
    int shiftop;
6922
 
    int conds;
6923
 
    int logic_cc;
6924
 
 
6925
 
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6926
 
          || arm_feature (env, ARM_FEATURE_M))) {
6927
 
        /* Thumb-1 cores may need to treat bl and blx as a pair of
6928
 
           16-bit instructions to get correct prefetch abort behavior.  */
6929
 
        insn = insn_hw1;
6930
 
        if ((insn & (1 << 12)) == 0) {
6931
 
            /* Second half of blx.  */
6932
 
            offset = ((insn & 0x7ff) << 1);
6933
 
            tmp = load_reg(s, 14);
6934
 
            tcg_gen_addi_i32(tmp, tmp, offset);
6935
 
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6936
 
 
6937
 
            tmp2 = new_tmp();
6938
 
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6939
 
            store_reg(s, 14, tmp2);
6940
 
            gen_bx(s, tmp);
6941
 
            return 0;
6942
 
        }
6943
 
        if (insn & (1 << 11)) {
6944
 
            /* Second half of bl.  */
6945
 
            offset = ((insn & 0x7ff) << 1) | 1;
6946
 
            tmp = load_reg(s, 14);
6947
 
            tcg_gen_addi_i32(tmp, tmp, offset);
6948
 
 
6949
 
            tmp2 = new_tmp();
6950
 
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6951
 
            store_reg(s, 14, tmp2);
6952
 
            gen_bx(s, tmp);
6953
 
            return 0;
6954
 
        }
6955
 
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6956
 
            /* Instruction spans a page boundary.  Implement it as two
6957
 
               16-bit instructions in case the second half causes an
6958
 
               prefetch abort.  */
6959
 
            offset = ((int32_t)insn << 21) >> 9;
6960
 
            gen_op_movl_T0_im(s->pc + 2 + offset);
6961
 
            gen_movl_reg_T0(s, 14);
6962
 
            return 0;
6963
 
        }
6964
 
        /* Fall through to 32-bit decode.  */
6965
 
    }
6966
 
 
6967
 
    insn = lduw_code(s->pc);
6968
 
    s->pc += 2;
6969
 
    insn |= (uint32_t)insn_hw1 << 16;
6970
 
 
6971
 
    if ((insn & 0xf800e800) != 0xf000e800) {
6972
 
        ARCH(6T2);
6973
 
    }
6974
 
 
6975
 
    rn = (insn >> 16) & 0xf;
6976
 
    rs = (insn >> 12) & 0xf;
6977
 
    rd = (insn >> 8) & 0xf;
6978
 
    rm = insn & 0xf;
6979
 
    switch ((insn >> 25) & 0xf) {
6980
 
    case 0: case 1: case 2: case 3:
6981
 
        /* 16-bit instructions.  Should never happen.  */
6982
 
        abort();
6983
 
    case 4:
6984
 
        if (insn & (1 << 22)) {
6985
 
            /* Other load/store, table branch.  */
6986
 
            if (insn & 0x01200000) {
6987
 
                /* Load/store doubleword.  */
6988
 
                if (rn == 15) {
6989
 
                    addr = new_tmp();
6990
 
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6991
 
                } else {
6992
 
                    addr = load_reg(s, rn);
6993
 
                }
6994
 
                offset = (insn & 0xff) * 4;
6995
 
                if ((insn & (1 << 23)) == 0)
6996
 
                    offset = -offset;
6997
 
                if (insn & (1 << 24)) {
6998
 
                    tcg_gen_addi_i32(addr, addr, offset);
6999
 
                    offset = 0;
7000
 
                }
7001
 
                if (insn & (1 << 20)) {
7002
 
                    /* ldrd */
7003
 
                    tmp = gen_ld32(addr, IS_USER(s));
7004
 
                    store_reg(s, rs, tmp);
7005
 
                    tcg_gen_addi_i32(addr, addr, 4);
7006
 
                    tmp = gen_ld32(addr, IS_USER(s));
7007
 
                    store_reg(s, rd, tmp);
7008
 
                } else {
7009
 
                    /* strd */
7010
 
                    tmp = load_reg(s, rs);
7011
 
                    gen_st32(tmp, addr, IS_USER(s));
7012
 
                    tcg_gen_addi_i32(addr, addr, 4);
7013
 
                    tmp = load_reg(s, rd);
7014
 
                    gen_st32(tmp, addr, IS_USER(s));
7015
 
                }
7016
 
                if (insn & (1 << 21)) {
7017
 
                    /* Base writeback.  */
7018
 
                    if (rn == 15)
7019
 
                        goto illegal_op;
7020
 
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7021
 
                    store_reg(s, rn, addr);
7022
 
                } else {
7023
 
                    dead_tmp(addr);
7024
 
                }
7025
 
            } else if ((insn & (1 << 23)) == 0) {
7026
 
                /* Load/store exclusive word.  */
7027
 
                gen_movl_T1_reg(s, rn);
7028
 
                addr = cpu_T[1];
7029
 
                if (insn & (1 << 20)) {
7030
 
                    gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
7031
 
                    tmp = gen_ld32(addr, IS_USER(s));
7032
 
                    store_reg(s, rd, tmp);
7033
 
                } else {
7034
 
                    int label = gen_new_label();
7035
 
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7036
 
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
7037
 
                                        0, label);
7038
 
                    tmp = load_reg(s, rs);
7039
 
                    gen_st32(tmp, cpu_T[1], IS_USER(s));
7040
 
                    gen_set_label(label);
7041
 
                    gen_movl_reg_T0(s, rd);
7042
 
                }
7043
 
            } else if ((insn & (1 << 6)) == 0) {
7044
 
                /* Table Branch.  */
7045
 
                if (rn == 15) {
7046
 
                    addr = new_tmp();
7047
 
                    tcg_gen_movi_i32(addr, s->pc);
7048
 
                } else {
7049
 
                    addr = load_reg(s, rn);
7050
 
                }
7051
 
                tmp = load_reg(s, rm);
7052
 
                tcg_gen_add_i32(addr, addr, tmp);
7053
 
                if (insn & (1 << 4)) {
7054
 
                    /* tbh */
7055
 
                    tcg_gen_add_i32(addr, addr, tmp);
7056
 
                    dead_tmp(tmp);
7057
 
                    tmp = gen_ld16u(addr, IS_USER(s));
7058
 
                } else { /* tbb */
7059
 
                    dead_tmp(tmp);
7060
 
                    tmp = gen_ld8u(addr, IS_USER(s));
7061
 
                }
7062
 
                dead_tmp(addr);
7063
 
                tcg_gen_shli_i32(tmp, tmp, 1);
7064
 
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7065
 
                store_reg(s, 15, tmp);
7066
 
            } else {
7067
 
                /* Load/store exclusive byte/halfword/doubleword.  */
7068
 
                /* ??? These are not really atomic.  However we know
7069
 
                   we never have multiple CPUs running in parallel,
7070
 
                   so it is good enough.  */
7071
 
                op = (insn >> 4) & 0x3;
7072
 
                /* Must use a global reg for the address because we have
7073
 
                   a conditional branch in the store instruction.  */
7074
 
                gen_movl_T1_reg(s, rn);
7075
 
                addr = cpu_T[1];
7076
 
                if (insn & (1 << 20)) {
7077
 
                    gen_helper_mark_exclusive(cpu_env, addr);
7078
 
                    switch (op) {
7079
 
                    case 0:
7080
 
                        tmp = gen_ld8u(addr, IS_USER(s));
7081
 
                        break;
7082
 
                    case 1:
7083
 
                        tmp = gen_ld16u(addr, IS_USER(s));
7084
 
                        break;
7085
 
                    case 3:
7086
 
                        tmp = gen_ld32(addr, IS_USER(s));
7087
 
                        tcg_gen_addi_i32(addr, addr, 4);
7088
 
                        tmp2 = gen_ld32(addr, IS_USER(s));
7089
 
                        store_reg(s, rd, tmp2);
7090
 
                        break;
7091
 
                    default:
7092
 
                        goto illegal_op;
7093
 
                    }
7094
 
                    store_reg(s, rs, tmp);
7095
 
                } else {
7096
 
                    int label = gen_new_label();
7097
 
                    /* Must use a global that is not killed by the branch.  */
7098
 
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7099
 
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7100
 
                    tmp = load_reg(s, rs);
7101
 
                    switch (op) {
7102
 
                    case 0:
7103
 
                        gen_st8(tmp, addr, IS_USER(s));
7104
 
                        break;
7105
 
                    case 1:
7106
 
                        gen_st16(tmp, addr, IS_USER(s));
7107
 
                        break;
7108
 
                    case 3:
7109
 
                        gen_st32(tmp, addr, IS_USER(s));
7110
 
                        tcg_gen_addi_i32(addr, addr, 4);
7111
 
                        tmp = load_reg(s, rd);
7112
 
                        gen_st32(tmp, addr, IS_USER(s));
7113
 
                        break;
7114
 
                    default:
7115
 
                        goto illegal_op;
7116
 
                    }
7117
 
                    gen_set_label(label);
7118
 
                    gen_movl_reg_T0(s, rm);
7119
 
                }
7120
 
            }
7121
 
        } else {
7122
 
            /* Load/store multiple, RFE, SRS.  */
7123
 
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7124
 
                /* Not available in user mode.  */
7125
 
                if (IS_USER(s))
7126
 
                    goto illegal_op;
7127
 
                if (insn & (1 << 20)) {
7128
 
                    /* rfe */
7129
 
                    addr = load_reg(s, rn);
7130
 
                    if ((insn & (1 << 24)) == 0)
7131
 
                        tcg_gen_addi_i32(addr, addr, -8);
7132
 
                    /* Load PC into tmp and CPSR into tmp2.  */
7133
 
                    tmp = gen_ld32(addr, 0);
7134
 
                    tcg_gen_addi_i32(addr, addr, 4);
7135
 
                    tmp2 = gen_ld32(addr, 0);
7136
 
                    if (insn & (1 << 21)) {
7137
 
                        /* Base writeback.  */
7138
 
                        if (insn & (1 << 24)) {
7139
 
                            tcg_gen_addi_i32(addr, addr, 4);
7140
 
                        } else {
7141
 
                            tcg_gen_addi_i32(addr, addr, -4);
7142
 
                        }
7143
 
                        store_reg(s, rn, addr);
7144
 
                    } else {
7145
 
                        dead_tmp(addr);
7146
 
                    }
7147
 
                    gen_rfe(s, tmp, tmp2);
7148
 
                } else {
7149
 
                    /* srs */
7150
 
                    op = (insn & 0x1f);
7151
 
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7152
 
                        addr = load_reg(s, 13);
7153
 
                    } else {
7154
 
                        addr = new_tmp();
7155
 
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7156
 
                    }
7157
 
                    if ((insn & (1 << 24)) == 0) {
7158
 
                        tcg_gen_addi_i32(addr, addr, -8);
7159
 
                    }
7160
 
                    tmp = load_reg(s, 14);
7161
 
                    gen_st32(tmp, addr, 0);
7162
 
                    tcg_gen_addi_i32(addr, addr, 4);
7163
 
                    tmp = new_tmp();
7164
 
                    gen_helper_cpsr_read(tmp);
7165
 
                    gen_st32(tmp, addr, 0);
7166
 
                    if (insn & (1 << 21)) {
7167
 
                        if ((insn & (1 << 24)) == 0) {
7168
 
                            tcg_gen_addi_i32(addr, addr, -4);
7169
 
                        } else {
7170
 
                            tcg_gen_addi_i32(addr, addr, 4);
7171
 
                        }
7172
 
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7173
 
                            store_reg(s, 13, addr);
7174
 
                        } else {
7175
 
                            gen_helper_set_r13_banked(cpu_env,
7176
 
                                tcg_const_i32(op), addr);
7177
 
                        }
7178
 
                    } else {
7179
 
                        dead_tmp(addr);
7180
 
                    }
7181
 
                }
7182
 
            } else {
7183
 
                int i;
7184
 
                /* Load/store multiple.  */
7185
 
                addr = load_reg(s, rn);
7186
 
                offset = 0;
7187
 
                for (i = 0; i < 16; i++) {
7188
 
                    if (insn & (1 << i))
7189
 
                        offset += 4;
7190
 
                }
7191
 
                if (insn & (1 << 24)) {
7192
 
                    tcg_gen_addi_i32(addr, addr, -offset);
7193
 
                }
7194
 
 
7195
 
                for (i = 0; i < 16; i++) {
7196
 
                    if ((insn & (1 << i)) == 0)
7197
 
                        continue;
7198
 
                    if (insn & (1 << 20)) {
7199
 
                        /* Load.  */
7200
 
                        tmp = gen_ld32(addr, IS_USER(s));
7201
 
                        if (i == 15) {
7202
 
                            gen_bx(s, tmp);
7203
 
                        } else {
7204
 
                            store_reg(s, i, tmp);
7205
 
                        }
7206
 
                    } else {
7207
 
                        /* Store.  */
7208
 
                        tmp = load_reg(s, i);
7209
 
                        gen_st32(tmp, addr, IS_USER(s));
7210
 
                    }
7211
 
                    tcg_gen_addi_i32(addr, addr, 4);
7212
 
                }
7213
 
                if (insn & (1 << 21)) {
7214
 
                    /* Base register writeback.  */
7215
 
                    if (insn & (1 << 24)) {
7216
 
                        tcg_gen_addi_i32(addr, addr, -offset);
7217
 
                    }
7218
 
                    /* Fault if writeback register is in register list.  */
7219
 
                    if (insn & (1 << rn))
7220
 
                        goto illegal_op;
7221
 
                    store_reg(s, rn, addr);
7222
 
                } else {
7223
 
                    dead_tmp(addr);
7224
 
                }
7225
 
            }
7226
 
        }
7227
 
        break;
7228
 
    case 5: /* Data processing register constant shift.  */
7229
 
        if (rn == 15)
7230
 
            gen_op_movl_T0_im(0);
7231
 
        else
7232
 
            gen_movl_T0_reg(s, rn);
7233
 
        gen_movl_T1_reg(s, rm);
7234
 
        op = (insn >> 21) & 0xf;
7235
 
        shiftop = (insn >> 4) & 3;
7236
 
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7237
 
        conds = (insn & (1 << 20)) != 0;
7238
 
        logic_cc = (conds && thumb2_logic_op(op));
7239
 
        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7240
 
        if (gen_thumb2_data_op(s, op, conds, 0))
7241
 
            goto illegal_op;
7242
 
        if (rd != 15)
7243
 
            gen_movl_reg_T0(s, rd);
7244
 
        break;
7245
 
    case 13: /* Misc data processing.  */
7246
 
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7247
 
        if (op < 4 && (insn & 0xf000) != 0xf000)
7248
 
            goto illegal_op;
7249
 
        switch (op) {
7250
 
        case 0: /* Register controlled shift.  */
7251
 
            tmp = load_reg(s, rn);
7252
 
            tmp2 = load_reg(s, rm);
7253
 
            if ((insn & 0x70) != 0)
7254
 
                goto illegal_op;
7255
 
            op = (insn >> 21) & 3;
7256
 
            logic_cc = (insn & (1 << 20)) != 0;
7257
 
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7258
 
            if (logic_cc)
7259
 
                gen_logic_CC(tmp);
7260
 
            store_reg(s, rd, tmp);
7261
 
            break;
7262
 
        case 1: /* Sign/zero extend.  */
7263
 
            tmp = load_reg(s, rm);
7264
 
            shift = (insn >> 4) & 3;
7265
 
            /* ??? In many cases it's not neccessary to do a
7266
 
               rotate, a shift is sufficient.  */
7267
 
            if (shift != 0)
7268
 
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
7269
 
            op = (insn >> 20) & 7;
7270
 
            switch (op) {
7271
 
            case 0: gen_sxth(tmp);   break;
7272
 
            case 1: gen_uxth(tmp);   break;
7273
 
            case 2: gen_sxtb16(tmp); break;
7274
 
            case 3: gen_uxtb16(tmp); break;
7275
 
            case 4: gen_sxtb(tmp);   break;
7276
 
            case 5: gen_uxtb(tmp);   break;
7277
 
            default: goto illegal_op;
7278
 
            }
7279
 
            if (rn != 15) {
7280
 
                tmp2 = load_reg(s, rn);
7281
 
                if ((op >> 1) == 1) {
7282
 
                    gen_add16(tmp, tmp2);
7283
 
                } else {
7284
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7285
 
                    dead_tmp(tmp2);
7286
 
                }
7287
 
            }
7288
 
            store_reg(s, rd, tmp);
7289
 
            break;
7290
 
        case 2: /* SIMD add/subtract.  */
7291
 
            op = (insn >> 20) & 7;
7292
 
            shift = (insn >> 4) & 7;
7293
 
            if ((op & 3) == 3 || (shift & 3) == 3)
7294
 
                goto illegal_op;
7295
 
            tmp = load_reg(s, rn);
7296
 
            tmp2 = load_reg(s, rm);
7297
 
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7298
 
            dead_tmp(tmp2);
7299
 
            store_reg(s, rd, tmp);
7300
 
            break;
7301
 
        case 3: /* Other data processing.  */
7302
 
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7303
 
            if (op < 4) {
7304
 
                /* Saturating add/subtract.  */
7305
 
                tmp = load_reg(s, rn);
7306
 
                tmp2 = load_reg(s, rm);
7307
 
                if (op & 2)
7308
 
                    gen_helper_double_saturate(tmp, tmp);
7309
 
                if (op & 1)
7310
 
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7311
 
                else
7312
 
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7313
 
                dead_tmp(tmp2);
7314
 
            } else {
7315
 
                tmp = load_reg(s, rn);
7316
 
                switch (op) {
7317
 
                case 0x0a: /* rbit */
7318
 
                    gen_helper_rbit(tmp, tmp);
7319
 
                    break;
7320
 
                case 0x08: /* rev */
7321
 
                    tcg_gen_bswap_i32(tmp, tmp);
7322
 
                    break;
7323
 
                case 0x09: /* rev16 */
7324
 
                    gen_rev16(tmp);
7325
 
                    break;
7326
 
                case 0x0b: /* revsh */
7327
 
                    gen_revsh(tmp);
7328
 
                    break;
7329
 
                case 0x10: /* sel */
7330
 
                    tmp2 = load_reg(s, rm);
7331
 
                    tmp3 = new_tmp();
7332
 
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7333
 
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7334
 
                    dead_tmp(tmp3);
7335
 
                    dead_tmp(tmp2);
7336
 
                    break;
7337
 
                case 0x18: /* clz */
7338
 
                    gen_helper_clz(tmp, tmp);
7339
 
                    break;
7340
 
                default:
7341
 
                    goto illegal_op;
7342
 
                }
7343
 
            }
7344
 
            store_reg(s, rd, tmp);
7345
 
            break;
7346
 
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7347
 
            op = (insn >> 4) & 0xf;
7348
 
            tmp = load_reg(s, rn);
7349
 
            tmp2 = load_reg(s, rm);
7350
 
            switch ((insn >> 20) & 7) {
7351
 
            case 0: /* 32 x 32 -> 32 */
7352
 
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7353
 
                dead_tmp(tmp2);
7354
 
                if (rs != 15) {
7355
 
                    tmp2 = load_reg(s, rs);
7356
 
                    if (op)
7357
 
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7358
 
                    else
7359
 
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7360
 
                    dead_tmp(tmp2);
7361
 
                }
7362
 
                break;
7363
 
            case 1: /* 16 x 16 -> 32 */
7364
 
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7365
 
                dead_tmp(tmp2);
7366
 
                if (rs != 15) {
7367
 
                    tmp2 = load_reg(s, rs);
7368
 
                    gen_helper_add_setq(tmp, tmp, tmp2);
7369
 
                    dead_tmp(tmp2);
7370
 
                }
7371
 
                break;
7372
 
            case 2: /* Dual multiply add.  */
7373
 
            case 4: /* Dual multiply subtract.  */
7374
 
                if (op)
7375
 
                    gen_swap_half(tmp2);
7376
 
                gen_smul_dual(tmp, tmp2);
7377
 
                /* This addition cannot overflow.  */
7378
 
                if (insn & (1 << 22)) {
7379
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7380
 
                } else {
7381
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7382
 
                }
7383
 
                dead_tmp(tmp2);
7384
 
                if (rs != 15)
7385
 
                  {
7386
 
                    tmp2 = load_reg(s, rs);
7387
 
                    gen_helper_add_setq(tmp, tmp, tmp2);
7388
 
                    dead_tmp(tmp2);
7389
 
                  }
7390
 
                break;
7391
 
            case 3: /* 32 * 16 -> 32msb */
7392
 
                if (op)
7393
 
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7394
 
                else
7395
 
                    gen_sxth(tmp2);
7396
 
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
7397
 
                tcg_gen_shri_i64(tmp2, tmp2, 16);
7398
 
                tmp = new_tmp();
7399
 
                tcg_gen_trunc_i64_i32(tmp, tmp2);
7400
 
                if (rs != 15)
7401
 
                  {
7402
 
                    tmp2 = load_reg(s, rs);
7403
 
                    gen_helper_add_setq(tmp, tmp, tmp2);
7404
 
                    dead_tmp(tmp2);
7405
 
                  }
7406
 
                break;
7407
 
            case 5: case 6: /* 32 * 32 -> 32msb */
7408
 
                gen_imull(tmp, tmp2);
7409
 
                if (insn & (1 << 5)) {
7410
 
                    gen_roundqd(tmp, tmp2);
7411
 
                    dead_tmp(tmp2);
7412
 
                } else {
7413
 
                    dead_tmp(tmp);
7414
 
                    tmp = tmp2;
7415
 
                }
7416
 
                if (rs != 15) {
7417
 
                    tmp2 = load_reg(s, rs);
7418
 
                    if (insn & (1 << 21)) {
7419
 
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7420
 
                    } else {
7421
 
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7422
 
                    }
7423
 
                    dead_tmp(tmp2);
7424
 
                }
7425
 
                break;
7426
 
            case 7: /* Unsigned sum of absolute differences.  */
7427
 
                gen_helper_usad8(tmp, tmp, tmp2);
7428
 
                dead_tmp(tmp2);
7429
 
                if (rs != 15) {
7430
 
                    tmp2 = load_reg(s, rs);
7431
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7432
 
                    dead_tmp(tmp2);
7433
 
                }
7434
 
                break;
7435
 
            }
7436
 
            store_reg(s, rd, tmp);
7437
 
            break;
7438
 
        case 6: case 7: /* 64-bit multiply, Divide.  */
7439
 
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7440
 
            tmp = load_reg(s, rn);
7441
 
            tmp2 = load_reg(s, rm);
7442
 
            if ((op & 0x50) == 0x10) {
7443
 
                /* sdiv, udiv */
7444
 
                if (!arm_feature(env, ARM_FEATURE_DIV))
7445
 
                    goto illegal_op;
7446
 
                if (op & 0x20)
7447
 
                    gen_helper_udiv(tmp, tmp, tmp2);
7448
 
                else
7449
 
                    gen_helper_sdiv(tmp, tmp, tmp2);
7450
 
                dead_tmp(tmp2);
7451
 
                store_reg(s, rd, tmp);
7452
 
            } else if ((op & 0xe) == 0xc) {
7453
 
                /* Dual multiply accumulate long.  */
7454
 
                if (op & 1)
7455
 
                    gen_swap_half(tmp2);
7456
 
                gen_smul_dual(tmp, tmp2);
7457
 
                if (op & 0x10) {
7458
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7459
 
                } else {
7460
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7461
 
                }
7462
 
                dead_tmp(tmp2);
7463
 
                tmp2 = tcg_temp_new(TCG_TYPE_I64);
7464
 
                gen_addq(s, tmp, rs, rd);
7465
 
                gen_storeq_reg(s, rs, rd, tmp);
7466
 
            } else {
7467
 
                if (op & 0x20) {
7468
 
                    /* Unsigned 64-bit multiply  */
7469
 
                    tmp = gen_mulu_i64_i32(tmp, tmp2);
7470
 
                } else {
7471
 
                    if (op & 8) {
7472
 
                        /* smlalxy */
7473
 
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7474
 
                        dead_tmp(tmp2);
7475
 
                        tmp2 = tcg_temp_new(TCG_TYPE_I64);
7476
 
                        tcg_gen_ext_i32_i64(tmp2, tmp);
7477
 
                        dead_tmp(tmp);
7478
 
                        tmp = tmp2;
7479
 
                    } else {
7480
 
                        /* Signed 64-bit multiply  */
7481
 
                        tmp = gen_muls_i64_i32(tmp, tmp2);
7482
 
                    }
7483
 
                }
7484
 
                if (op & 4) {
7485
 
                    /* umaal */
7486
 
                    gen_addq_lo(s, tmp, rs);
7487
 
                    gen_addq_lo(s, tmp, rd);
7488
 
                } else if (op & 0x40) {
7489
 
                    /* 64-bit accumulate.  */
7490
 
                    gen_addq(s, tmp, rs, rd);
7491
 
                }
7492
 
                gen_storeq_reg(s, rs, rd, tmp);
7493
 
            }
7494
 
            break;
7495
 
        }
7496
 
        break;
7497
 
    case 6: case 7: case 14: case 15:
7498
 
        /* Coprocessor.  */
7499
 
        if (((insn >> 24) & 3) == 3) {
7500
 
            /* Translate into the equivalent ARM encoding.  */
7501
 
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7502
 
            if (disas_neon_data_insn(env, s, insn))
7503
 
                goto illegal_op;
7504
 
        } else {
7505
 
            if (insn & (1 << 28))
7506
 
                goto illegal_op;
7507
 
            if (disas_coproc_insn (env, s, insn))
7508
 
                goto illegal_op;
7509
 
        }
7510
 
        break;
7511
 
    case 8: case 9: case 10: case 11:
7512
 
        if (insn & (1 << 15)) {
7513
 
            /* Branches, misc control.  */
7514
 
            if (insn & 0x5000) {
7515
 
                /* Unconditional branch.  */
7516
 
                /* signextend(hw1[10:0]) -> offset[:12].  */
7517
 
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7518
 
                /* hw1[10:0] -> offset[11:1].  */
7519
 
                offset |= (insn & 0x7ff) << 1;
7520
 
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7521
 
                   offset[24:22] already have the same value because of the
7522
 
                   sign extension above.  */
7523
 
                offset ^= ((~insn) & (1 << 13)) << 10;
7524
 
                offset ^= ((~insn) & (1 << 11)) << 11;
7525
 
 
7526
 
                if (insn & (1 << 14)) {
7527
 
                    /* Branch and link.  */
7528
 
                    gen_op_movl_T1_im(s->pc | 1);
7529
 
                    gen_movl_reg_T1(s, 14);
7530
 
                }
7531
 
 
7532
 
                offset += s->pc;
7533
 
                if (insn & (1 << 12)) {
7534
 
                    /* b/bl */
7535
 
                    gen_jmp(s, offset);
7536
 
                } else {
7537
 
                    /* blx */
7538
 
                    offset &= ~(uint32_t)2;
7539
 
                    gen_bx_im(s, offset);
7540
 
                }
7541
 
            } else if (((insn >> 23) & 7) == 7) {
7542
 
                /* Misc control */
7543
 
                if (insn & (1 << 13))
7544
 
                    goto illegal_op;
7545
 
 
7546
 
                if (insn & (1 << 26)) {
7547
 
                    /* Secure monitor call (v6Z) */
7548
 
                    goto illegal_op; /* not implemented.  */
7549
 
                } else {
7550
 
                    op = (insn >> 20) & 7;
7551
 
                    switch (op) {
7552
 
                    case 0: /* msr cpsr.  */
7553
 
                        if (IS_M(env)) {
7554
 
                            tmp = load_reg(s, rn);
7555
 
                            addr = tcg_const_i32(insn & 0xff);
7556
 
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7557
 
                            gen_lookup_tb(s);
7558
 
                            break;
7559
 
                        }
7560
 
                        /* fall through */
7561
 
                    case 1: /* msr spsr.  */
7562
 
                        if (IS_M(env))
7563
 
                            goto illegal_op;
7564
 
                        gen_movl_T0_reg(s, rn);
7565
 
                        if (gen_set_psr_T0(s,
7566
 
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7567
 
                              op == 1))
7568
 
                            goto illegal_op;
7569
 
                        break;
7570
 
                    case 2: /* cps, nop-hint.  */
7571
 
                        if (((insn >> 8) & 7) == 0) {
7572
 
                            gen_nop_hint(s, insn & 0xff);
7573
 
                        }
7574
 
                        /* Implemented as NOP in user mode.  */
7575
 
                        if (IS_USER(s))
7576
 
                            break;
7577
 
                        offset = 0;
7578
 
                        imm = 0;
7579
 
                        if (insn & (1 << 10)) {
7580
 
                            if (insn & (1 << 7))
7581
 
                                offset |= CPSR_A;
7582
 
                            if (insn & (1 << 6))
7583
 
                                offset |= CPSR_I;
7584
 
                            if (insn & (1 << 5))
7585
 
                                offset |= CPSR_F;
7586
 
                            if (insn & (1 << 9))
7587
 
                                imm = CPSR_A | CPSR_I | CPSR_F;
7588
 
                        }
7589
 
                        if (insn & (1 << 8)) {
7590
 
                            offset |= 0x1f;
7591
 
                            imm |= (insn & 0x1f);
7592
 
                        }
7593
 
                        if (offset) {
7594
 
                            gen_op_movl_T0_im(imm);
7595
 
                            gen_set_psr_T0(s, offset, 0);
7596
 
                        }
7597
 
                        break;
7598
 
                    case 3: /* Special control operations.  */
7599
 
                        op = (insn >> 4) & 0xf;
7600
 
                        switch (op) {
7601
 
                        case 2: /* clrex */
7602
 
                            gen_helper_clrex(cpu_env);
7603
 
                            break;
7604
 
                        case 4: /* dsb */
7605
 
                        case 5: /* dmb */
7606
 
                        case 6: /* isb */
7607
 
                            /* These execute as NOPs.  */
7608
 
                            ARCH(7);
7609
 
                            break;
7610
 
                        default:
7611
 
                            goto illegal_op;
7612
 
                        }
7613
 
                        break;
7614
 
                    case 4: /* bxj */
7615
 
                        /* Trivial implementation equivalent to bx.  */
7616
 
                        tmp = load_reg(s, rn);
7617
 
                        gen_bx(s, tmp);
7618
 
                        break;
7619
 
                    case 5: /* Exception return.  */
7620
 
                        /* Unpredictable in user mode.  */
7621
 
                        goto illegal_op;
7622
 
                    case 6: /* mrs cpsr.  */
7623
 
                        tmp = new_tmp();
7624
 
                        if (IS_M(env)) {
7625
 
                            addr = tcg_const_i32(insn & 0xff);
7626
 
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7627
 
                        } else {
7628
 
                            gen_helper_cpsr_read(tmp);
7629
 
                        }
7630
 
                        store_reg(s, rd, tmp);
7631
 
                        break;
7632
 
                    case 7: /* mrs spsr.  */
7633
 
                        /* Not accessible in user mode.  */
7634
 
                        if (IS_USER(s) || IS_M(env))
7635
 
                            goto illegal_op;
7636
 
                        tmp = load_cpu_field(spsr);
7637
 
                        store_reg(s, rd, tmp);
7638
 
                        break;
7639
 
                    }
7640
 
                }
7641
 
            } else {
7642
 
                /* Conditional branch.  */
7643
 
                op = (insn >> 22) & 0xf;
7644
 
                /* Generate a conditional jump to next instruction.  */
7645
 
                s->condlabel = gen_new_label();
7646
 
                gen_test_cc(op ^ 1, s->condlabel);
7647
 
                s->condjmp = 1;
7648
 
 
7649
 
                /* offset[11:1] = insn[10:0] */
7650
 
                offset = (insn & 0x7ff) << 1;
7651
 
                /* offset[17:12] = insn[21:16].  */
7652
 
                offset |= (insn & 0x003f0000) >> 4;
7653
 
                /* offset[31:20] = insn[26].  */
7654
 
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7655
 
                /* offset[18] = insn[13].  */
7656
 
                offset |= (insn & (1 << 13)) << 5;
7657
 
                /* offset[19] = insn[11].  */
7658
 
                offset |= (insn & (1 << 11)) << 8;
7659
 
 
7660
 
                /* jump to the offset */
7661
 
                gen_jmp(s, s->pc + offset);
7662
 
            }
7663
 
        } else {
7664
 
            /* Data processing immediate.  */
7665
 
            if (insn & (1 << 25)) {
7666
 
                if (insn & (1 << 24)) {
7667
 
                    if (insn & (1 << 20))
7668
 
                        goto illegal_op;
7669
 
                    /* Bitfield/Saturate.  */
7670
 
                    op = (insn >> 21) & 7;
7671
 
                    imm = insn & 0x1f;
7672
 
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7673
 
                    if (rn == 15) {
7674
 
                        tmp = new_tmp();
7675
 
                        tcg_gen_movi_i32(tmp, 0);
7676
 
                    } else {
7677
 
                        tmp = load_reg(s, rn);
7678
 
                    }
7679
 
                    switch (op) {
7680
 
                    case 2: /* Signed bitfield extract.  */
7681
 
                        imm++;
7682
 
                        if (shift + imm > 32)
7683
 
                            goto illegal_op;
7684
 
                        if (imm < 32)
7685
 
                            gen_sbfx(tmp, shift, imm);
7686
 
                        break;
7687
 
                    case 6: /* Unsigned bitfield extract.  */
7688
 
                        imm++;
7689
 
                        if (shift + imm > 32)
7690
 
                            goto illegal_op;
7691
 
                        if (imm < 32)
7692
 
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7693
 
                        break;
7694
 
                    case 3: /* Bitfield insert/clear.  */
7695
 
                        if (imm < shift)
7696
 
                            goto illegal_op;
7697
 
                        imm = imm + 1 - shift;
7698
 
                        if (imm != 32) {
7699
 
                            tmp2 = load_reg(s, rd);
7700
 
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7701
 
                            dead_tmp(tmp2);
7702
 
                        }
7703
 
                        break;
7704
 
                    case 7:
7705
 
                        goto illegal_op;
7706
 
                    default: /* Saturate.  */
7707
 
                        if (shift) {
7708
 
                            if (op & 1)
7709
 
                                tcg_gen_sari_i32(tmp, tmp, shift);
7710
 
                            else
7711
 
                                tcg_gen_shli_i32(tmp, tmp, shift);
7712
 
                        }
7713
 
                        tmp2 = tcg_const_i32(imm);
7714
 
                        if (op & 4) {
7715
 
                            /* Unsigned.  */
7716
 
                            if ((op & 1) && shift == 0)
7717
 
                                gen_helper_usat16(tmp, tmp, tmp2);
7718
 
                            else
7719
 
                                gen_helper_usat(tmp, tmp, tmp2);
7720
 
                        } else {
7721
 
                            /* Signed.  */
7722
 
                            if ((op & 1) && shift == 0)
7723
 
                                gen_helper_ssat16(tmp, tmp, tmp2);
7724
 
                            else
7725
 
                                gen_helper_ssat(tmp, tmp, tmp2);
7726
 
                        }
7727
 
                        break;
7728
 
                    }
7729
 
                    store_reg(s, rd, tmp);
7730
 
                } else {
7731
 
                    imm = ((insn & 0x04000000) >> 15)
7732
 
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7733
 
                    if (insn & (1 << 22)) {
7734
 
                        /* 16-bit immediate.  */
7735
 
                        imm |= (insn >> 4) & 0xf000;
7736
 
                        if (insn & (1 << 23)) {
7737
 
                            /* movt */
7738
 
                            tmp = load_reg(s, rd);
7739
 
                            tcg_gen_ext16u_i32(tmp, tmp);
7740
 
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7741
 
                        } else {
7742
 
                            /* movw */
7743
 
                            tmp = new_tmp();
7744
 
                            tcg_gen_movi_i32(tmp, imm);
7745
 
                        }
7746
 
                    } else {
7747
 
                        /* Add/sub 12-bit immediate.  */
7748
 
                        if (rn == 15) {
7749
 
                            offset = s->pc & ~(uint32_t)3;
7750
 
                            if (insn & (1 << 23))
7751
 
                                offset -= imm;
7752
 
                            else
7753
 
                                offset += imm;
7754
 
                            tmp = new_tmp();
7755
 
                            tcg_gen_movi_i32(tmp, offset);
7756
 
                        } else {
7757
 
                            tmp = load_reg(s, rn);
7758
 
                            if (insn & (1 << 23))
7759
 
                                tcg_gen_subi_i32(tmp, tmp, imm);
7760
 
                            else
7761
 
                                tcg_gen_addi_i32(tmp, tmp, imm);
7762
 
                        }
7763
 
                    }
7764
 
                    store_reg(s, rd, tmp);
7765
 
                }
7766
 
            } else {
7767
 
                int shifter_out = 0;
7768
 
                /* modified 12-bit immediate.  */
7769
 
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7770
 
                imm = (insn & 0xff);
7771
 
                switch (shift) {
7772
 
                case 0: /* XY */
7773
 
                    /* Nothing to do.  */
7774
 
                    break;
7775
 
                case 1: /* 00XY00XY */
7776
 
                    imm |= imm << 16;
7777
 
                    break;
7778
 
                case 2: /* XY00XY00 */
7779
 
                    imm |= imm << 16;
7780
 
                    imm <<= 8;
7781
 
                    break;
7782
 
                case 3: /* XYXYXYXY */
7783
 
                    imm |= imm << 16;
7784
 
                    imm |= imm << 8;
7785
 
                    break;
7786
 
                default: /* Rotated constant.  */
7787
 
                    shift = (shift << 1) | (imm >> 7);
7788
 
                    imm |= 0x80;
7789
 
                    imm = imm << (32 - shift);
7790
 
                    shifter_out = 1;
7791
 
                    break;
7792
 
                }
7793
 
                gen_op_movl_T1_im(imm);
7794
 
                rn = (insn >> 16) & 0xf;
7795
 
                if (rn == 15)
7796
 
                    gen_op_movl_T0_im(0);
7797
 
                else
7798
 
                    gen_movl_T0_reg(s, rn);
7799
 
                op = (insn >> 21) & 0xf;
7800
 
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7801
 
                                       shifter_out))
7802
 
                    goto illegal_op;
7803
 
                rd = (insn >> 8) & 0xf;
7804
 
                if (rd != 15) {
7805
 
                    gen_movl_reg_T0(s, rd);
7806
 
                }
7807
 
            }
7808
 
        }
7809
 
        break;
7810
 
    case 12: /* Load/store single data item.  */
7811
 
        {
7812
 
        int postinc = 0;
7813
 
        int writeback = 0;
7814
 
        int user;
7815
 
        if ((insn & 0x01100000) == 0x01000000) {
7816
 
            if (disas_neon_ls_insn(env, s, insn))
7817
 
                goto illegal_op;
7818
 
            break;
7819
 
        }
7820
 
        user = IS_USER(s);
7821
 
        if (rn == 15) {
7822
 
            addr = new_tmp();
7823
 
            /* PC relative.  */
7824
 
            /* s->pc has already been incremented by 4.  */
7825
 
            imm = s->pc & 0xfffffffc;
7826
 
            if (insn & (1 << 23))
7827
 
                imm += insn & 0xfff;
7828
 
            else
7829
 
                imm -= insn & 0xfff;
7830
 
            tcg_gen_movi_i32(addr, imm);
7831
 
        } else {
7832
 
            addr = load_reg(s, rn);
7833
 
            if (insn & (1 << 23)) {
7834
 
                /* Positive offset.  */
7835
 
                imm = insn & 0xfff;
7836
 
                tcg_gen_addi_i32(addr, addr, imm);
7837
 
            } else {
7838
 
                op = (insn >> 8) & 7;
7839
 
                imm = insn & 0xff;
7840
 
                switch (op) {
7841
 
                case 0: case 8: /* Shifted Register.  */
7842
 
                    shift = (insn >> 4) & 0xf;
7843
 
                    if (shift > 3)
7844
 
                        goto illegal_op;
7845
 
                    tmp = load_reg(s, rm);
7846
 
                    if (shift)
7847
 
                        tcg_gen_shli_i32(tmp, tmp, shift);
7848
 
                    tcg_gen_add_i32(addr, addr, tmp);
7849
 
                    dead_tmp(tmp);
7850
 
                    break;
7851
 
                case 4: /* Negative offset.  */
7852
 
                    tcg_gen_addi_i32(addr, addr, -imm);
7853
 
                    break;
7854
 
                case 6: /* User privilege.  */
7855
 
                    tcg_gen_addi_i32(addr, addr, imm);
7856
 
                    user = 1;
7857
 
                    break;
7858
 
                case 1: /* Post-decrement.  */
7859
 
                    imm = -imm;
7860
 
                    /* Fall through.  */
7861
 
                case 3: /* Post-increment.  */
7862
 
                    postinc = 1;
7863
 
                    writeback = 1;
7864
 
                    break;
7865
 
                case 5: /* Pre-decrement.  */
7866
 
                    imm = -imm;
7867
 
                    /* Fall through.  */
7868
 
                case 7: /* Pre-increment.  */
7869
 
                    tcg_gen_addi_i32(addr, addr, imm);
7870
 
                    writeback = 1;
7871
 
                    break;
7872
 
                default:
7873
 
                    goto illegal_op;
7874
 
                }
7875
 
            }
7876
 
        }
7877
 
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7878
 
        if (insn & (1 << 20)) {
7879
 
            /* Load.  */
7880
 
            if (rs == 15 && op != 2) {
7881
 
                if (op & 2)
7882
 
                    goto illegal_op;
7883
 
                /* Memory hint.  Implemented as NOP.  */
7884
 
            } else {
7885
 
                switch (op) {
7886
 
                case 0: tmp = gen_ld8u(addr, user); break;
7887
 
                case 4: tmp = gen_ld8s(addr, user); break;
7888
 
                case 1: tmp = gen_ld16u(addr, user); break;
7889
 
                case 5: tmp = gen_ld16s(addr, user); break;
7890
 
                case 2: tmp = gen_ld32(addr, user); break;
7891
 
                default: goto illegal_op;
7892
 
                }
7893
 
                if (rs == 15) {
7894
 
                    gen_bx(s, tmp);
7895
 
                } else {
7896
 
                    store_reg(s, rs, tmp);
7897
 
                }
7898
 
            }
7899
 
        } else {
7900
 
            /* Store.  */
7901
 
            if (rs == 15)
7902
 
                goto illegal_op;
7903
 
            tmp = load_reg(s, rs);
7904
 
            switch (op) {
7905
 
            case 0: gen_st8(tmp, addr, user); break;
7906
 
            case 1: gen_st16(tmp, addr, user); break;
7907
 
            case 2: gen_st32(tmp, addr, user); break;
7908
 
            default: goto illegal_op;
7909
 
            }
7910
 
        }
7911
 
        if (postinc)
7912
 
            tcg_gen_addi_i32(addr, addr, imm);
7913
 
        if (writeback) {
7914
 
            store_reg(s, rn, addr);
7915
 
        } else {
7916
 
            dead_tmp(addr);
7917
 
        }
7918
 
        }
7919
 
        break;
7920
 
    default:
7921
 
        goto illegal_op;
7922
 
    }
7923
 
    return 0;
7924
 
illegal_op:
7925
 
    return 1;
7926
 
}
7927
 
 
7928
 
static void disas_thumb_insn(CPUState *env, DisasContext *s)
 
2961
static void disas_thumb_insn(DisasContext *s)
7929
2962
{
7930
2963
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7931
2964
    int32_t offset;
7932
2965
    int i;
7933
 
    TCGv tmp;
7934
 
    TCGv tmp2;
7935
 
    TCGv addr;
7936
 
 
7937
 
    if (s->condexec_mask) {
7938
 
        cond = s->condexec_cond;
7939
 
        s->condlabel = gen_new_label();
7940
 
        gen_test_cc(cond ^ 1, s->condlabel);
7941
 
        s->condjmp = 1;
7942
 
    }
7943
2966
 
7944
2967
    insn = lduw_code(s->pc);
7945
2968
    s->pc += 2;
7960
2983
                rm = (insn >> 6) & 7;
7961
2984
                gen_movl_T1_reg(s, rm);
7962
2985
            }
7963
 
            if (insn & (1 << 9)) {
7964
 
                if (s->condexec_mask)
7965
 
                    gen_op_subl_T0_T1();
7966
 
                else
7967
 
                    gen_op_subl_T0_T1_cc();
7968
 
            } else {
7969
 
                if (s->condexec_mask)
7970
 
                    gen_op_addl_T0_T1();
7971
 
                else
7972
 
                    gen_op_addl_T0_T1_cc();
7973
 
            }
 
2986
            if (insn & (1 << 9))
 
2987
                gen_op_subl_T0_T1_cc();
 
2988
            else
 
2989
                gen_op_addl_T0_T1_cc();
7974
2990
            gen_movl_reg_T0(s, rd);
7975
2991
        } else {
7976
2992
            /* shift immediate */
7977
2993
            rm = (insn >> 3) & 7;
7978
2994
            shift = (insn >> 6) & 0x1f;
7979
 
            tmp = load_reg(s, rm);
7980
 
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7981
 
            if (!s->condexec_mask)
7982
 
                gen_logic_CC(tmp);
7983
 
            store_reg(s, rd, tmp);
 
2995
            gen_movl_T0_reg(s, rm);
 
2996
            gen_shift_T0_im_thumb[op](shift);
 
2997
            gen_movl_reg_T0(s, rd);
7984
2998
        }
7985
2999
        break;
7986
3000
    case 2: case 3:
7995
3009
        }
7996
3010
        switch (op) {
7997
3011
        case 0: /* mov */
7998
 
            if (!s->condexec_mask)
7999
 
                gen_op_logic_T0_cc();
 
3012
            gen_op_logic_T0_cc();
8000
3013
            break;
8001
3014
        case 1: /* cmp */
8002
3015
            gen_op_subl_T0_T1_cc();
8003
3016
            break;
8004
3017
        case 2: /* add */
8005
 
            if (s->condexec_mask)
8006
 
                gen_op_addl_T0_T1();
8007
 
            else
8008
 
                gen_op_addl_T0_T1_cc();
 
3018
            gen_op_addl_T0_T1_cc();
8009
3019
            break;
8010
3020
        case 3: /* sub */
8011
 
            if (s->condexec_mask)
8012
 
                gen_op_subl_T0_T1();
8013
 
            else
8014
 
                gen_op_subl_T0_T1_cc();
 
3021
            gen_op_subl_T0_T1_cc();
8015
3022
            break;
8016
3023
        }
8017
3024
        if (op != 1)
8023
3030
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8024
3031
            val = s->pc + 2 + ((insn & 0xff) * 4);
8025
3032
            val &= ~(uint32_t)2;
8026
 
            addr = new_tmp();
8027
 
            tcg_gen_movi_i32(addr, val);
8028
 
            tmp = gen_ld32(addr, IS_USER(s));
8029
 
            dead_tmp(addr);
8030
 
            store_reg(s, rd, tmp);
 
3033
            gen_op_movl_T1_im(val);
 
3034
            gen_ldst(ldl, s);
 
3035
            gen_movl_reg_T0(s, rd);
8031
3036
            break;
8032
3037
        }
8033
3038
        if (insn & (1 << 10)) {
8052
3057
                gen_movl_reg_T0(s, rd);
8053
3058
                break;
8054
3059
            case 3:/* branch [and link] exchange thumb register */
8055
 
                tmp = load_reg(s, rm);
8056
3060
                if (insn & (1 << 7)) {
8057
3061
                    val = (uint32_t)s->pc | 1;
8058
 
                    tmp2 = new_tmp();
8059
 
                    tcg_gen_movi_i32(tmp2, val);
8060
 
                    store_reg(s, 14, tmp2);
 
3062
                    gen_op_movl_T1_im(val);
 
3063
                    gen_movl_reg_T1(s, 14);
8061
3064
                }
8062
 
                gen_bx(s, tmp);
 
3065
                gen_movl_T0_reg(s, rm);
 
3066
                gen_bx(s);
8063
3067
                break;
8064
3068
            }
8065
3069
            break;
8088
3092
        switch (op) {
8089
3093
        case 0x0: /* and */
8090
3094
            gen_op_andl_T0_T1();
8091
 
            if (!s->condexec_mask)
8092
 
                gen_op_logic_T0_cc();
 
3095
            gen_op_logic_T0_cc();
8093
3096
            break;
8094
3097
        case 0x1: /* eor */
8095
3098
            gen_op_xorl_T0_T1();
8096
 
            if (!s->condexec_mask)
8097
 
                gen_op_logic_T0_cc();
 
3099
            gen_op_logic_T0_cc();
8098
3100
            break;
8099
3101
        case 0x2: /* lsl */
8100
 
            if (s->condexec_mask) {
8101
 
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8102
 
            } else {
8103
 
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8104
 
                gen_op_logic_T1_cc();
8105
 
            }
 
3102
            gen_op_shll_T1_T0_cc();
 
3103
            gen_op_logic_T1_cc();
8106
3104
            break;
8107
3105
        case 0x3: /* lsr */
8108
 
            if (s->condexec_mask) {
8109
 
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8110
 
            } else {
8111
 
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8112
 
                gen_op_logic_T1_cc();
8113
 
            }
 
3106
            gen_op_shrl_T1_T0_cc();
 
3107
            gen_op_logic_T1_cc();
8114
3108
            break;
8115
3109
        case 0x4: /* asr */
8116
 
            if (s->condexec_mask) {
8117
 
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8118
 
            } else {
8119
 
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8120
 
                gen_op_logic_T1_cc();
8121
 
            }
 
3110
            gen_op_sarl_T1_T0_cc();
 
3111
            gen_op_logic_T1_cc();
8122
3112
            break;
8123
3113
        case 0x5: /* adc */
8124
 
            if (s->condexec_mask)
8125
 
                gen_adc_T0_T1();
8126
 
            else
8127
 
                gen_op_adcl_T0_T1_cc();
 
3114
            gen_op_adcl_T0_T1_cc();
8128
3115
            break;
8129
3116
        case 0x6: /* sbc */
8130
 
            if (s->condexec_mask)
8131
 
                gen_sbc_T0_T1();
8132
 
            else
8133
 
                gen_op_sbcl_T0_T1_cc();
 
3117
            gen_op_sbcl_T0_T1_cc();
8134
3118
            break;
8135
3119
        case 0x7: /* ror */
8136
 
            if (s->condexec_mask) {
8137
 
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8138
 
            } else {
8139
 
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8140
 
                gen_op_logic_T1_cc();
8141
 
            }
 
3120
            gen_op_rorl_T1_T0_cc();
 
3121
            gen_op_logic_T1_cc();
8142
3122
            break;
8143
3123
        case 0x8: /* tst */
8144
3124
            gen_op_andl_T0_T1();
8146
3126
            rd = 16;
8147
3127
            break;
8148
3128
        case 0x9: /* neg */
8149
 
            if (s->condexec_mask)
8150
 
                tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8151
 
            else
8152
 
                gen_op_subl_T0_T1_cc();
 
3129
            gen_op_subl_T0_T1_cc();
8153
3130
            break;
8154
3131
        case 0xa: /* cmp */
8155
3132
            gen_op_subl_T0_T1_cc();
8161
3138
            break;
8162
3139
        case 0xc: /* orr */
8163
3140
            gen_op_orl_T0_T1();
8164
 
            if (!s->condexec_mask)
8165
 
                gen_op_logic_T0_cc();
 
3141
            gen_op_logic_T0_cc();
8166
3142
            break;
8167
3143
        case 0xd: /* mul */
8168
3144
            gen_op_mull_T0_T1();
8169
 
            if (!s->condexec_mask)
8170
 
                gen_op_logic_T0_cc();
 
3145
            gen_op_logic_T0_cc();
8171
3146
            break;
8172
3147
        case 0xe: /* bic */
8173
3148
            gen_op_bicl_T0_T1();
8174
 
            if (!s->condexec_mask)
8175
 
                gen_op_logic_T0_cc();
 
3149
            gen_op_logic_T0_cc();
8176
3150
            break;
8177
3151
        case 0xf: /* mvn */
8178
3152
            gen_op_notl_T1();
8179
 
            if (!s->condexec_mask)
8180
 
                gen_op_logic_T1_cc();
 
3153
            gen_op_logic_T1_cc();
8181
3154
            val = 1;
8182
3155
            rm = rd;
8183
3156
            break;
8196
3169
        rn = (insn >> 3) & 7;
8197
3170
        rm = (insn >> 6) & 7;
8198
3171
        op = (insn >> 9) & 7;
8199
 
        addr = load_reg(s, rn);
8200
 
        tmp = load_reg(s, rm);
8201
 
        tcg_gen_add_i32(addr, addr, tmp);
8202
 
        dead_tmp(tmp);
 
3172
        gen_movl_T1_reg(s, rn);
 
3173
        gen_movl_T2_reg(s, rm);
 
3174
        gen_op_addl_T1_T2();
8203
3175
 
8204
3176
        if (op < 3) /* store */
8205
 
            tmp = load_reg(s, rd);
 
3177
            gen_movl_T0_reg(s, rd);
8206
3178
 
8207
3179
        switch (op) {
8208
3180
        case 0: /* str */
8209
 
            gen_st32(tmp, addr, IS_USER(s));
 
3181
            gen_ldst(stl, s);
8210
3182
            break;
8211
3183
        case 1: /* strh */
8212
 
            gen_st16(tmp, addr, IS_USER(s));
 
3184
            gen_ldst(stw, s);
8213
3185
            break;
8214
3186
        case 2: /* strb */
8215
 
            gen_st8(tmp, addr, IS_USER(s));
 
3187
            gen_ldst(stb, s);
8216
3188
            break;
8217
3189
        case 3: /* ldrsb */
8218
 
            tmp = gen_ld8s(addr, IS_USER(s));
 
3190
            gen_ldst(ldsb, s);
8219
3191
            break;
8220
3192
        case 4: /* ldr */
8221
 
            tmp = gen_ld32(addr, IS_USER(s));
 
3193
            gen_ldst(ldl, s);
8222
3194
            break;
8223
3195
        case 5: /* ldrh */
8224
 
            tmp = gen_ld16u(addr, IS_USER(s));
 
3196
            gen_ldst(lduw, s);
8225
3197
            break;
8226
3198
        case 6: /* ldrb */
8227
 
            tmp = gen_ld8u(addr, IS_USER(s));
 
3199
            gen_ldst(ldub, s);
8228
3200
            break;
8229
3201
        case 7: /* ldrsh */
8230
 
            tmp = gen_ld16s(addr, IS_USER(s));
 
3202
            gen_ldst(ldsw, s);
8231
3203
            break;
8232
3204
        }
8233
3205
        if (op >= 3) /* load */
8234
 
            store_reg(s, rd, tmp);
8235
 
        dead_tmp(addr);
 
3206
            gen_movl_reg_T0(s, rd);
8236
3207
        break;
8237
3208
 
8238
3209
    case 6:
8239
3210
        /* load/store word immediate offset */
8240
3211
        rd = insn & 7;
8241
3212
        rn = (insn >> 3) & 7;
8242
 
        addr = load_reg(s, rn);
 
3213
        gen_movl_T1_reg(s, rn);
8243
3214
        val = (insn >> 4) & 0x7c;
8244
 
        tcg_gen_addi_i32(addr, addr, val);
 
3215
        gen_op_movl_T2_im(val);
 
3216
        gen_op_addl_T1_T2();
8245
3217
 
8246
3218
        if (insn & (1 << 11)) {
8247
3219
            /* load */
8248
 
            tmp = gen_ld32(addr, IS_USER(s));
8249
 
            store_reg(s, rd, tmp);
 
3220
            gen_ldst(ldl, s);
 
3221
            gen_movl_reg_T0(s, rd);
8250
3222
        } else {
8251
3223
            /* store */
8252
 
            tmp = load_reg(s, rd);
8253
 
            gen_st32(tmp, addr, IS_USER(s));
 
3224
            gen_movl_T0_reg(s, rd);
 
3225
            gen_ldst(stl, s);
8254
3226
        }
8255
 
        dead_tmp(addr);
8256
3227
        break;
8257
3228
 
8258
3229
    case 7:
8259
3230
        /* load/store byte immediate offset */
8260
3231
        rd = insn & 7;
8261
3232
        rn = (insn >> 3) & 7;
8262
 
        addr = load_reg(s, rn);
 
3233
        gen_movl_T1_reg(s, rn);
8263
3234
        val = (insn >> 6) & 0x1f;
8264
 
        tcg_gen_addi_i32(addr, addr, val);
 
3235
        gen_op_movl_T2_im(val);
 
3236
        gen_op_addl_T1_T2();
8265
3237
 
8266
3238
        if (insn & (1 << 11)) {
8267
3239
            /* load */
8268
 
            tmp = gen_ld8u(addr, IS_USER(s));
8269
 
            store_reg(s, rd, tmp);
 
3240
            gen_ldst(ldub, s);
 
3241
            gen_movl_reg_T0(s, rd);
8270
3242
        } else {
8271
3243
            /* store */
8272
 
            tmp = load_reg(s, rd);
8273
 
            gen_st8(tmp, addr, IS_USER(s));
 
3244
            gen_movl_T0_reg(s, rd);
 
3245
            gen_ldst(stb, s);
8274
3246
        }
8275
 
        dead_tmp(addr);
8276
3247
        break;
8277
3248
 
8278
3249
    case 8:
8279
3250
        /* load/store halfword immediate offset */
8280
3251
        rd = insn & 7;
8281
3252
        rn = (insn >> 3) & 7;
8282
 
        addr = load_reg(s, rn);
 
3253
        gen_movl_T1_reg(s, rn);
8283
3254
        val = (insn >> 5) & 0x3e;
8284
 
        tcg_gen_addi_i32(addr, addr, val);
 
3255
        gen_op_movl_T2_im(val);
 
3256
        gen_op_addl_T1_T2();
8285
3257
 
8286
3258
        if (insn & (1 << 11)) {
8287
3259
            /* load */
8288
 
            tmp = gen_ld16u(addr, IS_USER(s));
8289
 
            store_reg(s, rd, tmp);
 
3260
            gen_ldst(lduw, s);
 
3261
            gen_movl_reg_T0(s, rd);
8290
3262
        } else {
8291
3263
            /* store */
8292
 
            tmp = load_reg(s, rd);
8293
 
            gen_st16(tmp, addr, IS_USER(s));
 
3264
            gen_movl_T0_reg(s, rd);
 
3265
            gen_ldst(stw, s);
8294
3266
        }
8295
 
        dead_tmp(addr);
8296
3267
        break;
8297
3268
 
8298
3269
    case 9:
8299
3270
        /* load/store from stack */
8300
3271
        rd = (insn >> 8) & 7;
8301
 
        addr = load_reg(s, 13);
 
3272
        gen_movl_T1_reg(s, 13);
8302
3273
        val = (insn & 0xff) * 4;
8303
 
        tcg_gen_addi_i32(addr, addr, val);
 
3274
        gen_op_movl_T2_im(val);
 
3275
        gen_op_addl_T1_T2();
8304
3276
 
8305
3277
        if (insn & (1 << 11)) {
8306
3278
            /* load */
8307
 
            tmp = gen_ld32(addr, IS_USER(s));
8308
 
            store_reg(s, rd, tmp);
 
3279
            gen_ldst(ldl, s);
 
3280
            gen_movl_reg_T0(s, rd);
8309
3281
        } else {
8310
3282
            /* store */
8311
 
            tmp = load_reg(s, rd);
8312
 
            gen_st32(tmp, addr, IS_USER(s));
 
3283
            gen_movl_T0_reg(s, rd);
 
3284
            gen_ldst(stl, s);
8313
3285
        }
8314
 
        dead_tmp(addr);
8315
3286
        break;
8316
3287
 
8317
3288
    case 10:
8319
3290
        rd = (insn >> 8) & 7;
8320
3291
        if (insn & (1 << 11)) {
8321
3292
            /* SP */
8322
 
            tmp = load_reg(s, 13);
 
3293
            gen_movl_T0_reg(s, 13);
8323
3294
        } else {
8324
3295
            /* PC. bit 1 is ignored.  */
8325
 
            tmp = new_tmp();
8326
 
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
 
3296
            gen_op_movl_T0_im((s->pc + 2) & ~(uint32_t)2);
8327
3297
        }
8328
3298
        val = (insn & 0xff) * 4;
8329
 
        tcg_gen_addi_i32(tmp, tmp, val);
8330
 
        store_reg(s, rd, tmp);
 
3299
        gen_op_movl_T1_im(val);
 
3300
        gen_op_addl_T0_T1();
 
3301
        gen_movl_reg_T0(s, rd);
8331
3302
        break;
8332
3303
 
8333
3304
    case 11:
8336
3307
        switch (op) {
8337
3308
        case 0:
8338
3309
            /* adjust stack pointer */
8339
 
            tmp = load_reg(s, 13);
 
3310
            gen_movl_T1_reg(s, 13);
8340
3311
            val = (insn & 0x7f) * 4;
8341
3312
            if (insn & (1 << 7))
8342
 
                val = -(int32_t)val;
8343
 
            tcg_gen_addi_i32(tmp, tmp, val);
8344
 
            store_reg(s, 13, tmp);
 
3313
              val = -(int32_t)val;
 
3314
            gen_op_movl_T2_im(val);
 
3315
            gen_op_addl_T1_T2();
 
3316
            gen_movl_reg_T1(s, 13);
8345
3317
            break;
8346
3318
 
8347
 
        case 2: /* sign/zero extend.  */
8348
 
            ARCH(6);
8349
 
            rd = insn & 7;
8350
 
            rm = (insn >> 3) & 7;
8351
 
            tmp = load_reg(s, rm);
8352
 
            switch ((insn >> 6) & 3) {
8353
 
            case 0: gen_sxth(tmp); break;
8354
 
            case 1: gen_sxtb(tmp); break;
8355
 
            case 2: gen_uxth(tmp); break;
8356
 
            case 3: gen_uxtb(tmp); break;
8357
 
            }
8358
 
            store_reg(s, rd, tmp);
8359
 
            break;
8360
3319
        case 4: case 5: case 0xc: case 0xd:
8361
3320
            /* push/pop */
8362
 
            addr = load_reg(s, 13);
 
3321
            gen_movl_T1_reg(s, 13);
8363
3322
            if (insn & (1 << 8))
8364
3323
                offset = 4;
8365
3324
            else
8369
3328
                    offset += 4;
8370
3329
            }
8371
3330
            if ((insn & (1 << 11)) == 0) {
8372
 
                tcg_gen_addi_i32(addr, addr, -offset);
 
3331
                gen_op_movl_T2_im(-offset);
 
3332
                gen_op_addl_T1_T2();
8373
3333
            }
 
3334
            gen_op_movl_T2_im(4);
8374
3335
            for (i = 0; i < 8; i++) {
8375
3336
                if (insn & (1 << i)) {
8376
3337
                    if (insn & (1 << 11)) {
8377
3338
                        /* pop */
8378
 
                        tmp = gen_ld32(addr, IS_USER(s));
8379
 
                        store_reg(s, i, tmp);
 
3339
                        gen_ldst(ldl, s);
 
3340
                        gen_movl_reg_T0(s, i);
8380
3341
                    } else {
8381
3342
                        /* push */
8382
 
                        tmp = load_reg(s, i);
8383
 
                        gen_st32(tmp, addr, IS_USER(s));
 
3343
                        gen_movl_T0_reg(s, i);
 
3344
                        gen_ldst(stl, s);
8384
3345
                    }
8385
3346
                    /* advance to the next address.  */
8386
 
                    tcg_gen_addi_i32(addr, addr, 4);
 
3347
                    gen_op_addl_T1_T2();
8387
3348
                }
8388
3349
            }
8389
 
            TCGV_UNUSED(tmp);
8390
3350
            if (insn & (1 << 8)) {
8391
3351
                if (insn & (1 << 11)) {
8392
3352
                    /* pop pc */
8393
 
                    tmp = gen_ld32(addr, IS_USER(s));
 
3353
                    gen_ldst(ldl, s);
8394
3354
                    /* don't set the pc until the rest of the instruction
8395
3355
                       has completed */
8396
3356
                } else {
8397
3357
                    /* push lr */
8398
 
                    tmp = load_reg(s, 14);
8399
 
                    gen_st32(tmp, addr, IS_USER(s));
 
3358
                    gen_movl_T0_reg(s, 14);
 
3359
                    gen_ldst(stl, s);
8400
3360
                }
8401
 
                tcg_gen_addi_i32(addr, addr, 4);
 
3361
                gen_op_addl_T1_T2();
8402
3362
            }
8403
3363
            if ((insn & (1 << 11)) == 0) {
8404
 
                tcg_gen_addi_i32(addr, addr, -offset);
 
3364
                gen_op_movl_T2_im(-offset);
 
3365
                gen_op_addl_T1_T2();
8405
3366
            }
8406
3367
            /* write back the new stack pointer */
8407
 
            store_reg(s, 13, addr);
 
3368
            gen_movl_reg_T1(s, 13);
8408
3369
            /* set the new PC value */
8409
3370
            if ((insn & 0x0900) == 0x0900)
8410
 
                gen_bx(s, tmp);
8411
 
            break;
8412
 
 
8413
 
        case 1: case 3: case 9: case 11: /* czb */
8414
 
            rm = insn & 7;
8415
 
            tmp = load_reg(s, rm);
8416
 
            s->condlabel = gen_new_label();
8417
 
            s->condjmp = 1;
8418
 
            if (insn & (1 << 11))
8419
 
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8420
 
            else
8421
 
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8422
 
            dead_tmp(tmp);
8423
 
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8424
 
            val = (uint32_t)s->pc + 2;
8425
 
            val += offset;
8426
 
            gen_jmp(s, val);
8427
 
            break;
8428
 
 
8429
 
        case 15: /* IT, nop-hint.  */
8430
 
            if ((insn & 0xf) == 0) {
8431
 
                gen_nop_hint(s, (insn >> 4) & 0xf);
8432
 
                break;
8433
 
            }
8434
 
            /* If Then.  */
8435
 
            s->condexec_cond = (insn >> 4) & 0xe;
8436
 
            s->condexec_mask = insn & 0x1f;
8437
 
            /* No actual code generated for this insn, just setup state.  */
 
3371
                gen_bx(s);
8438
3372
            break;
8439
3373
 
8440
3374
        case 0xe: /* bkpt */
8441
 
            gen_set_condexec(s);
8442
 
            gen_set_pc_im(s->pc - 2);
8443
 
            gen_exception(EXCP_BKPT);
 
3375
            gen_op_movl_T0_im((long)s->pc - 2);
 
3376
            gen_op_movl_reg_TN[0][15]();
 
3377
            gen_op_bkpt();
8444
3378
            s->is_jmp = DISAS_JUMP;
8445
3379
            break;
8446
3380
 
8447
 
        case 0xa: /* rev */
8448
 
            ARCH(6);
8449
 
            rn = (insn >> 3) & 0x7;
8450
 
            rd = insn & 0x7;
8451
 
            tmp = load_reg(s, rn);
8452
 
            switch ((insn >> 6) & 3) {
8453
 
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8454
 
            case 1: gen_rev16(tmp); break;
8455
 
            case 3: gen_revsh(tmp); break;
8456
 
            default: goto illegal_op;
8457
 
            }
8458
 
            store_reg(s, rd, tmp);
8459
 
            break;
8460
 
 
8461
 
        case 6: /* cps */
8462
 
            ARCH(6);
8463
 
            if (IS_USER(s))
8464
 
                break;
8465
 
            if (IS_M(env)) {
8466
 
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8467
 
                /* PRIMASK */
8468
 
                if (insn & 1) {
8469
 
                    addr = tcg_const_i32(16);
8470
 
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8471
 
                }
8472
 
                /* FAULTMASK */
8473
 
                if (insn & 2) {
8474
 
                    addr = tcg_const_i32(17);
8475
 
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8476
 
                }
8477
 
                gen_lookup_tb(s);
8478
 
            } else {
8479
 
                if (insn & (1 << 4))
8480
 
                    shift = CPSR_A | CPSR_I | CPSR_F;
8481
 
                else
8482
 
                    shift = 0;
8483
 
 
8484
 
                val = ((insn & 7) << 6) & shift;
8485
 
                gen_op_movl_T0_im(val);
8486
 
                gen_set_psr_T0(s, shift, 0);
8487
 
            }
8488
 
            break;
8489
 
 
8490
3381
        default:
8491
3382
            goto undef;
8492
3383
        }
8495
3386
    case 12:
8496
3387
        /* load/store multiple */
8497
3388
        rn = (insn >> 8) & 0x7;
8498
 
        addr = load_reg(s, rn);
 
3389
        gen_movl_T1_reg(s, rn);
 
3390
        gen_op_movl_T2_im(4);
8499
3391
        for (i = 0; i < 8; i++) {
8500
3392
            if (insn & (1 << i)) {
8501
3393
                if (insn & (1 << 11)) {
8502
3394
                    /* load */
8503
 
                    tmp = gen_ld32(addr, IS_USER(s));
8504
 
                    store_reg(s, i, tmp);
 
3395
                    gen_ldst(ldl, s);
 
3396
                    gen_movl_reg_T0(s, i);
8505
3397
                } else {
8506
3398
                    /* store */
8507
 
                    tmp = load_reg(s, i);
8508
 
                    gen_st32(tmp, addr, IS_USER(s));
 
3399
                    gen_movl_T0_reg(s, i);
 
3400
                    gen_ldst(stl, s);
8509
3401
                }
8510
3402
                /* advance to the next address */
8511
 
                tcg_gen_addi_i32(addr, addr, 4);
 
3403
                gen_op_addl_T1_T2();
8512
3404
            }
8513
3405
        }
8514
3406
        /* Base register writeback.  */
8515
 
        if ((insn & (1 << rn)) == 0) {
8516
 
            store_reg(s, rn, addr);
8517
 
        } else {
8518
 
            dead_tmp(addr);
8519
 
        }
 
3407
        if ((insn & (1 << rn)) == 0)
 
3408
            gen_movl_reg_T1(s, rn);
8520
3409
        break;
8521
3410
 
8522
3411
    case 13:
8527
3416
 
8528
3417
        if (cond == 0xf) {
8529
3418
            /* swi */
8530
 
            gen_set_condexec(s);
8531
 
            gen_set_pc_im(s->pc);
8532
 
            s->is_jmp = DISAS_SWI;
 
3419
            gen_op_movl_T0_im((long)s->pc | 1);
 
3420
            /* Don't set r15.  */
 
3421
            gen_op_movl_reg_TN[0][15]();
 
3422
            gen_op_swi();
 
3423
            s->is_jmp = DISAS_JUMP;
8533
3424
            break;
8534
3425
        }
8535
3426
        /* generate a conditional jump to next instruction */
8536
3427
        s->condlabel = gen_new_label();
8537
 
        gen_test_cc(cond ^ 1, s->condlabel);
 
3428
        gen_test_cc[cond ^ 1](s->condlabel);
8538
3429
        s->condjmp = 1;
 
3430
        //gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
 
3431
        //s->is_jmp = DISAS_JUMP_NEXT;
8539
3432
        gen_movl_T1_reg(s, 15);
8540
3433
 
8541
3434
        /* jump to the offset */
8546
3439
        break;
8547
3440
 
8548
3441
    case 14:
8549
 
        if (insn & (1 << 11)) {
8550
 
            if (disas_thumb2_insn(env, s, insn))
8551
 
              goto undef32;
8552
 
            break;
8553
 
        }
8554
3442
        /* unconditional branch */
 
3443
        if (insn & (1 << 11)) {
 
3444
            /* Second half of blx.  */
 
3445
            offset = ((insn & 0x7ff) << 1);
 
3446
            gen_movl_T0_reg(s, 14);
 
3447
            gen_op_movl_T1_im(offset);
 
3448
            gen_op_addl_T0_T1();
 
3449
            gen_op_movl_T1_im(0xfffffffc);
 
3450
            gen_op_andl_T0_T1();
 
3451
 
 
3452
            val = (uint32_t)s->pc;
 
3453
            gen_op_movl_T1_im(val | 1);
 
3454
            gen_movl_reg_T1(s, 14);
 
3455
            gen_bx(s);
 
3456
            break;
 
3457
        }
8555
3458
        val = (uint32_t)s->pc;
8556
3459
        offset = ((int32_t)insn << 21) >> 21;
8557
3460
        val += (offset << 1) + 2;
8559
3462
        break;
8560
3463
 
8561
3464
    case 15:
8562
 
        if (disas_thumb2_insn(env, s, insn))
8563
 
            goto undef32;
8564
 
        break;
 
3465
        /* branch and link [and switch to arm] */
 
3466
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
 
3467
            /* Instruction spans a page boundary.  Implement it as two
 
3468
               16-bit instructions in case the second half causes an
 
3469
               prefetch abort.  */
 
3470
            offset = ((int32_t)insn << 21) >> 9;
 
3471
            val = s->pc + 2 + offset;
 
3472
            gen_op_movl_T0_im(val);
 
3473
            gen_movl_reg_T0(s, 14);
 
3474
            break;
 
3475
        }
 
3476
        if (insn & (1 << 11)) {
 
3477
            /* Second half of bl.  */
 
3478
            offset = ((insn & 0x7ff) << 1) | 1;
 
3479
            gen_movl_T0_reg(s, 14);
 
3480
            gen_op_movl_T1_im(offset);
 
3481
            gen_op_addl_T0_T1();
 
3482
 
 
3483
            val = (uint32_t)s->pc;
 
3484
            gen_op_movl_T1_im(val | 1);
 
3485
            gen_movl_reg_T1(s, 14);
 
3486
            gen_bx(s);
 
3487
            break;
 
3488
        }
 
3489
        offset = ((int32_t)insn << 21) >> 10;
 
3490
        insn = lduw_code(s->pc);
 
3491
        offset |= insn & 0x7ff;
 
3492
 
 
3493
        val = (uint32_t)s->pc + 2;
 
3494
        gen_op_movl_T1_im(val | 1);
 
3495
        gen_movl_reg_T1(s, 14);
 
3496
        
 
3497
        val += offset << 1;
 
3498
        if (insn & (1 << 12)) {
 
3499
            /* bl */
 
3500
            gen_jmp(s, val);
 
3501
        } else {
 
3502
            /* blx */
 
3503
            val &= ~(uint32_t)2;
 
3504
            gen_op_movl_T0_im(val);
 
3505
            gen_bx(s);
 
3506
        }
8565
3507
    }
8566
3508
    return;
8567
 
undef32:
8568
 
    gen_set_condexec(s);
8569
 
    gen_set_pc_im(s->pc - 4);
8570
 
    gen_exception(EXCP_UDEF);
8571
 
    s->is_jmp = DISAS_JUMP;
8572
 
    return;
8573
 
illegal_op:
8574
3509
undef:
8575
 
    gen_set_condexec(s);
8576
 
    gen_set_pc_im(s->pc - 2);
8577
 
    gen_exception(EXCP_UDEF);
 
3510
    gen_op_movl_T0_im((long)s->pc - 2);
 
3511
    gen_op_movl_reg_TN[0][15]();
 
3512
    gen_op_undef_insn();
8578
3513
    s->is_jmp = DISAS_JUMP;
8579
3514
}
8580
3515
 
8581
3516
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8582
3517
   basic block 'tb'. If search_pc is TRUE, also generate PC
8583
3518
   information for each intermediate instruction. */
8584
 
static inline void gen_intermediate_code_internal(CPUState *env,
8585
 
                                                  TranslationBlock *tb,
8586
 
                                                  int search_pc)
 
3519
static inline int gen_intermediate_code_internal(CPUState *env, 
 
3520
                                                 TranslationBlock *tb, 
 
3521
                                                 int search_pc)
8587
3522
{
8588
3523
    DisasContext dc1, *dc = &dc1;
8589
3524
    uint16_t *gen_opc_end;
8590
3525
    int j, lj;
8591
3526
    target_ulong pc_start;
8592
3527
    uint32_t next_page_start;
8593
 
    int num_insns;
8594
 
    int max_insns;
8595
 
 
 
3528
    
8596
3529
    /* generate intermediate code */
8597
 
    num_temps = 0;
8598
 
    memset(temps, 0, sizeof(temps));
8599
 
 
8600
3530
    pc_start = tb->pc;
8601
 
 
 
3531
       
8602
3532
    dc->tb = tb;
8603
3533
 
 
3534
    gen_opc_ptr = gen_opc_buf;
8604
3535
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
 
3536
    gen_opparam_ptr = gen_opparam_buf;
8605
3537
 
8606
3538
    dc->is_jmp = DISAS_NEXT;
8607
3539
    dc->pc = pc_start;
8608
3540
    dc->singlestep_enabled = env->singlestep_enabled;
8609
3541
    dc->condjmp = 0;
8610
3542
    dc->thumb = env->thumb;
8611
 
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8612
 
    dc->condexec_cond = env->condexec_bits >> 4;
8613
3543
    dc->is_mem = 0;
8614
3544
#if !defined(CONFIG_USER_ONLY)
8615
 
    if (IS_M(env)) {
8616
 
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8617
 
    } else {
8618
 
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8619
 
    }
 
3545
    dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8620
3546
#endif
8621
 
    cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8622
 
    cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8623
 
    cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8624
 
    cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8625
 
    cpu_V0 = cpu_F0d;
8626
 
    cpu_V1 = cpu_F1d;
8627
 
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8628
 
    cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8629
3547
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 
3548
    nb_gen_labels = 0;
8630
3549
    lj = -1;
8631
 
    num_insns = 0;
8632
 
    max_insns = tb->cflags & CF_COUNT_MASK;
8633
 
    if (max_insns == 0)
8634
 
        max_insns = CF_COUNT_MASK;
8635
 
 
8636
 
    gen_icount_start();
8637
 
    /* Reset the conditional execution bits immediately. This avoids
8638
 
       complications trying to do it at the end of the block.  */
8639
 
    if (env->condexec_bits)
8640
 
      {
8641
 
        TCGv tmp = new_tmp();
8642
 
        tcg_gen_movi_i32(tmp, 0);
8643
 
        store_cpu_field(tmp, condexec_bits);
8644
 
      }
8645
3550
    do {
8646
 
#ifdef CONFIG_USER_ONLY
8647
 
        /* Intercept jump to the magic kernel page.  */
8648
 
        if (dc->pc >= 0xffff0000) {
8649
 
            /* We always get here via a jump, so know we are not in a
8650
 
               conditional execution block.  */
8651
 
            gen_exception(EXCP_KERNEL_TRAP);
8652
 
            dc->is_jmp = DISAS_UPDATE;
8653
 
            break;
8654
 
        }
8655
 
#else
8656
 
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8657
 
            /* We always get here via a jump, so know we are not in a
8658
 
               conditional execution block.  */
8659
 
            gen_exception(EXCP_EXCEPTION_EXIT);
8660
 
            dc->is_jmp = DISAS_UPDATE;
8661
 
            break;
8662
 
        }
8663
 
#endif
8664
 
 
8665
3551
        if (env->nb_breakpoints > 0) {
8666
3552
            for(j = 0; j < env->nb_breakpoints; j++) {
8667
3553
                if (env->breakpoints[j] == dc->pc) {
8668
 
                    gen_set_condexec(dc);
8669
 
                    gen_set_pc_im(dc->pc);
8670
 
                    gen_exception(EXCP_DEBUG);
 
3554
                    gen_op_movl_T0_im((long)dc->pc);
 
3555
                    gen_op_movl_reg_TN[0][15]();
 
3556
                    gen_op_debug();
8671
3557
                    dc->is_jmp = DISAS_JUMP;
8672
 
                    /* Advance PC so that clearing the breakpoint will
8673
 
                       invalidate this TB.  */
8674
 
                    dc->pc += 2;
8675
 
                    goto done_generating;
8676
3558
                    break;
8677
3559
                }
8678
3560
            }
8686
3568
            }
8687
3569
            gen_opc_pc[lj] = dc->pc;
8688
3570
            gen_opc_instr_start[lj] = 1;
8689
 
            gen_opc_icount[lj] = num_insns;
8690
 
        }
8691
 
 
8692
 
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8693
 
            gen_io_start();
8694
 
 
8695
 
        if (env->thumb) {
8696
 
            disas_thumb_insn(env, dc);
8697
 
            if (dc->condexec_mask) {
8698
 
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8699
 
                                   | ((dc->condexec_mask >> 4) & 1);
8700
 
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8701
 
                if (dc->condexec_mask == 0) {
8702
 
                    dc->condexec_cond = 0;
8703
 
                }
8704
 
            }
8705
 
        } else {
8706
 
            disas_arm_insn(env, dc);
8707
 
        }
8708
 
        if (num_temps) {
8709
 
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8710
 
            num_temps = 0;
8711
 
        }
 
3571
        }
 
3572
 
 
3573
        if (env->thumb)
 
3574
          disas_thumb_insn(dc);
 
3575
        else
 
3576
          disas_arm_insn(env, dc);
8712
3577
 
8713
3578
        if (dc->condjmp && !dc->is_jmp) {
8714
3579
            gen_set_label(dc->condlabel);
8723
3588
        /* Translation stops when a conditional branch is enoutered.
8724
3589
         * Otherwise the subsequent code could get translated several times.
8725
3590
         * Also stop translation when a page boundary is reached.  This
8726
 
         * ensures prefetch aborts occur at the right place.  */
8727
 
        num_insns ++;
 
3591
         * ensures prefech aborts occur at the right place.  */
8728
3592
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8729
3593
             !env->singlestep_enabled &&
8730
 
             dc->pc < next_page_start &&
8731
 
             num_insns < max_insns);
8732
 
 
8733
 
    if (tb->cflags & CF_LAST_IO) {
8734
 
        if (dc->condjmp) {
8735
 
            /* FIXME:  This can theoretically happen with self-modifying
8736
 
               code.  */
8737
 
            cpu_abort(env, "IO on conditional branch instruction");
8738
 
        }
8739
 
        gen_io_end();
8740
 
    }
8741
 
 
 
3594
             dc->pc < next_page_start);
8742
3595
    /* At this stage dc->condjmp will only be set when the skipped
8743
 
       instruction was a conditional branch or trap, and the PC has
8744
 
       already been written.  */
8745
 
    if (unlikely(env->singlestep_enabled)) {
 
3596
     * instruction was a conditional branch, and the PC has already been
 
3597
     * written.  */
 
3598
    if (__builtin_expect(env->singlestep_enabled, 0)) {
8746
3599
        /* Make sure the pc is updated, and raise a debug exception.  */
8747
3600
        if (dc->condjmp) {
8748
 
            gen_set_condexec(dc);
8749
 
            if (dc->is_jmp == DISAS_SWI) {
8750
 
                gen_exception(EXCP_SWI);
8751
 
            } else {
8752
 
                gen_exception(EXCP_DEBUG);
8753
 
            }
 
3601
            gen_op_debug();
8754
3602
            gen_set_label(dc->condlabel);
8755
3603
        }
8756
3604
        if (dc->condjmp || !dc->is_jmp) {
8757
 
            gen_set_pc_im(dc->pc);
 
3605
            gen_op_movl_T0_im((long)dc->pc);
 
3606
            gen_op_movl_reg_TN[0][15]();
8758
3607
            dc->condjmp = 0;
8759
3608
        }
8760
 
        gen_set_condexec(dc);
8761
 
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8762
 
            gen_exception(EXCP_SWI);
8763
 
        } else {
8764
 
            /* FIXME: Single stepping a WFI insn will not halt
8765
 
               the CPU.  */
8766
 
            gen_exception(EXCP_DEBUG);
8767
 
        }
 
3609
        gen_op_debug();
8768
3610
    } else {
8769
 
        /* While branches must always occur at the end of an IT block,
8770
 
           there are a few other things that can cause us to terminate
8771
 
           the TB in the middel of an IT block:
8772
 
            - Exception generating instructions (bkpt, swi, undefined).
8773
 
            - Page boundaries.
8774
 
            - Hardware watchpoints.
8775
 
           Hardware breakpoints have already been handled and skip this code.
8776
 
         */
8777
 
        gen_set_condexec(dc);
8778
3611
        switch(dc->is_jmp) {
8779
3612
        case DISAS_NEXT:
8780
3613
            gen_goto_tb(dc, 1, dc->pc);
8783
3616
        case DISAS_JUMP:
8784
3617
        case DISAS_UPDATE:
8785
3618
            /* indicate that the hash table must be used to find the next TB */
8786
 
            tcg_gen_exit_tb(0);
 
3619
            gen_op_movl_T0_0();
 
3620
            gen_op_exit_tb();
8787
3621
            break;
8788
3622
        case DISAS_TB_JUMP:
8789
3623
            /* nothing more to generate */
8790
3624
            break;
8791
 
        case DISAS_WFI:
8792
 
            gen_helper_wfi();
8793
 
            break;
8794
 
        case DISAS_SWI:
8795
 
            gen_exception(EXCP_SWI);
8796
 
            break;
8797
3625
        }
8798
3626
        if (dc->condjmp) {
8799
3627
            gen_set_label(dc->condlabel);
8800
 
            gen_set_condexec(dc);
8801
3628
            gen_goto_tb(dc, 1, dc->pc);
8802
3629
            dc->condjmp = 0;
8803
3630
        }
8804
3631
    }
8805
 
 
8806
 
done_generating:
8807
 
    gen_icount_end(tb, num_insns);
8808
3632
    *gen_opc_ptr = INDEX_op_end;
8809
3633
 
8810
3634
#ifdef DEBUG_DISAS
8813
3637
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8814
3638
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8815
3639
        fprintf(logfile, "\n");
 
3640
        if (loglevel & (CPU_LOG_TB_OP)) {
 
3641
            fprintf(logfile, "OP:\n");
 
3642
            dump_ops(gen_opc_buf, gen_opparam_buf);
 
3643
            fprintf(logfile, "\n");
 
3644
        }
8816
3645
    }
8817
3646
#endif
8818
3647
    if (search_pc) {
8820
3649
        lj++;
8821
3650
        while (lj <= j)
8822
3651
            gen_opc_instr_start[lj++] = 0;
 
3652
        tb->size = 0;
8823
3653
    } else {
8824
3654
        tb->size = dc->pc - pc_start;
8825
 
        tb->icount = num_insns;
8826
3655
    }
8827
 
}
8828
 
 
8829
 
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8830
 
{
8831
 
    gen_intermediate_code_internal(env, tb, 0);
8832
 
}
8833
 
 
8834
 
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8835
 
{
8836
 
    gen_intermediate_code_internal(env, tb, 1);
 
3656
    return 0;
 
3657
}
 
3658
 
 
3659
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
 
3660
{
 
3661
    return gen_intermediate_code_internal(env, tb, 0);
 
3662
}
 
3663
 
 
3664
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
 
3665
{
 
3666
    return gen_intermediate_code_internal(env, tb, 1);
8837
3667
}
8838
3668
 
8839
3669
static const char *cpu_mode_names[16] = {
8840
3670
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8841
3671
  "???", "???", "???", "und", "???", "???", "???", "sys"
8842
3672
};
8843
 
 
8844
 
void cpu_dump_state(CPUState *env, FILE *f,
 
3673
void cpu_dump_state(CPUState *env, FILE *f, 
8845
3674
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8846
3675
                    int flags)
8847
3676
{
8848
3677
    int i;
8849
 
#if 0
8850
3678
    union {
8851
3679
        uint32_t i;
8852
3680
        float s;
8858
3686
        float64 f64;
8859
3687
        double d;
8860
3688
    } d0;
8861
 
#endif
8862
3689
    uint32_t psr;
8863
3690
 
8864
3691
    for(i=0;i<16;i++) {
8875
3702
                psr & (1 << 30) ? 'Z' : '-',
8876
3703
                psr & (1 << 29) ? 'C' : '-',
8877
3704
                psr & (1 << 28) ? 'V' : '-',
8878
 
                psr & CPSR_T ? 'T' : 'A',
 
3705
                psr & CPSR_T ? 'T' : 'A', 
8879
3706
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8880
3707
 
8881
 
#if 0
8882
3708
    for (i = 0; i < 16; i++) {
8883
3709
        d.d = env->vfp.regs[i];
8884
3710
        s0.i = d.l.lower;
8891
3717
                    d0.d);
8892
3718
    }
8893
3719
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8894
 
#endif
8895
3720
}
8896
3721
 
8897
 
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8898
 
                unsigned long searched_pc, int pc_pos, void *puc)
8899
 
{
8900
 
    env->regs[15] = gen_opc_pc[pc_pos];
8901
 
}