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

« back to all changes in this revision

Viewing changes to target-arm/op.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  ARM micro operations
3
 
 *
4
 
 *  Copyright (c) 2003 Fabrice Bellard
5
 
 *  Copyright (c) 2005-2007 CodeSourcery, LLC
6
 
 *
7
 
 * This library is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU Lesser General Public
9
 
 * License as published by the Free Software Foundation; either
10
 
 * version 2 of the License, or (at your option) any later version.
11
 
 *
12
 
 * This library is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
 * Lesser General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU Lesser General Public
18
 
 * License along with this library; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 */
21
 
#include "exec.h"
22
 
 
23
 
#define REGNAME r0
24
 
#define REG (env->regs[0])
25
 
#include "op_template.h"
26
 
 
27
 
#define REGNAME r1
28
 
#define REG (env->regs[1])
29
 
#include "op_template.h"
30
 
 
31
 
#define REGNAME r2
32
 
#define REG (env->regs[2])
33
 
#include "op_template.h"
34
 
 
35
 
#define REGNAME r3
36
 
#define REG (env->regs[3])
37
 
#include "op_template.h"
38
 
 
39
 
#define REGNAME r4
40
 
#define REG (env->regs[4])
41
 
#include "op_template.h"
42
 
 
43
 
#define REGNAME r5
44
 
#define REG (env->regs[5])
45
 
#include "op_template.h"
46
 
 
47
 
#define REGNAME r6
48
 
#define REG (env->regs[6])
49
 
#include "op_template.h"
50
 
 
51
 
#define REGNAME r7
52
 
#define REG (env->regs[7])
53
 
#include "op_template.h"
54
 
 
55
 
#define REGNAME r8
56
 
#define REG (env->regs[8])
57
 
#include "op_template.h"
58
 
 
59
 
#define REGNAME r9
60
 
#define REG (env->regs[9])
61
 
#include "op_template.h"
62
 
 
63
 
#define REGNAME r10
64
 
#define REG (env->regs[10])
65
 
#include "op_template.h"
66
 
 
67
 
#define REGNAME r11
68
 
#define REG (env->regs[11])
69
 
#include "op_template.h"
70
 
 
71
 
#define REGNAME r12
72
 
#define REG (env->regs[12])
73
 
#include "op_template.h"
74
 
 
75
 
#define REGNAME r13
76
 
#define REG (env->regs[13])
77
 
#include "op_template.h"
78
 
 
79
 
#define REGNAME r14
80
 
#define REG (env->regs[14])
81
 
#include "op_template.h"
82
 
 
83
 
#define REGNAME r15
84
 
#define REG (env->regs[15])
85
 
#define SET_REG(x) REG = x & ~(uint32_t)1
86
 
#include "op_template.h"
87
 
 
88
 
void OPPROTO op_bx_T0(void)
89
 
{
90
 
  env->regs[15] = T0 & ~(uint32_t)1;
91
 
  env->thumb = (T0 & 1) != 0;
92
 
}
93
 
 
94
 
void OPPROTO op_movl_T0_0(void)
95
 
{
96
 
    T0 = 0;
97
 
}
98
 
 
99
 
void OPPROTO op_movl_T0_im(void)
100
 
{
101
 
    T0 = PARAM1;
102
 
}
103
 
 
104
 
void OPPROTO op_movl_T1_im(void)
105
 
{
106
 
    T1 = PARAM1;
107
 
}
108
 
 
109
 
void OPPROTO op_mov_CF_T1(void)
110
 
{
111
 
    env->CF = ((uint32_t)T1) >> 31;
112
 
}
113
 
 
114
 
void OPPROTO op_movl_T2_im(void)
115
 
{
116
 
    T2 = PARAM1;
117
 
}
118
 
 
119
 
void OPPROTO op_addl_T1_im(void)
120
 
{
121
 
    T1 += PARAM1;
122
 
}
123
 
 
124
 
void OPPROTO op_addl_T1_T2(void)
125
 
{
126
 
    T1 += T2;
127
 
}
128
 
 
129
 
void OPPROTO op_subl_T1_T2(void)
130
 
{
131
 
    T1 -= T2;
132
 
}
133
 
 
134
 
void OPPROTO op_addl_T0_T1(void)
135
 
{
136
 
    T0 += T1;
137
 
}
138
 
 
139
 
void OPPROTO op_addl_T0_T1_cc(void)
140
 
{
141
 
    unsigned int src1;
142
 
    src1 = T0;
143
 
    T0 += T1;
144
 
    env->NZF = T0;
145
 
    env->CF = T0 < src1;
146
 
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
147
 
}
148
 
 
149
 
void OPPROTO op_adcl_T0_T1(void)
150
 
{
151
 
    T0 += T1 + env->CF;
152
 
}
153
 
 
154
 
void OPPROTO op_adcl_T0_T1_cc(void)
155
 
{
156
 
    unsigned int src1;
157
 
    src1 = T0;
158
 
    if (!env->CF) {
159
 
        T0 += T1;
160
 
        env->CF = T0 < src1;
161
 
    } else {
162
 
        T0 += T1 + 1;
163
 
        env->CF = T0 <= src1;
164
 
    }
165
 
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
166
 
    env->NZF = T0;
167
 
    FORCE_RET();
168
 
}
169
 
 
170
 
#define OPSUB(sub, sbc, res, T0, T1)            \
171
 
                                                \
172
 
void OPPROTO op_ ## sub ## l_T0_T1(void)        \
173
 
{                                               \
174
 
    res = T0 - T1;                              \
175
 
}                                               \
176
 
                                                \
177
 
void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
178
 
{                                               \
179
 
    unsigned int src1;                          \
180
 
    src1 = T0;                                  \
181
 
    T0 -= T1;                                   \
182
 
    env->NZF = T0;                              \
183
 
    env->CF = src1 >= T1;                       \
184
 
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
185
 
    res = T0;                                   \
186
 
}                                               \
187
 
                                                \
188
 
void OPPROTO op_ ## sbc ## l_T0_T1(void)        \
189
 
{                                               \
190
 
    res = T0 - T1 + env->CF - 1;                \
191
 
}                                               \
192
 
                                                \
193
 
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
194
 
{                                               \
195
 
    unsigned int src1;                          \
196
 
    src1 = T0;                                  \
197
 
    if (!env->CF) {                             \
198
 
        T0 = T0 - T1 - 1;                       \
199
 
        env->CF = src1 > T1;                    \
200
 
    } else {                                    \
201
 
        T0 = T0 - T1;                           \
202
 
        env->CF = src1 >= T1;                   \
203
 
    }                                           \
204
 
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
205
 
    env->NZF = T0;                              \
206
 
    res = T0;                                   \
207
 
    FORCE_RET();                                \
208
 
}
209
 
 
210
 
OPSUB(sub, sbc, T0, T0, T1)
211
 
 
212
 
OPSUB(rsb, rsc, T0, T1, T0)
213
 
 
214
 
void OPPROTO op_andl_T0_T1(void)
215
 
{
216
 
    T0 &= T1;
217
 
}
218
 
 
219
 
void OPPROTO op_xorl_T0_T1(void)
220
 
{
221
 
    T0 ^= T1;
222
 
}
223
 
 
224
 
void OPPROTO op_orl_T0_T1(void)
225
 
{
226
 
    T0 |= T1;
227
 
}
228
 
 
229
 
void OPPROTO op_bicl_T0_T1(void)
230
 
{
231
 
    T0 &= ~T1;
232
 
}
233
 
 
234
 
void OPPROTO op_notl_T0(void)
235
 
{
236
 
    T0 = ~T0;
237
 
}
238
 
 
239
 
void OPPROTO op_notl_T1(void)
240
 
{
241
 
    T1 = ~T1;
242
 
}
243
 
 
244
 
void OPPROTO op_logic_T0_cc(void)
245
 
{
246
 
    env->NZF = T0;
247
 
}
248
 
 
249
 
void OPPROTO op_logic_T1_cc(void)
250
 
{
251
 
    env->NZF = T1;
252
 
}
253
 
 
254
 
#define EIP (env->regs[15])
255
 
 
256
 
void OPPROTO op_test_eq(void)
257
 
{
258
 
    if (env->NZF == 0)
259
 
        GOTO_LABEL_PARAM(1);;
260
 
    FORCE_RET();
261
 
}
262
 
 
263
 
void OPPROTO op_test_ne(void)
264
 
{
265
 
    if (env->NZF != 0)
266
 
        GOTO_LABEL_PARAM(1);;
267
 
    FORCE_RET();
268
 
}
269
 
 
270
 
void OPPROTO op_test_cs(void)
271
 
{
272
 
    if (env->CF != 0)
273
 
        GOTO_LABEL_PARAM(1);
274
 
    FORCE_RET();
275
 
}
276
 
 
277
 
void OPPROTO op_test_cc(void)
278
 
{
279
 
    if (env->CF == 0)
280
 
        GOTO_LABEL_PARAM(1);
281
 
    FORCE_RET();
282
 
}
283
 
 
284
 
void OPPROTO op_test_mi(void)
285
 
{
286
 
    if ((env->NZF & 0x80000000) != 0)
287
 
        GOTO_LABEL_PARAM(1);
288
 
    FORCE_RET();
289
 
}
290
 
 
291
 
void OPPROTO op_test_pl(void)
292
 
{
293
 
    if ((env->NZF & 0x80000000) == 0)
294
 
        GOTO_LABEL_PARAM(1);
295
 
    FORCE_RET();
296
 
}
297
 
 
298
 
void OPPROTO op_test_vs(void)
299
 
{
300
 
    if ((env->VF & 0x80000000) != 0)
301
 
        GOTO_LABEL_PARAM(1);
302
 
    FORCE_RET();
303
 
}
304
 
 
305
 
void OPPROTO op_test_vc(void)
306
 
{
307
 
    if ((env->VF & 0x80000000) == 0)
308
 
        GOTO_LABEL_PARAM(1);
309
 
    FORCE_RET();
310
 
}
311
 
 
312
 
void OPPROTO op_test_hi(void)
313
 
{
314
 
    if (env->CF != 0 && env->NZF != 0)
315
 
        GOTO_LABEL_PARAM(1);
316
 
    FORCE_RET();
317
 
}
318
 
 
319
 
void OPPROTO op_test_ls(void)
320
 
{
321
 
    if (env->CF == 0 || env->NZF == 0)
322
 
        GOTO_LABEL_PARAM(1);
323
 
    FORCE_RET();
324
 
}
325
 
 
326
 
void OPPROTO op_test_ge(void)
327
 
{
328
 
    if (((env->VF ^ env->NZF) & 0x80000000) == 0)
329
 
        GOTO_LABEL_PARAM(1);
330
 
    FORCE_RET();
331
 
}
332
 
 
333
 
void OPPROTO op_test_lt(void)
334
 
{
335
 
    if (((env->VF ^ env->NZF) & 0x80000000) != 0)
336
 
        GOTO_LABEL_PARAM(1);
337
 
    FORCE_RET();
338
 
}
339
 
 
340
 
void OPPROTO op_test_gt(void)
341
 
{
342
 
    if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
343
 
        GOTO_LABEL_PARAM(1);
344
 
    FORCE_RET();
345
 
}
346
 
 
347
 
void OPPROTO op_test_le(void)
348
 
{
349
 
    if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
350
 
        GOTO_LABEL_PARAM(1);
351
 
    FORCE_RET();
352
 
}
353
 
 
354
 
void OPPROTO op_test_T0(void)
355
 
{
356
 
    if (T0)
357
 
        GOTO_LABEL_PARAM(1);
358
 
    FORCE_RET();
359
 
}
360
 
void OPPROTO op_testn_T0(void)
361
 
{
362
 
    if (!T0)
363
 
        GOTO_LABEL_PARAM(1);
364
 
    FORCE_RET();
365
 
}
366
 
 
367
 
void OPPROTO op_goto_tb0(void)
368
 
{
369
 
    GOTO_TB(op_goto_tb0, PARAM1, 0);
370
 
}
371
 
 
372
 
void OPPROTO op_goto_tb1(void)
373
 
{
374
 
    GOTO_TB(op_goto_tb1, PARAM1, 1);
375
 
}
376
 
 
377
 
void OPPROTO op_exit_tb(void)
378
 
{
379
 
    EXIT_TB();
380
 
}
381
 
 
382
 
void OPPROTO op_movl_T0_cpsr(void)
383
 
{
384
 
    /* Execution state bits always read as zero.  */
385
 
    T0 = cpsr_read(env) & ~CPSR_EXEC;
386
 
    FORCE_RET();
387
 
}
388
 
 
389
 
void OPPROTO op_movl_T0_spsr(void)
390
 
{
391
 
    T0 = env->spsr;
392
 
}
393
 
 
394
 
void OPPROTO op_movl_spsr_T0(void)
395
 
{
396
 
    uint32_t mask = PARAM1;
397
 
    env->spsr = (env->spsr & ~mask) | (T0 & mask);
398
 
}
399
 
 
400
 
void OPPROTO op_movl_cpsr_T0(void)
401
 
{
402
 
    cpsr_write(env, T0, PARAM1);
403
 
    FORCE_RET();
404
 
}
405
 
 
406
 
void OPPROTO op_mul_T0_T1(void)
407
 
{
408
 
    T0 = T0 * T1;
409
 
}
410
 
 
411
 
/* 64 bit unsigned mul */
412
 
void OPPROTO op_mull_T0_T1(void)
413
 
{
414
 
    uint64_t res;
415
 
    res = (uint64_t)T0 * (uint64_t)T1;
416
 
    T1 = res >> 32;
417
 
    T0 = res;
418
 
}
419
 
 
420
 
/* 64 bit signed mul */
421
 
void OPPROTO op_imull_T0_T1(void)
422
 
{
423
 
    uint64_t res;
424
 
    res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
425
 
    T1 = res >> 32;
426
 
    T0 = res;
427
 
}
428
 
 
429
 
/* 48 bit signed mul, top 32 bits */
430
 
void OPPROTO op_imulw_T0_T1(void)
431
 
{
432
 
  uint64_t res;
433
 
  res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
434
 
  T0 = res >> 16;
435
 
}
436
 
 
437
 
void OPPROTO op_addq_T0_T1(void)
438
 
{
439
 
    uint64_t res;
440
 
    res = ((uint64_t)T1 << 32) | T0;
441
 
    res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
442
 
    T1 = res >> 32;
443
 
    T0 = res;
444
 
}
445
 
 
446
 
void OPPROTO op_addq_lo_T0_T1(void)
447
 
{
448
 
    uint64_t res;
449
 
    res = ((uint64_t)T1 << 32) | T0;
450
 
    res += (uint64_t)(env->regs[PARAM1]);
451
 
    T1 = res >> 32;
452
 
    T0 = res;
453
 
}
454
 
 
455
 
/* Dual 16-bit accumulate.  */
456
 
void OPPROTO op_addq_T0_T1_dual(void)
457
 
{
458
 
  uint64_t res;
459
 
  res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
460
 
  res += (int32_t)T0;
461
 
  res += (int32_t)T1;
462
 
  env->regs[PARAM1] = (uint32_t)res;
463
 
  env->regs[PARAM2] = res >> 32;
464
 
}
465
 
 
466
 
/* Dual 16-bit subtract accumulate.  */
467
 
void OPPROTO op_subq_T0_T1_dual(void)
468
 
{
469
 
  uint64_t res;
470
 
  res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
471
 
  res += (int32_t)T0;
472
 
  res -= (int32_t)T1;
473
 
  env->regs[PARAM1] = (uint32_t)res;
474
 
  env->regs[PARAM2] = res >> 32;
475
 
}
476
 
 
477
 
void OPPROTO op_logicq_cc(void)
478
 
{
479
 
    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
480
 
}
481
 
 
482
 
/* memory access */
483
 
 
484
 
#define MEMSUFFIX _raw
485
 
#include "op_mem.h"
486
 
 
487
 
#if !defined(CONFIG_USER_ONLY)
488
 
#define MEMSUFFIX _user
489
 
#include "op_mem.h"
490
 
#define MEMSUFFIX _kernel
491
 
#include "op_mem.h"
492
 
#endif
493
 
 
494
 
void OPPROTO op_clrex(void)
495
 
{
496
 
    cpu_lock();
497
 
    helper_clrex(env);
498
 
    cpu_unlock();
499
 
}
500
 
 
501
 
/* shifts */
502
 
 
503
 
/* Used by NEON.  */
504
 
void OPPROTO op_shll_T0_im(void)
505
 
{
506
 
    T1 = T1 << PARAM1;
507
 
}
508
 
 
509
 
/* T1 based */
510
 
 
511
 
void OPPROTO op_shll_T1_im(void)
512
 
{
513
 
    T1 = T1 << PARAM1;
514
 
}
515
 
 
516
 
void OPPROTO op_shrl_T1_im(void)
517
 
{
518
 
    T1 = (uint32_t)T1 >> PARAM1;
519
 
}
520
 
 
521
 
void OPPROTO op_shrl_T1_0(void)
522
 
{
523
 
    T1 = 0;
524
 
}
525
 
 
526
 
void OPPROTO op_sarl_T1_im(void)
527
 
{
528
 
    T1 = (int32_t)T1 >> PARAM1;
529
 
}
530
 
 
531
 
void OPPROTO op_sarl_T1_0(void)
532
 
{
533
 
    T1 = (int32_t)T1 >> 31;
534
 
}
535
 
 
536
 
void OPPROTO op_rorl_T1_im(void)
537
 
{
538
 
    int shift;
539
 
    shift = PARAM1;
540
 
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
541
 
}
542
 
 
543
 
void OPPROTO op_rrxl_T1(void)
544
 
{
545
 
    T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
546
 
}
547
 
 
548
 
/* T1 based, set C flag */
549
 
void OPPROTO op_shll_T1_im_cc(void)
550
 
{
551
 
    env->CF = (T1 >> (32 - PARAM1)) & 1;
552
 
    T1 = T1 << PARAM1;
553
 
}
554
 
 
555
 
void OPPROTO op_shrl_T1_im_cc(void)
556
 
{
557
 
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
558
 
    T1 = (uint32_t)T1 >> PARAM1;
559
 
}
560
 
 
561
 
void OPPROTO op_shrl_T1_0_cc(void)
562
 
{
563
 
    env->CF = (T1 >> 31) & 1;
564
 
    T1 = 0;
565
 
}
566
 
 
567
 
void OPPROTO op_sarl_T1_im_cc(void)
568
 
{
569
 
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
570
 
    T1 = (int32_t)T1 >> PARAM1;
571
 
}
572
 
 
573
 
void OPPROTO op_sarl_T1_0_cc(void)
574
 
{
575
 
    env->CF = (T1 >> 31) & 1;
576
 
    T1 = (int32_t)T1 >> 31;
577
 
}
578
 
 
579
 
void OPPROTO op_rorl_T1_im_cc(void)
580
 
{
581
 
    int shift;
582
 
    shift = PARAM1;
583
 
    env->CF = (T1 >> (shift - 1)) & 1;
584
 
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
585
 
}
586
 
 
587
 
void OPPROTO op_rrxl_T1_cc(void)
588
 
{
589
 
    uint32_t c;
590
 
    c = T1 & 1;
591
 
    T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
592
 
    env->CF = c;
593
 
}
594
 
 
595
 
/* T2 based */
596
 
void OPPROTO op_shll_T2_im(void)
597
 
{
598
 
    T2 = T2 << PARAM1;
599
 
}
600
 
 
601
 
void OPPROTO op_shrl_T2_im(void)
602
 
{
603
 
    T2 = (uint32_t)T2 >> PARAM1;
604
 
}
605
 
 
606
 
void OPPROTO op_shrl_T2_0(void)
607
 
{
608
 
    T2 = 0;
609
 
}
610
 
 
611
 
void OPPROTO op_sarl_T2_im(void)
612
 
{
613
 
    T2 = (int32_t)T2 >> PARAM1;
614
 
}
615
 
 
616
 
void OPPROTO op_sarl_T2_0(void)
617
 
{
618
 
    T2 = (int32_t)T2 >> 31;
619
 
}
620
 
 
621
 
void OPPROTO op_rorl_T2_im(void)
622
 
{
623
 
    int shift;
624
 
    shift = PARAM1;
625
 
    T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
626
 
}
627
 
 
628
 
void OPPROTO op_rrxl_T2(void)
629
 
{
630
 
    T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31);
631
 
}
632
 
 
633
 
/* T1 based, use T0 as shift count */
634
 
 
635
 
void OPPROTO op_shll_T1_T0(void)
636
 
{
637
 
    int shift;
638
 
    shift = T0 & 0xff;
639
 
    if (shift >= 32)
640
 
        T1 = 0;
641
 
    else
642
 
        T1 = T1 << shift;
643
 
    FORCE_RET();
644
 
}
645
 
 
646
 
void OPPROTO op_shrl_T1_T0(void)
647
 
{
648
 
    int shift;
649
 
    shift = T0 & 0xff;
650
 
    if (shift >= 32)
651
 
        T1 = 0;
652
 
    else
653
 
        T1 = (uint32_t)T1 >> shift;
654
 
    FORCE_RET();
655
 
}
656
 
 
657
 
void OPPROTO op_sarl_T1_T0(void)
658
 
{
659
 
    int shift;
660
 
    shift = T0 & 0xff;
661
 
    if (shift >= 32)
662
 
        shift = 31;
663
 
    T1 = (int32_t)T1 >> shift;
664
 
}
665
 
 
666
 
void OPPROTO op_rorl_T1_T0(void)
667
 
{
668
 
    int shift;
669
 
    shift = T0 & 0x1f;
670
 
    if (shift) {
671
 
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
672
 
    }
673
 
    FORCE_RET();
674
 
}
675
 
 
676
 
/* T1 based, use T0 as shift count and compute CF */
677
 
 
678
 
void OPPROTO op_shll_T1_T0_cc(void)
679
 
{
680
 
    int shift;
681
 
    shift = T0 & 0xff;
682
 
    if (shift >= 32) {
683
 
        if (shift == 32)
684
 
            env->CF = T1 & 1;
685
 
        else
686
 
            env->CF = 0;
687
 
        T1 = 0;
688
 
    } else if (shift != 0) {
689
 
        env->CF = (T1 >> (32 - shift)) & 1;
690
 
        T1 = T1 << shift;
691
 
    }
692
 
    FORCE_RET();
693
 
}
694
 
 
695
 
void OPPROTO op_shrl_T1_T0_cc(void)
696
 
{
697
 
    int shift;
698
 
    shift = T0 & 0xff;
699
 
    if (shift >= 32) {
700
 
        if (shift == 32)
701
 
            env->CF = (T1 >> 31) & 1;
702
 
        else
703
 
            env->CF = 0;
704
 
        T1 = 0;
705
 
    } else if (shift != 0) {
706
 
        env->CF = (T1 >> (shift - 1)) & 1;
707
 
        T1 = (uint32_t)T1 >> shift;
708
 
    }
709
 
    FORCE_RET();
710
 
}
711
 
 
712
 
void OPPROTO op_sarl_T1_T0_cc(void)
713
 
{
714
 
    int shift;
715
 
    shift = T0 & 0xff;
716
 
    if (shift >= 32) {
717
 
        env->CF = (T1 >> 31) & 1;
718
 
        T1 = (int32_t)T1 >> 31;
719
 
    } else if (shift != 0) {
720
 
        env->CF = (T1 >> (shift - 1)) & 1;
721
 
        T1 = (int32_t)T1 >> shift;
722
 
    }
723
 
    FORCE_RET();
724
 
}
725
 
 
726
 
void OPPROTO op_rorl_T1_T0_cc(void)
727
 
{
728
 
    int shift1, shift;
729
 
    shift1 = T0 & 0xff;
730
 
    shift = shift1 & 0x1f;
731
 
    if (shift == 0) {
732
 
        if (shift1 != 0)
733
 
            env->CF = (T1 >> 31) & 1;
734
 
    } else {
735
 
        env->CF = (T1 >> (shift - 1)) & 1;
736
 
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
737
 
    }
738
 
    FORCE_RET();
739
 
}
740
 
 
741
 
/* misc */
742
 
void OPPROTO op_clz_T0(void)
743
 
{
744
 
    int count;
745
 
    for (count = 32; T0 > 0; count--)
746
 
        T0 = T0 >> 1;
747
 
    T0 = count;
748
 
    FORCE_RET();
749
 
}
750
 
 
751
 
void OPPROTO op_sarl_T0_im(void)
752
 
{
753
 
    T0 = (int32_t)T0 >> PARAM1;
754
 
}
755
 
 
756
 
/* Sign/zero extend */
757
 
void OPPROTO op_sxth_T0(void)
758
 
{
759
 
  T0 = (int16_t)T0;
760
 
}
761
 
 
762
 
void OPPROTO op_sxth_T1(void)
763
 
{
764
 
  T1 = (int16_t)T1;
765
 
}
766
 
 
767
 
void OPPROTO op_sxtb_T1(void)
768
 
{
769
 
    T1 = (int8_t)T1;
770
 
}
771
 
 
772
 
void OPPROTO op_uxtb_T1(void)
773
 
{
774
 
    T1 = (uint8_t)T1;
775
 
}
776
 
 
777
 
void OPPROTO op_uxth_T1(void)
778
 
{
779
 
    T1 = (uint16_t)T1;
780
 
}
781
 
 
782
 
void OPPROTO op_sxtb16_T1(void)
783
 
{
784
 
    uint32_t res;
785
 
    res = (uint16_t)(int8_t)T1;
786
 
    res |= (uint32_t)(int8_t)(T1 >> 16) << 16;
787
 
    T1 = res;
788
 
}
789
 
 
790
 
void OPPROTO op_uxtb16_T1(void)
791
 
{
792
 
    uint32_t res;
793
 
    res = (uint16_t)(uint8_t)T1;
794
 
    res |= (uint32_t)(uint8_t)(T1 >> 16) << 16;
795
 
    T1 = res;
796
 
}
797
 
 
798
 
#define SIGNBIT (uint32_t)0x80000000
799
 
/* saturating arithmetic  */
800
 
void OPPROTO op_addl_T0_T1_setq(void)
801
 
{
802
 
  uint32_t res;
803
 
 
804
 
  res = T0 + T1;
805
 
  if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT))
806
 
      env->QF = 1;
807
 
 
808
 
  T0 = res;
809
 
  FORCE_RET();
810
 
}
811
 
 
812
 
void OPPROTO op_addl_T0_T1_saturate(void)
813
 
{
814
 
  uint32_t res;
815
 
 
816
 
  res = T0 + T1;
817
 
  if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) {
818
 
      env->QF = 1;
819
 
      if (T0 & SIGNBIT)
820
 
          T0 = 0x80000000;
821
 
      else
822
 
          T0 = 0x7fffffff;
823
 
  }
824
 
  else
825
 
    T0 = res;
826
 
 
827
 
  FORCE_RET();
828
 
}
829
 
 
830
 
void OPPROTO op_subl_T0_T1_saturate(void)
831
 
{
832
 
  uint32_t res;
833
 
 
834
 
  res = T0 - T1;
835
 
  if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) {
836
 
      env->QF = 1;
837
 
      if (T0 & SIGNBIT)
838
 
          T0 = 0x80000000;
839
 
      else
840
 
          T0 = 0x7fffffff;
841
 
  }
842
 
  else
843
 
    T0 = res;
844
 
 
845
 
  FORCE_RET();
846
 
}
847
 
 
848
 
void OPPROTO op_double_T1_saturate(void)
849
 
{
850
 
  int32_t val;
851
 
 
852
 
  val = T1;
853
 
  if (val >= 0x40000000) {
854
 
      T1 = 0x7fffffff;
855
 
      env->QF = 1;
856
 
  } else if (val <= (int32_t)0xc0000000) {
857
 
      T1 = 0x80000000;
858
 
      env->QF = 1;
859
 
  } else {
860
 
      T1 = val << 1;
861
 
  }
862
 
  FORCE_RET();
863
 
}
864
 
 
865
 
/* Unsigned saturating arithmetic for NEON.  */
866
 
void OPPROTO op_addl_T0_T1_usaturate(void)
867
 
{
868
 
  uint32_t res;
869
 
 
870
 
  res = T0 + T1;
871
 
  if (res < T0) {
872
 
      env->QF = 1;
873
 
      T0 = 0xffffffff;
874
 
  } else {
875
 
      T0 = res;
876
 
  }
877
 
 
878
 
  FORCE_RET();
879
 
}
880
 
 
881
 
void OPPROTO op_subl_T0_T1_usaturate(void)
882
 
{
883
 
  uint32_t res;
884
 
 
885
 
  res = T0 - T1;
886
 
  if (res > T0) {
887
 
      env->QF = 1;
888
 
      T0 = 0;
889
 
  } else {
890
 
      T0 = res;
891
 
  }
892
 
 
893
 
  FORCE_RET();
894
 
}
895
 
 
896
 
/* Thumb shift by immediate */
897
 
void OPPROTO op_shll_T0_im_thumb_cc(void)
898
 
{
899
 
    int shift;
900
 
    shift = PARAM1;
901
 
    if (shift != 0) {
902
 
        env->CF = (T0 >> (32 - shift)) & 1;
903
 
        T0 = T0 << shift;
904
 
    }
905
 
    env->NZF = T0;
906
 
    FORCE_RET();
907
 
}
908
 
 
909
 
void OPPROTO op_shll_T0_im_thumb(void)
910
 
{
911
 
    T0 = T0 << PARAM1;
912
 
    FORCE_RET();
913
 
}
914
 
 
915
 
void OPPROTO op_shrl_T0_im_thumb_cc(void)
916
 
{
917
 
    int shift;
918
 
 
919
 
    shift = PARAM1;
920
 
    if (shift == 0) {
921
 
        env->CF = ((uint32_t)T0) >> 31;
922
 
        T0 = 0;
923
 
    } else {
924
 
        env->CF = (T0 >> (shift - 1)) & 1;
925
 
        T0 = T0 >> shift;
926
 
    }
927
 
    env->NZF = T0;
928
 
    FORCE_RET();
929
 
}
930
 
 
931
 
void OPPROTO op_shrl_T0_im_thumb(void)
932
 
{
933
 
    int shift;
934
 
 
935
 
    shift = PARAM1;
936
 
    if (shift == 0) {
937
 
        T0 = 0;
938
 
    } else {
939
 
        T0 = T0 >> shift;
940
 
    }
941
 
    FORCE_RET();
942
 
}
943
 
 
944
 
void OPPROTO op_sarl_T0_im_thumb_cc(void)
945
 
{
946
 
    int shift;
947
 
 
948
 
    shift = PARAM1;
949
 
    if (shift == 0) {
950
 
        T0 = ((int32_t)T0) >> 31;
951
 
        env->CF = T0 & 1;
952
 
    } else {
953
 
        env->CF = (T0 >> (shift - 1)) & 1;
954
 
        T0 = ((int32_t)T0) >> shift;
955
 
    }
956
 
    env->NZF = T0;
957
 
    FORCE_RET();
958
 
}
959
 
 
960
 
void OPPROTO op_sarl_T0_im_thumb(void)
961
 
{
962
 
    int shift;
963
 
 
964
 
    shift = PARAM1;
965
 
    if (shift == 0) {
966
 
        env->CF = T0 & 1;
967
 
    } else {
968
 
        T0 = ((int32_t)T0) >> shift;
969
 
    }
970
 
    FORCE_RET();
971
 
}
972
 
 
973
 
/* exceptions */
974
 
 
975
 
void OPPROTO op_swi(void)
976
 
{
977
 
    env->exception_index = EXCP_SWI;
978
 
    cpu_loop_exit();
979
 
}
980
 
 
981
 
void OPPROTO op_undef_insn(void)
982
 
{
983
 
    env->exception_index = EXCP_UDEF;
984
 
    cpu_loop_exit();
985
 
}
986
 
 
987
 
void OPPROTO op_debug(void)
988
 
{
989
 
    env->exception_index = EXCP_DEBUG;
990
 
    cpu_loop_exit();
991
 
}
992
 
 
993
 
void OPPROTO op_wfi(void)
994
 
{
995
 
    env->exception_index = EXCP_HLT;
996
 
    env->halted = 1;
997
 
    cpu_loop_exit();
998
 
}
999
 
 
1000
 
void OPPROTO op_bkpt(void)
1001
 
{
1002
 
    env->exception_index = EXCP_BKPT;
1003
 
    cpu_loop_exit();
1004
 
}
1005
 
 
1006
 
void OPPROTO op_exception_exit(void)
1007
 
{
1008
 
    env->exception_index = EXCP_EXCEPTION_EXIT;
1009
 
    cpu_loop_exit();
1010
 
}
1011
 
 
1012
 
/* VFP support.  We follow the convention used for VFP instrunctions:
1013
 
   Single precition routines have a "s" suffix, double precision a
1014
 
   "d" suffix.  */
1015
 
 
1016
 
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
1017
 
 
1018
 
#define VFP_BINOP(name) \
1019
 
VFP_OP(name, s)             \
1020
 
{                           \
1021
 
    FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status);    \
1022
 
}                           \
1023
 
VFP_OP(name, d)             \
1024
 
{                           \
1025
 
    FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status);    \
1026
 
}
1027
 
VFP_BINOP(add)
1028
 
VFP_BINOP(sub)
1029
 
VFP_BINOP(mul)
1030
 
VFP_BINOP(div)
1031
 
#undef VFP_BINOP
1032
 
 
1033
 
#define VFP_HELPER(name)  \
1034
 
VFP_OP(name, s)           \
1035
 
{                         \
1036
 
    do_vfp_##name##s();    \
1037
 
}                         \
1038
 
VFP_OP(name, d)           \
1039
 
{                         \
1040
 
    do_vfp_##name##d();    \
1041
 
}
1042
 
VFP_HELPER(abs)
1043
 
VFP_HELPER(sqrt)
1044
 
VFP_HELPER(cmp)
1045
 
VFP_HELPER(cmpe)
1046
 
#undef VFP_HELPER
1047
 
 
1048
 
/* XXX: Will this do the right thing for NANs.  Should invert the signbit
1049
 
   without looking at the rest of the value.  */
1050
 
VFP_OP(neg, s)
1051
 
{
1052
 
    FT0s = float32_chs(FT0s);
1053
 
}
1054
 
 
1055
 
VFP_OP(neg, d)
1056
 
{
1057
 
    FT0d = float64_chs(FT0d);
1058
 
}
1059
 
 
1060
 
VFP_OP(F1_ld0, s)
1061
 
{
1062
 
    union {
1063
 
        uint32_t i;
1064
 
        float32 s;
1065
 
    } v;
1066
 
    v.i = 0;
1067
 
    FT1s = v.s;
1068
 
}
1069
 
 
1070
 
VFP_OP(F1_ld0, d)
1071
 
{
1072
 
    union {
1073
 
        uint64_t i;
1074
 
        float64 d;
1075
 
    } v;
1076
 
    v.i = 0;
1077
 
    FT1d = v.d;
1078
 
}
1079
 
 
1080
 
/* Helper routines to perform bitwise copies between float and int.  */
1081
 
static inline float32 vfp_itos(uint32_t i)
1082
 
{
1083
 
    union {
1084
 
        uint32_t i;
1085
 
        float32 s;
1086
 
    } v;
1087
 
 
1088
 
    v.i = i;
1089
 
    return v.s;
1090
 
}
1091
 
 
1092
 
static inline uint32_t vfp_stoi(float32 s)
1093
 
{
1094
 
    union {
1095
 
        uint32_t i;
1096
 
        float32 s;
1097
 
    } v;
1098
 
 
1099
 
    v.s = s;
1100
 
    return v.i;
1101
 
}
1102
 
 
1103
 
static inline float64 vfp_itod(uint64_t i)
1104
 
{
1105
 
    union {
1106
 
        uint64_t i;
1107
 
        float64 d;
1108
 
    } v;
1109
 
 
1110
 
    v.i = i;
1111
 
    return v.d;
1112
 
}
1113
 
 
1114
 
static inline uint64_t vfp_dtoi(float64 d)
1115
 
{
1116
 
    union {
1117
 
        uint64_t i;
1118
 
        float64 d;
1119
 
    } v;
1120
 
 
1121
 
    v.d = d;
1122
 
    return v.i;
1123
 
}
1124
 
 
1125
 
/* Integer to float conversion.  */
1126
 
VFP_OP(uito, s)
1127
 
{
1128
 
    FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
1129
 
}
1130
 
 
1131
 
VFP_OP(uito, d)
1132
 
{
1133
 
    FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
1134
 
}
1135
 
 
1136
 
VFP_OP(sito, s)
1137
 
{
1138
 
    FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
1139
 
}
1140
 
 
1141
 
VFP_OP(sito, d)
1142
 
{
1143
 
    FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
1144
 
}
1145
 
 
1146
 
/* Float to integer conversion.  */
1147
 
VFP_OP(toui, s)
1148
 
{
1149
 
    FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
1150
 
}
1151
 
 
1152
 
VFP_OP(toui, d)
1153
 
{
1154
 
    FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
1155
 
}
1156
 
 
1157
 
VFP_OP(tosi, s)
1158
 
{
1159
 
    FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
1160
 
}
1161
 
 
1162
 
VFP_OP(tosi, d)
1163
 
{
1164
 
    FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
1165
 
}
1166
 
 
1167
 
/* TODO: Set rounding mode properly.  */
1168
 
VFP_OP(touiz, s)
1169
 
{
1170
 
    FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
1171
 
}
1172
 
 
1173
 
VFP_OP(touiz, d)
1174
 
{
1175
 
    FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
1176
 
}
1177
 
 
1178
 
VFP_OP(tosiz, s)
1179
 
{
1180
 
    FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
1181
 
}
1182
 
 
1183
 
VFP_OP(tosiz, d)
1184
 
{
1185
 
    FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
1186
 
}
1187
 
 
1188
 
/* floating point conversion */
1189
 
VFP_OP(fcvtd, s)
1190
 
{
1191
 
    FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
1192
 
}
1193
 
 
1194
 
VFP_OP(fcvts, d)
1195
 
{
1196
 
    FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
1197
 
}
1198
 
 
1199
 
/* VFP3 fixed point conversion.  */
1200
 
#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
1201
 
VFP_OP(name##to, p) \
1202
 
{ \
1203
 
    ftype tmp; \
1204
 
    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(FT0##p), \
1205
 
                                  &env->vfp.fp_status); \
1206
 
    FT0##p = ftype##_scalbn(tmp, PARAM1, &env->vfp.fp_status); \
1207
 
} \
1208
 
VFP_OP(to##name, p) \
1209
 
{ \
1210
 
    ftype tmp; \
1211
 
    tmp = ftype##_scalbn(FT0##p, PARAM1, &env->vfp.fp_status); \
1212
 
    FT0##p = vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
1213
 
            &env->vfp.fp_status)); \
1214
 
}
1215
 
 
1216
 
VFP_CONV_FIX(sh, d, float64, int16, )
1217
 
VFP_CONV_FIX(sl, d, float64, int32, )
1218
 
VFP_CONV_FIX(uh, d, float64, uint16, u)
1219
 
VFP_CONV_FIX(ul, d, float64, uint32, u)
1220
 
VFP_CONV_FIX(sh, s, float32, int16, )
1221
 
VFP_CONV_FIX(sl, s, float32, int32, )
1222
 
VFP_CONV_FIX(uh, s, float32, uint16, u)
1223
 
VFP_CONV_FIX(ul, s, float32, uint32, u)
1224
 
 
1225
 
/* Get and Put values from registers.  */
1226
 
VFP_OP(getreg_F0, d)
1227
 
{
1228
 
  FT0d = *(float64 *)((char *) env + PARAM1);
1229
 
}
1230
 
 
1231
 
VFP_OP(getreg_F0, s)
1232
 
{
1233
 
  FT0s = *(float32 *)((char *) env + PARAM1);
1234
 
}
1235
 
 
1236
 
VFP_OP(getreg_F1, d)
1237
 
{
1238
 
  FT1d = *(float64 *)((char *) env + PARAM1);
1239
 
}
1240
 
 
1241
 
VFP_OP(getreg_F1, s)
1242
 
{
1243
 
  FT1s = *(float32 *)((char *) env + PARAM1);
1244
 
}
1245
 
 
1246
 
VFP_OP(setreg_F0, d)
1247
 
{
1248
 
  *(float64 *)((char *) env + PARAM1) = FT0d;
1249
 
}
1250
 
 
1251
 
VFP_OP(setreg_F0, s)
1252
 
{
1253
 
  *(float32 *)((char *) env + PARAM1) = FT0s;
1254
 
}
1255
 
 
1256
 
void OPPROTO op_vfp_movl_T0_fpscr(void)
1257
 
{
1258
 
    do_vfp_get_fpscr ();
1259
 
}
1260
 
 
1261
 
void OPPROTO op_vfp_movl_T0_fpscr_flags(void)
1262
 
{
1263
 
    T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);
1264
 
}
1265
 
 
1266
 
void OPPROTO op_vfp_movl_fpscr_T0(void)
1267
 
{
1268
 
    do_vfp_set_fpscr();
1269
 
}
1270
 
 
1271
 
void OPPROTO op_vfp_movl_T0_xreg(void)
1272
 
{
1273
 
    T0 = env->vfp.xregs[PARAM1];
1274
 
}
1275
 
 
1276
 
void OPPROTO op_vfp_movl_xreg_T0(void)
1277
 
{
1278
 
    env->vfp.xregs[PARAM1] = T0;
1279
 
}
1280
 
 
1281
 
/* Move between FT0s to T0  */
1282
 
void OPPROTO op_vfp_mrs(void)
1283
 
{
1284
 
    T0 = vfp_stoi(FT0s);
1285
 
}
1286
 
 
1287
 
void OPPROTO op_vfp_msr(void)
1288
 
{
1289
 
    FT0s = vfp_itos(T0);
1290
 
}
1291
 
 
1292
 
/* Move between FT0d and {T0,T1} */
1293
 
void OPPROTO op_vfp_mrrd(void)
1294
 
{
1295
 
    CPU_DoubleU u;
1296
 
 
1297
 
    u.d = FT0d;
1298
 
    T0 = u.l.lower;
1299
 
    T1 = u.l.upper;
1300
 
}
1301
 
 
1302
 
void OPPROTO op_vfp_mdrr(void)
1303
 
{
1304
 
    CPU_DoubleU u;
1305
 
 
1306
 
    u.l.lower = T0;
1307
 
    u.l.upper = T1;
1308
 
    FT0d = u.d;
1309
 
}
1310
 
 
1311
 
/* Load immediate.  PARAM1 is the 32 most significant bits of the value.  */
1312
 
void OPPROTO op_vfp_fconstd(void)
1313
 
{
1314
 
    CPU_DoubleU u;
1315
 
    u.l.upper = PARAM1;
1316
 
    u.l.lower = 0;
1317
 
    FT0d = u.d;
1318
 
}
1319
 
 
1320
 
void OPPROTO op_vfp_fconsts(void)
1321
 
{
1322
 
    FT0s = vfp_itos(PARAM1);
1323
 
}
1324
 
 
1325
 
/* Copy the most significant bit of T0 to all bits of T1.  */
1326
 
void OPPROTO op_signbit_T1_T0(void)
1327
 
{
1328
 
    T1 = (int32_t)T0 >> 31;
1329
 
}
1330
 
 
1331
 
void OPPROTO op_movl_cp_T0(void)
1332
 
{
1333
 
    helper_set_cp(env, PARAM1, T0);
1334
 
    FORCE_RET();
1335
 
}
1336
 
 
1337
 
void OPPROTO op_movl_T0_cp(void)
1338
 
{
1339
 
    T0 = helper_get_cp(env, PARAM1);
1340
 
    FORCE_RET();
1341
 
}
1342
 
 
1343
 
void OPPROTO op_movl_cp15_T0(void)
1344
 
{
1345
 
    helper_set_cp15(env, PARAM1, T0);
1346
 
    FORCE_RET();
1347
 
}
1348
 
 
1349
 
void OPPROTO op_movl_T0_cp15(void)
1350
 
{
1351
 
    T0 = helper_get_cp15(env, PARAM1);
1352
 
    FORCE_RET();
1353
 
}
1354
 
 
1355
 
/* Access to user mode registers from privileged modes.  */
1356
 
void OPPROTO op_movl_T0_user(void)
1357
 
{
1358
 
    int regno = PARAM1;
1359
 
    if (regno == 13) {
1360
 
        T0 = env->banked_r13[0];
1361
 
    } else if (regno == 14) {
1362
 
        T0 = env->banked_r14[0];
1363
 
    } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
1364
 
        T0 = env->usr_regs[regno - 8];
1365
 
    } else {
1366
 
        T0 = env->regs[regno];
1367
 
    }
1368
 
    FORCE_RET();
1369
 
}
1370
 
 
1371
 
 
1372
 
void OPPROTO op_movl_user_T0(void)
1373
 
{
1374
 
    int regno = PARAM1;
1375
 
    if (regno == 13) {
1376
 
        env->banked_r13[0] = T0;
1377
 
    } else if (regno == 14) {
1378
 
        env->banked_r14[0] = T0;
1379
 
    } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
1380
 
        env->usr_regs[regno - 8] = T0;
1381
 
    } else {
1382
 
        env->regs[regno] = T0;
1383
 
    }
1384
 
    FORCE_RET();
1385
 
}
1386
 
 
1387
 
void OPPROTO op_movl_T0_T1(void)
1388
 
{
1389
 
    T0 = T1;
1390
 
}
1391
 
 
1392
 
void OPPROTO op_movl_T0_T2(void)
1393
 
{
1394
 
    T0 = T2;
1395
 
}
1396
 
 
1397
 
void OPPROTO op_movl_T1_T0(void)
1398
 
{
1399
 
    T1 = T0;
1400
 
}
1401
 
 
1402
 
void OPPROTO op_movl_T1_T2(void)
1403
 
{
1404
 
    T1 = T2;
1405
 
}
1406
 
 
1407
 
void OPPROTO op_movl_T2_T0(void)
1408
 
{
1409
 
    T2 = T0;
1410
 
}
1411
 
 
1412
 
/* ARMv6 Media instructions.  */
1413
 
 
1414
 
/* Note that signed overflow is undefined in C.  The following routines are
1415
 
   careful to use unsigned types where modulo arithmetic is required.
1416
 
   Failure to do so _will_ break on newer gcc.  */
1417
 
 
1418
 
/* Signed saturating arithmetic.  */
1419
 
 
1420
 
/* Perform 16-bit signed satruating addition.  */
1421
 
static inline uint16_t add16_sat(uint16_t a, uint16_t b)
1422
 
{
1423
 
    uint16_t res;
1424
 
 
1425
 
    res = a + b;
1426
 
    if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
1427
 
        if (a & 0x8000)
1428
 
            res = 0x8000;
1429
 
        else
1430
 
            res = 0x7fff;
1431
 
    }
1432
 
    return res;
1433
 
}
1434
 
 
1435
 
/* Perform 8-bit signed satruating addition.  */
1436
 
static inline uint8_t add8_sat(uint8_t a, uint8_t b)
1437
 
{
1438
 
    uint8_t res;
1439
 
 
1440
 
    res = a + b;
1441
 
    if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
1442
 
        if (a & 0x80)
1443
 
            res = 0x80;
1444
 
        else
1445
 
            res = 0x7f;
1446
 
    }
1447
 
    return res;
1448
 
}
1449
 
 
1450
 
/* Perform 16-bit signed satruating subtraction.  */
1451
 
static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
1452
 
{
1453
 
    uint16_t res;
1454
 
 
1455
 
    res = a - b;
1456
 
    if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
1457
 
        if (a & 0x8000)
1458
 
            res = 0x8000;
1459
 
        else
1460
 
            res = 0x7fff;
1461
 
    }
1462
 
    return res;
1463
 
}
1464
 
 
1465
 
/* Perform 8-bit signed satruating subtraction.  */
1466
 
static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
1467
 
{
1468
 
    uint8_t res;
1469
 
 
1470
 
    res = a - b;
1471
 
    if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
1472
 
        if (a & 0x80)
1473
 
            res = 0x80;
1474
 
        else
1475
 
            res = 0x7f;
1476
 
    }
1477
 
    return res;
1478
 
}
1479
 
 
1480
 
#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
1481
 
#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
1482
 
#define ADD8(a, b, n)  RESULT(add8_sat(a, b), n, 8);
1483
 
#define SUB8(a, b, n)  RESULT(sub8_sat(a, b), n, 8);
1484
 
#define PFX q
1485
 
 
1486
 
#include "op_addsub.h"
1487
 
 
1488
 
/* Unsigned saturating arithmetic.  */
1489
 
static inline uint16_t add16_usat(uint16_t a, uint8_t b)
1490
 
{
1491
 
    uint16_t res;
1492
 
    res = a + b;
1493
 
    if (res < a)
1494
 
        res = 0xffff;
1495
 
    return res;
1496
 
}
1497
 
 
1498
 
static inline uint16_t sub16_usat(uint16_t a, uint8_t b)
1499
 
{
1500
 
    if (a < b)
1501
 
        return a - b;
1502
 
    else
1503
 
        return 0;
1504
 
}
1505
 
 
1506
 
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
1507
 
{
1508
 
    uint8_t res;
1509
 
    res = a + b;
1510
 
    if (res < a)
1511
 
        res = 0xff;
1512
 
    return res;
1513
 
}
1514
 
 
1515
 
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
1516
 
{
1517
 
    if (a < b)
1518
 
        return a - b;
1519
 
    else
1520
 
        return 0;
1521
 
}
1522
 
 
1523
 
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
1524
 
#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
1525
 
#define ADD8(a, b, n)  RESULT(add8_usat(a, b), n, 8);
1526
 
#define SUB8(a, b, n)  RESULT(sub8_usat(a, b), n, 8);
1527
 
#define PFX uq
1528
 
 
1529
 
#include "op_addsub.h"
1530
 
 
1531
 
/* Signed modulo arithmetic.  */
1532
 
#define SARITH16(a, b, n, op) do { \
1533
 
    int32_t sum; \
1534
 
    sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
1535
 
    RESULT(sum, n, 16); \
1536
 
    if (sum >= 0) \
1537
 
        ge |= 3 << (n * 2); \
1538
 
    } while(0)
1539
 
 
1540
 
#define SARITH8(a, b, n, op) do { \
1541
 
    int32_t sum; \
1542
 
    sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
1543
 
    RESULT(sum, n, 8); \
1544
 
    if (sum >= 0) \
1545
 
        ge |= 1 << n; \
1546
 
    } while(0)
1547
 
 
1548
 
 
1549
 
#define ADD16(a, b, n) SARITH16(a, b, n, +)
1550
 
#define SUB16(a, b, n) SARITH16(a, b, n, -)
1551
 
#define ADD8(a, b, n)  SARITH8(a, b, n, +)
1552
 
#define SUB8(a, b, n)  SARITH8(a, b, n, -)
1553
 
#define PFX s
1554
 
#define ARITH_GE
1555
 
 
1556
 
#include "op_addsub.h"
1557
 
 
1558
 
/* Unsigned modulo arithmetic.  */
1559
 
#define ADD16(a, b, n) do { \
1560
 
    uint32_t sum; \
1561
 
    sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
1562
 
    RESULT(sum, n, 16); \
1563
 
    if ((sum >> 16) == 0) \
1564
 
        ge |= 3 << (n * 2); \
1565
 
    } while(0)
1566
 
 
1567
 
#define ADD8(a, b, n) do { \
1568
 
    uint32_t sum; \
1569
 
    sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
1570
 
    RESULT(sum, n, 8); \
1571
 
    if ((sum >> 8) == 0) \
1572
 
        ge |= 3 << (n * 2); \
1573
 
    } while(0)
1574
 
 
1575
 
#define SUB16(a, b, n) do { \
1576
 
    uint32_t sum; \
1577
 
    sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
1578
 
    RESULT(sum, n, 16); \
1579
 
    if ((sum >> 16) == 0) \
1580
 
        ge |= 3 << (n * 2); \
1581
 
    } while(0)
1582
 
 
1583
 
#define SUB8(a, b, n) do { \
1584
 
    uint32_t sum; \
1585
 
    sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
1586
 
    RESULT(sum, n, 8); \
1587
 
    if ((sum >> 8) == 0) \
1588
 
        ge |= 3 << (n * 2); \
1589
 
    } while(0)
1590
 
 
1591
 
#define PFX u
1592
 
#define ARITH_GE
1593
 
 
1594
 
#include "op_addsub.h"
1595
 
 
1596
 
/* Halved signed arithmetic.  */
1597
 
#define ADD16(a, b, n) \
1598
 
  RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
1599
 
#define SUB16(a, b, n) \
1600
 
  RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
1601
 
#define ADD8(a, b, n) \
1602
 
  RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
1603
 
#define SUB8(a, b, n) \
1604
 
  RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
1605
 
#define PFX sh
1606
 
 
1607
 
#include "op_addsub.h"
1608
 
 
1609
 
/* Halved unsigned arithmetic.  */
1610
 
#define ADD16(a, b, n) \
1611
 
  RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
1612
 
#define SUB16(a, b, n) \
1613
 
  RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
1614
 
#define ADD8(a, b, n) \
1615
 
  RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
1616
 
#define SUB8(a, b, n) \
1617
 
  RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
1618
 
#define PFX uh
1619
 
 
1620
 
#include "op_addsub.h"
1621
 
 
1622
 
void OPPROTO op_pkhtb_T0_T1(void)
1623
 
{
1624
 
    T0 = (T0 & 0xffff0000) | (T1 & 0xffff);
1625
 
}
1626
 
 
1627
 
void OPPROTO op_pkhbt_T0_T1(void)
1628
 
{
1629
 
    T0 = (T0 & 0xffff) | (T1 & 0xffff0000);
1630
 
}
1631
 
void OPPROTO op_rev_T0(void)
1632
 
{
1633
 
    T0 =  ((T0 & 0xff000000) >> 24)
1634
 
        | ((T0 & 0x00ff0000) >> 8)
1635
 
        | ((T0 & 0x0000ff00) << 8)
1636
 
        | ((T0 & 0x000000ff) << 24);
1637
 
}
1638
 
 
1639
 
void OPPROTO op_revh_T0(void)
1640
 
{
1641
 
    T0 = (T0 >> 16) | (T0 << 16);
1642
 
}
1643
 
 
1644
 
void OPPROTO op_rev16_T0(void)
1645
 
{
1646
 
    T0 =  ((T0 & 0xff000000) >> 8)
1647
 
        | ((T0 & 0x00ff0000) << 8)
1648
 
        | ((T0 & 0x0000ff00) >> 8)
1649
 
        | ((T0 & 0x000000ff) << 8);
1650
 
}
1651
 
 
1652
 
void OPPROTO op_revsh_T0(void)
1653
 
{
1654
 
    T0 = (int16_t)(  ((T0 & 0x0000ff00) >> 8)
1655
 
                   | ((T0 & 0x000000ff) << 8));
1656
 
}
1657
 
 
1658
 
void OPPROTO op_rbit_T0(void)
1659
 
{
1660
 
    T0 =  ((T0 & 0xff000000) >> 24)
1661
 
        | ((T0 & 0x00ff0000) >> 8)
1662
 
        | ((T0 & 0x0000ff00) << 8)
1663
 
        | ((T0 & 0x000000ff) << 24);
1664
 
    T0 =  ((T0 & 0xf0f0f0f0) >> 4)
1665
 
        | ((T0 & 0x0f0f0f0f) << 4);
1666
 
    T0 =  ((T0 & 0x88888888) >> 3)
1667
 
        | ((T0 & 0x44444444) >> 1)
1668
 
        | ((T0 & 0x22222222) << 1)
1669
 
        | ((T0 & 0x11111111) << 3);
1670
 
}
1671
 
 
1672
 
/* Swap low and high halfwords.  */
1673
 
void OPPROTO op_swap_half_T1(void)
1674
 
{
1675
 
    T1 = (T1 >> 16) | (T1 << 16);
1676
 
    FORCE_RET();
1677
 
}
1678
 
 
1679
 
/* Dual 16-bit signed multiply.  */
1680
 
void OPPROTO op_mul_dual_T0_T1(void)
1681
 
{
1682
 
    int32_t low;
1683
 
    int32_t high;
1684
 
    low = (int32_t)(int16_t)T0 * (int32_t)(int16_t)T1;
1685
 
    high = (((int32_t)T0) >> 16) * (((int32_t)T1) >> 16);
1686
 
    T0 = low;
1687
 
    T1 = high;
1688
 
}
1689
 
 
1690
 
void OPPROTO op_sel_T0_T1(void)
1691
 
{
1692
 
    uint32_t mask;
1693
 
    uint32_t flags;
1694
 
 
1695
 
    flags = env->GE;
1696
 
    mask = 0;
1697
 
    if (flags & 1)
1698
 
        mask |= 0xff;
1699
 
    if (flags & 2)
1700
 
        mask |= 0xff00;
1701
 
    if (flags & 4)
1702
 
        mask |= 0xff0000;
1703
 
    if (flags & 8)
1704
 
        mask |= 0xff000000;
1705
 
    T0 = (T0 & mask) | (T1 & ~mask);
1706
 
    FORCE_RET();
1707
 
}
1708
 
 
1709
 
void OPPROTO op_roundqd_T0_T1(void)
1710
 
{
1711
 
    T0 = T1 + ((uint32_t)T0 >> 31);
1712
 
}
1713
 
 
1714
 
/* Signed saturation.  */
1715
 
static inline uint32_t do_ssat(int32_t val, int shift)
1716
 
{
1717
 
    int32_t top;
1718
 
    uint32_t mask;
1719
 
 
1720
 
    shift = PARAM1;
1721
 
    top = val >> shift;
1722
 
    mask = (1u << shift) - 1;
1723
 
    if (top > 0) {
1724
 
        env->QF = 1;
1725
 
        return mask;
1726
 
    } else if (top < -1) {
1727
 
        env->QF = 1;
1728
 
        return ~mask;
1729
 
    }
1730
 
    return val;
1731
 
}
1732
 
 
1733
 
/* Unsigned saturation.  */
1734
 
static inline uint32_t do_usat(int32_t val, int shift)
1735
 
{
1736
 
    uint32_t max;
1737
 
 
1738
 
    shift = PARAM1;
1739
 
    max = (1u << shift) - 1;
1740
 
    if (val < 0) {
1741
 
        env->QF = 1;
1742
 
        return 0;
1743
 
    } else if (val > max) {
1744
 
        env->QF = 1;
1745
 
        return max;
1746
 
    }
1747
 
    return val;
1748
 
}
1749
 
 
1750
 
/* Signed saturate.  */
1751
 
void OPPROTO op_ssat_T1(void)
1752
 
{
1753
 
    T0 = do_ssat(T0, PARAM1);
1754
 
    FORCE_RET();
1755
 
}
1756
 
 
1757
 
/* Dual halfword signed saturate.  */
1758
 
void OPPROTO op_ssat16_T1(void)
1759
 
{
1760
 
    uint32_t res;
1761
 
 
1762
 
    res = (uint16_t)do_ssat((int16_t)T0, PARAM1);
1763
 
    res |= do_ssat(((int32_t)T0) >> 16, PARAM1) << 16;
1764
 
    T0 = res;
1765
 
    FORCE_RET();
1766
 
}
1767
 
 
1768
 
/* Unsigned saturate.  */
1769
 
void OPPROTO op_usat_T1(void)
1770
 
{
1771
 
    T0 = do_usat(T0, PARAM1);
1772
 
    FORCE_RET();
1773
 
}
1774
 
 
1775
 
/* Dual halfword unsigned saturate.  */
1776
 
void OPPROTO op_usat16_T1(void)
1777
 
{
1778
 
    uint32_t res;
1779
 
 
1780
 
    res = (uint16_t)do_usat((int16_t)T0, PARAM1);
1781
 
    res |= do_usat(((int32_t)T0) >> 16, PARAM1) << 16;
1782
 
    T0 = res;
1783
 
    FORCE_RET();
1784
 
}
1785
 
 
1786
 
/* Dual 16-bit add.  */
1787
 
void OPPROTO op_add16_T1_T2(void)
1788
 
{
1789
 
    uint32_t mask;
1790
 
    mask = (T0 & T1) & 0x8000;
1791
 
    T0 ^= ~0x8000;
1792
 
    T1 ^= ~0x8000;
1793
 
    T0 = (T0 + T1) ^ mask;
1794
 
}
1795
 
 
1796
 
static inline uint8_t do_usad(uint8_t a, uint8_t b)
1797
 
{
1798
 
    if (a > b)
1799
 
        return a - b;
1800
 
    else
1801
 
        return b - a;
1802
 
}
1803
 
 
1804
 
/* Unsigned sum of absolute byte differences.  */
1805
 
void OPPROTO op_usad8_T0_T1(void)
1806
 
{
1807
 
    uint32_t sum;
1808
 
    sum = do_usad(T0, T1);
1809
 
    sum += do_usad(T0 >> 8, T1 >> 8);
1810
 
    sum += do_usad(T0 >> 16, T1 >>16);
1811
 
    sum += do_usad(T0 >> 24, T1 >> 24);
1812
 
    T0 = sum;
1813
 
}
1814
 
 
1815
 
/* Thumb-2 instructions.  */
1816
 
 
1817
 
/* Insert T1 into T0.  Result goes in T1.  */
1818
 
void OPPROTO op_bfi_T1_T0(void)
1819
 
{
1820
 
    int shift = PARAM1;
1821
 
    uint32_t mask = PARAM2;
1822
 
    uint32_t bits;
1823
 
 
1824
 
    bits = (T1 << shift) & mask;
1825
 
    T1 = (T0 & ~mask) | bits;
1826
 
}
1827
 
 
1828
 
/* Unsigned bitfield extract.  */
1829
 
void OPPROTO op_ubfx_T1(void)
1830
 
{
1831
 
    uint32_t shift = PARAM1;
1832
 
    uint32_t mask = PARAM2;
1833
 
 
1834
 
    T1 >>= shift;
1835
 
    T1 &= mask;
1836
 
}
1837
 
 
1838
 
/* Signed bitfield extract.  */
1839
 
void OPPROTO op_sbfx_T1(void)
1840
 
{
1841
 
    uint32_t shift = PARAM1;
1842
 
    uint32_t width = PARAM2;
1843
 
    int32_t val;
1844
 
 
1845
 
    val = T1 << (32 - (shift + width));
1846
 
    T1 = val >> (32 - width);
1847
 
}
1848
 
 
1849
 
void OPPROTO op_movtop_T0_im(void)
1850
 
{
1851
 
    T0 = (T0 & 0xffff) | PARAM1;
1852
 
}
1853
 
 
1854
 
/* Used by table branch instructions.  */
1855
 
void OPPROTO op_jmp_T0_im(void)
1856
 
{
1857
 
    env->regs[15] = PARAM1 + (T0 << 1);
1858
 
}
1859
 
 
1860
 
void OPPROTO op_set_condexec(void)
1861
 
{
1862
 
    env->condexec_bits = PARAM1;
1863
 
}
1864
 
 
1865
 
void OPPROTO op_sdivl_T0_T1(void)
1866
 
{
1867
 
  int32_t num;
1868
 
  int32_t den;
1869
 
  num = T0;
1870
 
  den = T1;
1871
 
  if (den == 0)
1872
 
    T0 = 0;
1873
 
  else
1874
 
    T0 = num / den;
1875
 
  FORCE_RET();
1876
 
}
1877
 
 
1878
 
void OPPROTO op_udivl_T0_T1(void)
1879
 
{
1880
 
  uint32_t num;
1881
 
  uint32_t den;
1882
 
  num = T0;
1883
 
  den = T1;
1884
 
  if (den == 0)
1885
 
    T0 = 0;
1886
 
  else
1887
 
    T0 = num / den;
1888
 
  FORCE_RET();
1889
 
}
1890
 
 
1891
 
void OPPROTO op_movl_T1_r13_banked(void)
1892
 
{
1893
 
    T1 = helper_get_r13_banked(env, PARAM1);
1894
 
}
1895
 
 
1896
 
void OPPROTO op_movl_r13_T1_banked(void)
1897
 
{
1898
 
    helper_set_r13_banked(env, PARAM1, T1);
1899
 
}
1900
 
 
1901
 
void OPPROTO op_v7m_mrs_T0(void)
1902
 
{
1903
 
    T0 = helper_v7m_mrs(env, PARAM1);
1904
 
}
1905
 
 
1906
 
void OPPROTO op_v7m_msr_T0(void)
1907
 
{
1908
 
    helper_v7m_msr(env, PARAM1, T0);
1909
 
}
1910
 
 
1911
 
void OPPROTO op_movl_T0_sp(void)
1912
 
{
1913
 
    if (PARAM1 == env->v7m.current_sp)
1914
 
        T0 = env->regs[13];
1915
 
    else
1916
 
        T0 = env->v7m.other_sp;
1917
 
    FORCE_RET();
1918
 
}
1919
 
 
1920
 
#include "op_neon.h"
1921
 
 
1922
 
/* iwMMXt support */
1923
 
#include "op_iwmmxt.c"