Revision 1497c961

b/target-arm/helper.c
322 322
    env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
323 323
}
324 324

  
325
#define HELPER(x) helper_##x
326 325
/* Sign/zero extend */
327 326
uint32_t HELPER(sxtb16)(uint32_t x)
328 327
{
......
1894 1893
}
1895 1894

  
1896 1895
#endif
1897

  
b/target-arm/helpers.h
1
#ifndef DEF_HELPER
2 1
#define DEF_HELPER(name, ret, args) ret helper_##name args;
2

  
3
#ifdef GEN_HELPER
4
#define DEF_HELPER_1_1(name, ret, args) \
5
DEF_HELPER(name, ret, args) \
6
static inline void gen_helper_##name(TCGv ret, TCGv arg1) \
7
{ \
8
    tcg_gen_helper_1_1(helper_##name, ret, arg1); \
9
}
10
#define DEF_HELPER_1_2(name, ret, args) \
11
DEF_HELPER(name, ret, args) \
12
static inline void gen_helper_##name(TCGv ret, TCGv arg1, TCGv arg2) \
13
{ \
14
    tcg_gen_helper_1_2(helper_##name, ret, arg1, arg2); \
15
}
16
#else /* !GEN_HELPER */
17
#define DEF_HELPER_1_1 DEF_HELPER
18
#define DEF_HELPER_1_2 DEF_HELPER
19
#define HELPER(x) helper_##x
3 20
#endif
4 21

  
5
DEF_HELPER(clz, uint32_t, (uint32_t))
6
DEF_HELPER(sxtb16, uint32_t, (uint32_t))
7
DEF_HELPER(uxtb16, uint32_t, (uint32_t))
22
DEF_HELPER_1_1(clz, uint32_t, (uint32_t))
23
DEF_HELPER_1_1(sxtb16, uint32_t, (uint32_t))
24
DEF_HELPER_1_1(uxtb16, uint32_t, (uint32_t))
25

  
26
DEF_HELPER_1_2(add_setq, uint32_t, (uint32_t, uint32_t))
27
DEF_HELPER_1_2(add_saturate, uint32_t, (uint32_t, uint32_t))
28
DEF_HELPER_1_2(sub_saturate, uint32_t, (uint32_t, uint32_t))
29
DEF_HELPER_1_2(add_usaturate, uint32_t, (uint32_t, uint32_t))
30
DEF_HELPER_1_2(sub_usaturate, uint32_t, (uint32_t, uint32_t))
31
DEF_HELPER_1_1(double_saturate, uint32_t, (int32_t))
32

  
33
#undef DEF_HELPER
34
#undef DEF_HELPER_1_1
35
#undef DEF_HELPER_1_2
36
#undef GEN_HELPER
b/target-arm/op.c
425 425
    FORCE_RET();
426 426
}
427 427

  
428
/* misc */
429
#define SIGNBIT (uint32_t)0x80000000
430
/* saturating arithmetic  */
431
void OPPROTO op_addl_T0_T1_setq(void)
432
{
433
  uint32_t res;
434

  
435
  res = T0 + T1;
436
  if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT))
437
      env->QF = 1;
438

  
439
  T0 = res;
440
  FORCE_RET();
441
}
442

  
443
void OPPROTO op_addl_T0_T1_saturate(void)
444
{
445
  uint32_t res;
446

  
447
  res = T0 + T1;
448
  if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) {
449
      env->QF = 1;
450
      if (T0 & SIGNBIT)
451
          T0 = 0x80000000;
452
      else
453
          T0 = 0x7fffffff;
454
  }
455
  else
456
    T0 = res;
457

  
458
  FORCE_RET();
459
}
460

  
461
void OPPROTO op_subl_T0_T1_saturate(void)
462
{
463
  uint32_t res;
464

  
465
  res = T0 - T1;
466
  if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) {
467
      env->QF = 1;
468
      if (T0 & SIGNBIT)
469
          T0 = 0x80000000;
470
      else
471
          T0 = 0x7fffffff;
472
  }
473
  else
474
    T0 = res;
475

  
476
  FORCE_RET();
477
}
478

  
479
void OPPROTO op_double_T1_saturate(void)
480
{
481
  int32_t val;
482

  
483
  val = T1;
484
  if (val >= 0x40000000) {
485
      T1 = 0x7fffffff;
486
      env->QF = 1;
487
  } else if (val <= (int32_t)0xc0000000) {
488
      T1 = 0x80000000;
489
      env->QF = 1;
490
  } else {
491
      T1 = val << 1;
492
  }
493
  FORCE_RET();
494
}
495

  
496
/* Unsigned saturating arithmetic for NEON.  */
497
void OPPROTO op_addl_T0_T1_usaturate(void)
498
{
499
  uint32_t res;
500

  
501
  res = T0 + T1;
502
  if (res < T0) {
503
      env->QF = 1;
504
      T0 = 0xffffffff;
505
  } else {
506
      T0 = res;
507
  }
508

  
509
  FORCE_RET();
510
}
511

  
512
void OPPROTO op_subl_T0_T1_usaturate(void)
513
{
514
  uint32_t res;
515

  
516
  res = T0 - T1;
517
  if (res > T0) {
518
      env->QF = 1;
519
      T0 = 0;
520
  } else {
521
      T0 = res;
522
  }
523

  
524
  FORCE_RET();
525
}
526

  
527 428
/* exceptions */
528 429

  
529 430
void OPPROTO op_swi(void)
b/target-arm/op_helper.c
18 18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 19
 */
20 20
#include "exec.h"
21
#include "helpers.h"
21 22

  
22 23
void raise_exception(int tt)
23 24
{
......
303 304
    env = saved_env;
304 305
}
305 306
#endif
307

  
308
#define SIGNBIT (uint32_t)0x80000000
309
uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
310
{
311
    uint32_t res = a + b;
312
    if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
313
        env->QF = 1;
314
    return res;
315
}
316

  
317
uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b)
318
{
319
    uint32_t res = a + b;
320
    if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
321
        env->QF = 1;
322
        res = ~(((int32_t)a >> 31) ^ SIGNBIT);
323
    }
324
    return res;
325
}
326

  
327
uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b)
328
{
329
    uint32_t res = a - b;
330
    if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
331
        env->QF = 1;
332
        res = ~(((int32_t)a >> 31) ^ SIGNBIT);
333
    }
334
    return res;
335
}
336

  
337
uint32_t HELPER(double_saturate)(int32_t val)
338
{
339
    uint32_t res;
340
    if (val >= 0x40000000) {
341
        res = ~SIGNBIT;
342
        env->QF = 1;
343
    } else if (val <= (int32_t)0xc0000000) {
344
        res = SIGNBIT;
345
        env->QF = 1;
346
    } else {
347
        res = val << 1;
348
    }
349
    return res;
350
}
351

  
352
uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b)
353
{
354
    uint32_t res = a + b;
355
    if (res < a) {
356
        env->QF = 1;
357
        res = ~0;
358
    }
359
    return res;
360
}
361

  
362
uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b)
363
{
364
    uint32_t res = a - b;
365
    if (res > a) {
366
        env->QF = 1;
367
        res = 0;
368
    }
369
    return res;
370
}
371

  
b/target-arm/op_neon.h
9 9
/* Note that for NEON an "l" prefix means it is a wide operation, unlike
10 10
   scalar arm ops where it means a word size operation.  */
11 11

  
12
#define SIGNBIT (uint32_t)0x80000000
12 13
/* ??? NEON ops should probably have their own float status.  */
13 14
#define NFS &env->vfp.fp_status
14 15
#define NEON_OP(name) void OPPROTO op_neon_##name (void)
b/target-arm/translate.c
29 29
#include "exec-all.h"
30 30
#include "disas.h"
31 31
#include "tcg-op.h"
32

  
33
#define GEN_HELPER 1
32 34
#include "helpers.h"
33 35

  
34 36
#define ENABLE_ARCH_5J    0
......
200 202
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
201 203
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
202 204

  
203
#define HELPER_ADDR(x) helper_##x
204

  
205
#define gen_sxtb16(var) tcg_gen_helper_1_1(HELPER_ADDR(sxtb16), var, var)
206
#define gen_uxtb16(var) tcg_gen_helper_1_1(HELPER_ADDR(uxtb16), var, var)
205
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
206
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
207 207

  
208
#define gen_op_clz_T0(var) \
209
    tcg_gen_helper_1_1(HELPER_ADDR(clz), cpu_T[0], cpu_T[0])
208
#define gen_op_addl_T0_T1_setq() \
209
    gen_helper_add_setq(cpu_T[0], cpu_T[0], cpu_T[1])
210
#define gen_op_addl_T0_T1_saturate() \
211
    gen_helper_add_saturate(cpu_T[0], cpu_T[0], cpu_T[1])
212
#define gen_op_subl_T0_T1_saturate() \
213
    gen_helper_sub_saturate(cpu_T[0], cpu_T[0], cpu_T[1])
214
#define gen_op_addl_T0_T1_usaturate() \
215
    gen_helper_add_usaturate(cpu_T[0], cpu_T[0], cpu_T[1])
216
#define gen_op_subl_T0_T1_usaturate() \
217
    gen_helper_sub_usaturate(cpu_T[0], cpu_T[0], cpu_T[1])
210 218

  
211 219
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
212 220
    tmp = (t0 ^ t1) & 0x8000;
......
4526 4534
                            switch (size) {
4527 4535
                            case 0: gen_op_neon_clz_u8(); break;
4528 4536
                            case 1: gen_op_neon_clz_u16(); break;
4529
                            case 2: gen_op_clz_T0(); break;
4537
                            case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
4530 4538
                            default: return 1;
4531 4539
                            }
4532 4540
                            break;
......
5021 5029
            } else if (op1 == 3) {
5022 5030
                /* clz */
5023 5031
                rd = (insn >> 12) & 0xf;
5024
                gen_movl_T0_reg(s, rm);
5025
                gen_op_clz_T0();
5026
                gen_movl_reg_T0(s, rd);
5032
                tmp = load_reg(s, rm);
5033
                gen_helper_clz(tmp, tmp);
5034
                store_reg(s, rd, tmp);
5027 5035
            } else {
5028 5036
                goto illegal_op;
5029 5037
            }
......
5055 5063
            gen_movl_T0_reg(s, rm);
5056 5064
            gen_movl_T1_reg(s, rn);
5057 5065
            if (op1 & 2)
5058
                gen_op_double_T1_saturate();
5066
                gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
5059 5067
            if (op1 & 1)
5060 5068
                gen_op_subl_T0_T1_saturate();
5061 5069
            else
......
6317 6325
                gen_movl_T0_reg(s, rm);
6318 6326
                gen_movl_T1_reg(s, rn);
6319 6327
                if (op & 2)
6320
                    gen_op_double_T1_saturate();
6328
                    gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
6321 6329
                if (op & 1)
6322 6330
                    gen_op_subl_T0_T1_saturate();
6323 6331
                else
......
6342 6350
                    gen_op_sel_T0_T1();
6343 6351
                    break;
6344 6352
                case 0x18: /* clz */
6345
                    gen_op_clz_T0();
6353
                    gen_helper_clz(cpu_T[0], cpu_T[0]);
6346 6354
                    break;
6347 6355
                default:
6348 6356
                    goto illegal_op;

Also available in: Unified diff