Revision 2bece2c8

b/def-helper.h
81 81
#define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
82 82
#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
83 83

  
84
#define dh_is_signed_void 0
85
#define dh_is_signed_i32 0
86
#define dh_is_signed_s32 1
87
#define dh_is_signed_i64 0
88
#define dh_is_signed_s64 1
89
#define dh_is_signed_f32 0
90
#define dh_is_signed_f64 0
91
#define dh_is_signed_tl  0
92
#define dh_is_signed_int 1
93
/* ??? This is highly specific to the host cpu.  There are even special
94
   extension instructions that may be required, e.g. ia64's addp4.  But
95
   for now we don't support any 64-bit targets with 32-bit pointers.  */
96
#define dh_is_signed_ptr 0
97
#define dh_is_signed_env dh_is_signed_ptr
98
#define dh_is_signed(t) dh_is_signed_##t
99

  
100
#define dh_sizemask(t, n) \
101
  sizemask |= dh_is_64bit(t) << (n*2); \
102
  sizemask |= dh_is_signed(t) << (n*2+1)
103

  
84 104
#define dh_arg(t, n) \
85 105
  args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
86
  sizemask |= dh_is_64bit(t) << n
106
  dh_sizemask(t, n)
87 107

  
88 108
#define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)
89 109

  
......
138 158
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
139 159
{ \
140 160
  TCGArg args[1]; \
141
  int sizemask; \
142
  sizemask = dh_is_64bit(ret); \
161
  int sizemask = 0; \
162
  dh_sizemask(ret, 0); \
143 163
  dh_arg(t1, 1); \
144 164
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
145 165
}
......
149 169
    dh_arg_decl(t2, 2)) \
150 170
{ \
151 171
  TCGArg args[2]; \
152
  int sizemask; \
153
  sizemask = dh_is_64bit(ret); \
172
  int sizemask = 0; \
173
  dh_sizemask(ret, 0); \
154 174
  dh_arg(t1, 1); \
155 175
  dh_arg(t2, 2); \
156 176
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
......
161 181
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
162 182
{ \
163 183
  TCGArg args[3]; \
164
  int sizemask; \
165
  sizemask = dh_is_64bit(ret); \
184
  int sizemask = 0; \
185
  dh_sizemask(ret, 0); \
166 186
  dh_arg(t1, 1); \
167 187
  dh_arg(t2, 2); \
168 188
  dh_arg(t3, 3); \
......
174 194
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
175 195
{ \
176 196
  TCGArg args[4]; \
177
  int sizemask; \
178
  sizemask = dh_is_64bit(ret); \
197
  int sizemask = 0; \
198
  dh_sizemask(ret, 0); \
179 199
  dh_arg(t1, 1); \
180 200
  dh_arg(t2, 2); \
181 201
  dh_arg(t3, 3); \
b/target-i386/ops_sse_header.h
30 30
#define dh_ctype_Reg Reg *
31 31
#define dh_ctype_XMMReg XMMReg *
32 32
#define dh_ctype_MMXReg MMXReg *
33
#define dh_is_signed_Reg dh_is_signed_ptr
34
#define dh_is_signed_XMMReg dh_is_signed_ptr
35
#define dh_is_signed_MMXReg dh_is_signed_ptr
33 36

  
34 37
DEF_HELPER_2(glue(psrlw, SUFFIX), void, Reg, Reg)
35 38
DEF_HELPER_2(glue(psraw, SUFFIX), void, Reg, Reg)
b/target-ppc/helper.h
95 95

  
96 96
#define dh_alias_avr ptr
97 97
#define dh_ctype_avr ppc_avr_t *
98
#define dh_is_signed_avr dh_is_signed_ptr
98 99

  
99 100
DEF_HELPER_3(vaddubm, void, avr, avr, avr)
100 101
DEF_HELPER_3(vadduhm, void, avr, avr, avr)
b/tcg/ppc64/tcg-target.h
106 106
#define TCG_AREG0 TCG_REG_R27
107 107

  
108 108
#define TCG_TARGET_HAS_GUEST_BASE
109
#define TCG_TARGET_EXTEND_ARGS 1
b/tcg/s390/tcg-target.h
87 87
#define TCG_TARGET_STACK_ALIGN		8
88 88
#define TCG_TARGET_CALL_STACK_OFFSET	0
89 89

  
90
#define TCG_TARGET_EXTEND_ARGS 1
91

  
90 92
enum {
91 93
    /* Note: must be synced with dyngen-exec.h */
92 94
    TCG_AREG0 = TCG_REG_R10,
b/tcg/sparc/tcg-target.h
87 87
#define TCG_TARGET_STACK_ALIGN 8
88 88
#endif
89 89

  
90
#ifdef __arch64__
91
#define TCG_TARGET_EXTEND_ARGS 1
92
#endif
93

  
90 94
/* optional instructions */
91 95
#define TCG_TARGET_HAS_div_i32
92 96
// #define TCG_TARGET_HAS_rot_i32
b/tcg/tcg-op.h
353 353
    tcg_gen_op2i_i32(INDEX_op_movi_i32, ret, arg);
354 354
}
355 355

  
356
/* A version of dh_sizemask from def-helper.h that doesn't rely on
357
   preprocessor magic.  */
358
static inline int tcg_gen_sizemask(int n, int is_64bit, int is_signed)
359
{
360
    return (is_64bit << n*2) | (is_signed << (n*2 + 1));
361
}
362

  
356 363
/* helper calls */
357 364
static inline void tcg_gen_helperN(void *func, int flags, int sizemask,
358 365
                                   TCGArg ret, int nargs, TCGArg *args)
......
369 376
   and pure, hence the call to tcg_gen_callN() with TCG_CALL_CONST |
370 377
   TCG_CALL_PURE. This may need to be adjusted if these functions
371 378
   start to be used with other helpers. */
372
static inline void tcg_gen_helper32(void *func, TCGv_i32 ret,
379
static inline void tcg_gen_helper32(void *func, int sizemask, TCGv_i32 ret,
373 380
                                    TCGv_i32 a, TCGv_i32 b)
374 381
{
375 382
    TCGv_ptr fn;
......
377 384
    fn = tcg_const_ptr((tcg_target_long)func);
378 385
    args[0] = GET_TCGV_I32(a);
379 386
    args[1] = GET_TCGV_I32(b);
380
    tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE,
381
                  0, GET_TCGV_I32(ret), 2, args);
387
    tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE, sizemask,
388
                  GET_TCGV_I32(ret), 2, args);
382 389
    tcg_temp_free_ptr(fn);
383 390
}
384 391

  
385
static inline void tcg_gen_helper64(void *func, TCGv_i64 ret,
392
static inline void tcg_gen_helper64(void *func, int sizemask, TCGv_i64 ret,
386 393
                                    TCGv_i64 a, TCGv_i64 b)
387 394
{
388 395
    TCGv_ptr fn;
......
390 397
    fn = tcg_const_ptr((tcg_target_long)func);
391 398
    args[0] = GET_TCGV_I64(a);
392 399
    args[1] = GET_TCGV_I64(b);
393
    tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE,
394
                  7, GET_TCGV_I64(ret), 2, args);
400
    tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE, sizemask,
401
                  GET_TCGV_I64(ret), 2, args);
395 402
    tcg_temp_free_ptr(fn);
396 403
}
397 404

  
......
692 699
#else
693 700
static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
694 701
{
695
    tcg_gen_helper32(tcg_helper_div_i32, ret, arg1, arg2);
702
    int sizemask = 0;
703
    /* Return value and both arguments are 32-bit and signed.  */
704
    sizemask |= tcg_gen_sizemask(0, 0, 1);
705
    sizemask |= tcg_gen_sizemask(1, 0, 1);
706
    sizemask |= tcg_gen_sizemask(2, 0, 1);
707

  
708
    tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2);
696 709
}
697 710

  
698 711
static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
699 712
{
700
    tcg_gen_helper32(tcg_helper_rem_i32, ret, arg1, arg2);
713
    int sizemask = 0;
714
    /* Return value and both arguments are 32-bit and signed.  */
715
    sizemask |= tcg_gen_sizemask(0, 0, 1);
716
    sizemask |= tcg_gen_sizemask(1, 0, 1);
717
    sizemask |= tcg_gen_sizemask(2, 0, 1);
718

  
719
    tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2);
701 720
}
702 721

  
703 722
static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
704 723
{
705
    tcg_gen_helper32(tcg_helper_divu_i32, ret, arg1, arg2);
724
    int sizemask = 0;
725
    /* Return value and both arguments are 32-bit and unsigned.  */
726
    sizemask |= tcg_gen_sizemask(0, 0, 0);
727
    sizemask |= tcg_gen_sizemask(1, 0, 0);
728
    sizemask |= tcg_gen_sizemask(2, 0, 0);
729

  
730
    tcg_gen_helper32(tcg_helper_divu_i32, ret, arg1, arg2, 0);
706 731
}
707 732

  
708 733
static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
709 734
{
710
    tcg_gen_helper32(tcg_helper_remu_i32, ret, arg1, arg2);
735
    int sizemask = 0;
736
    /* Return value and both arguments are 32-bit and unsigned.  */
737
    sizemask |= tcg_gen_sizemask(0, 0, 0);
738
    sizemask |= tcg_gen_sizemask(1, 0, 0);
739
    sizemask |= tcg_gen_sizemask(2, 0, 0);
740

  
741
    tcg_gen_helper32(tcg_helper_remu_i32, ret, arg1, arg2, 0);
711 742
}
712 743
#endif
713 744

  
......
867 898
   specific code (x86) */
868 899
static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
869 900
{
870
    tcg_gen_helper64(tcg_helper_shl_i64, ret, arg1, arg2);
901
    int sizemask = 0;
902
    /* Return value and both arguments are 64-bit and signed.  */
903
    sizemask |= tcg_gen_sizemask(0, 1, 1);
904
    sizemask |= tcg_gen_sizemask(1, 1, 1);
905
    sizemask |= tcg_gen_sizemask(2, 1, 1);
906

  
907
    tcg_gen_helper64(tcg_helper_shl_i64, sizemask, ret, arg1, arg2);
871 908
}
872 909

  
873 910
static inline void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
......
877 914

  
878 915
static inline void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
879 916
{
880
    tcg_gen_helper64(tcg_helper_shr_i64, ret, arg1, arg2);
917
    int sizemask = 0;
918
    /* Return value and both arguments are 64-bit and signed.  */
919
    sizemask |= tcg_gen_sizemask(0, 1, 1);
920
    sizemask |= tcg_gen_sizemask(1, 1, 1);
921
    sizemask |= tcg_gen_sizemask(2, 1, 1);
922

  
923
    tcg_gen_helper64(tcg_helper_shr_i64, sizemask, ret, arg1, arg2);
881 924
}
882 925

  
883 926
static inline void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
......
887 930

  
888 931
static inline void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
889 932
{
890
    tcg_gen_helper64(tcg_helper_sar_i64, ret, arg1, arg2);
933
    int sizemask = 0;
934
    /* Return value and both arguments are 64-bit and signed.  */
935
    sizemask |= tcg_gen_sizemask(0, 1, 1);
936
    sizemask |= tcg_gen_sizemask(1, 1, 1);
937
    sizemask |= tcg_gen_sizemask(2, 1, 1);
938

  
939
    tcg_gen_helper64(tcg_helper_sar_i64, sizemask, ret, arg1, arg2);
891 940
}
892 941

  
893 942
static inline void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
......
935 984

  
936 985
static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
937 986
{
938
    tcg_gen_helper64(tcg_helper_div_i64, ret, arg1, arg2);
987
    int sizemask = 0;
988
    /* Return value and both arguments are 64-bit and signed.  */
989
    sizemask |= tcg_gen_sizemask(0, 1, 1);
990
    sizemask |= tcg_gen_sizemask(1, 1, 1);
991
    sizemask |= tcg_gen_sizemask(2, 1, 1);
992

  
993
    tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
939 994
}
940 995

  
941 996
static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
942 997
{
943
    tcg_gen_helper64(tcg_helper_rem_i64, ret, arg1, arg2);
998
    int sizemask = 0;
999
    /* Return value and both arguments are 64-bit and signed.  */
1000
    sizemask |= tcg_gen_sizemask(0, 1, 1);
1001
    sizemask |= tcg_gen_sizemask(1, 1, 1);
1002
    sizemask |= tcg_gen_sizemask(2, 1, 1);
1003

  
1004
    tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
944 1005
}
945 1006

  
946 1007
static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
947 1008
{
948
    tcg_gen_helper64(tcg_helper_divu_i64, ret, arg1, arg2);
1009
    int sizemask = 0;
1010
    /* Return value and both arguments are 64-bit and unsigned.  */
1011
    sizemask |= tcg_gen_sizemask(0, 1, 0);
1012
    sizemask |= tcg_gen_sizemask(1, 1, 0);
1013
    sizemask |= tcg_gen_sizemask(2, 1, 0);
1014

  
1015
    tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
949 1016
}
950 1017

  
951 1018
static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
952 1019
{
953
    tcg_gen_helper64(tcg_helper_remu_i64, ret, arg1, arg2);
1020
    int sizemask = 0;
1021
    /* Return value and both arguments are 64-bit and unsigned.  */
1022
    sizemask |= tcg_gen_sizemask(0, 1, 0);
1023
    sizemask |= tcg_gen_sizemask(1, 1, 0);
1024
    sizemask |= tcg_gen_sizemask(2, 1, 0);
1025

  
1026
    tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
954 1027
}
955 1028

  
956 1029
#else
......
1212 1285
#else
1213 1286
static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1214 1287
{
1215
    tcg_gen_helper64(tcg_helper_div_i64, ret, arg1, arg2);
1288
    int sizemask = 0;
1289
    /* Return value and both arguments are 64-bit and signed.  */
1290
    sizemask |= tcg_gen_sizemask(0, 1, 1);
1291
    sizemask |= tcg_gen_sizemask(1, 1, 1);
1292
    sizemask |= tcg_gen_sizemask(2, 1, 1);
1293

  
1294
    tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
1216 1295
}
1217 1296

  
1218 1297
static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1219 1298
{
1220
    tcg_gen_helper64(tcg_helper_rem_i64, ret, arg1, arg2);
1299
    int sizemask = 0;
1300
    /* Return value and both arguments are 64-bit and signed.  */
1301
    sizemask |= tcg_gen_sizemask(0, 1, 1);
1302
    sizemask |= tcg_gen_sizemask(1, 1, 1);
1303
    sizemask |= tcg_gen_sizemask(2, 1, 1);
1304

  
1305
    tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
1221 1306
}
1222 1307

  
1223 1308
static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1224 1309
{
1225
    tcg_gen_helper64(tcg_helper_divu_i64, ret, arg1, arg2);
1310
    int sizemask = 0;
1311
    /* Return value and both arguments are 64-bit and unsigned.  */
1312
    sizemask |= tcg_gen_sizemask(0, 1, 0);
1313
    sizemask |= tcg_gen_sizemask(1, 1, 0);
1314
    sizemask |= tcg_gen_sizemask(2, 1, 0);
1315

  
1316
    tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
1226 1317
}
1227 1318

  
1228 1319
static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1229 1320
{
1230
    tcg_gen_helper64(tcg_helper_remu_i64, ret, arg1, arg2);
1321
    int sizemask = 0;
1322
    /* Return value and both arguments are 64-bit and unsigned.  */
1323
    sizemask |= tcg_gen_sizemask(0, 1, 0);
1324
    sizemask |= tcg_gen_sizemask(1, 1, 0);
1325
    sizemask |= tcg_gen_sizemask(2, 1, 0);
1326

  
1327
    tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
1231 1328
}
1232 1329
#endif
1233 1330

  
b/tcg/tcg.c
560 560
    int real_args;
561 561
    int nb_rets;
562 562
    TCGArg *nparam;
563

  
564
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
565
    for (i = 0; i < nargs; ++i) {
566
        int is_64bit = sizemask & (1 << (i+1)*2);
567
        int is_signed = sizemask & (2 << (i+1)*2);
568
        if (!is_64bit) {
569
            TCGv_i64 temp = tcg_temp_new_i64();
570
            TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
571
            if (is_signed) {
572
                tcg_gen_ext32s_i64(temp, orig);
573
            } else {
574
                tcg_gen_ext32u_i64(temp, orig);
575
            }
576
            args[i] = GET_TCGV_I64(temp);
577
        }
578
    }
579
#endif /* TCG_TARGET_EXTEND_ARGS */
580

  
563 581
    *gen_opc_ptr++ = INDEX_op_call;
564 582
    nparam = gen_opparam_ptr++;
565 583
#ifdef TCG_TARGET_I386
......
588 606
    real_args = 0;
589 607
    for (i = 0; i < nargs; i++) {
590 608
#if TCG_TARGET_REG_BITS < 64
591
        if (sizemask & (2 << i)) {
609
        int is_64bit = sizemask & (1 << (i+1)*2);
610
        if (is_64bit) {
592 611
#ifdef TCG_TARGET_I386
593 612
            /* REGPARM case: if the third parameter is 64 bit, it is
594 613
               allocated on the stack */
......
622 641
            *gen_opparam_ptr++ = args[i] + 1;
623 642
#endif
624 643
            real_args += 2;
625
        } else
626
#endif
627
        {
628
            *gen_opparam_ptr++ = args[i];
629
            real_args++;
644
            continue;
630 645
        }
646
#endif /* TCG_TARGET_REG_BITS < 64 */
647

  
648
        *gen_opparam_ptr++ = args[i];
649
        real_args++;
631 650
    }
632 651
    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
633 652

  
......
637 656

  
638 657
    /* total parameters, needed to go backward in the instruction stream */
639 658
    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
659

  
660
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
661
    for (i = 0; i < nargs; ++i) {
662
        int is_64bit = sizemask & (1 << (i+1)*2);
663
        if (!is_64bit) {
664
            TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
665
            tcg_temp_free_i64(temp);
666
        }
667
    }
668
#endif /* TCG_TARGET_EXTEND_ARGS */
640 669
}
641 670

  
642 671
#if TCG_TARGET_REG_BITS == 32

Also available in: Unified diff