Commit 2bece2c8 authored by Richard Henderson's avatar Richard Henderson Committed by Aurelien Jarno
Browse files

tcg: Optionally sign-extend 32-bit arguments for 64-bit hosts.



Some hosts (amd64, ia64) have an ABI that ignores the high bits
of the 64-bit register when passing 32-bit arguments.  Others
require the value to be properly sign-extended for the type.
I.e. "int32_t" must be sign-extended and "uint32_t" must be
zero-extended to 64-bits.

To effect this, extend the "sizemask" parameter to tcg_gen_callN
to include the signedness of the type of each parameter.  If the
tcg target requires it, extend each 32-bit argument into a 64-bit
temp and pass that to the function call.

This ABI feature is required by sparc64, ppc64 and s390x.

Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarAurelien Jarno <aurelien@aurel32.net>
parent d2c5efd8
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -81,9 +81,29 @@
#define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))

#define dh_is_signed_void 0
#define dh_is_signed_i32 0
#define dh_is_signed_s32 1
#define dh_is_signed_i64 0
#define dh_is_signed_s64 1
#define dh_is_signed_f32 0
#define dh_is_signed_f64 0
#define dh_is_signed_tl  0
#define dh_is_signed_int 1
/* ??? This is highly specific to the host cpu.  There are even special
   extension instructions that may be required, e.g. ia64's addp4.  But
   for now we don't support any 64-bit targets with 32-bit pointers.  */
#define dh_is_signed_ptr 0
#define dh_is_signed_env dh_is_signed_ptr
#define dh_is_signed(t) dh_is_signed_##t

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

#define dh_arg(t, n) \
  args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
  sizemask |= dh_is_64bit(t) << n
  dh_sizemask(t, n)

#define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)

@@ -138,8 +158,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
{ \
  TCGArg args[1]; \
  int sizemask; \
  sizemask = dh_is_64bit(ret); \
  int sizemask = 0; \
  dh_sizemask(ret, 0); \
  dh_arg(t1, 1); \
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
}
@@ -149,8 +169,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1
    dh_arg_decl(t2, 2)) \
{ \
  TCGArg args[2]; \
  int sizemask; \
  sizemask = dh_is_64bit(ret); \
  int sizemask = 0; \
  dh_sizemask(ret, 0); \
  dh_arg(t1, 1); \
  dh_arg(t2, 2); \
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
@@ -161,8 +181,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
{ \
  TCGArg args[3]; \
  int sizemask; \
  sizemask = dh_is_64bit(ret); \
  int sizemask = 0; \
  dh_sizemask(ret, 0); \
  dh_arg(t1, 1); \
  dh_arg(t2, 2); \
  dh_arg(t3, 3); \
@@ -174,8 +194,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
{ \
  TCGArg args[4]; \
  int sizemask; \
  sizemask = dh_is_64bit(ret); \
  int sizemask = 0; \
  dh_sizemask(ret, 0); \
  dh_arg(t1, 1); \
  dh_arg(t2, 2); \
  dh_arg(t3, 3); \
+3 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@
#define dh_ctype_Reg Reg *
#define dh_ctype_XMMReg XMMReg *
#define dh_ctype_MMXReg MMXReg *
#define dh_is_signed_Reg dh_is_signed_ptr
#define dh_is_signed_XMMReg dh_is_signed_ptr
#define dh_is_signed_MMXReg dh_is_signed_ptr

DEF_HELPER_2(glue(psrlw, SUFFIX), void, Reg, Reg)
DEF_HELPER_2(glue(psraw, SUFFIX), void, Reg, Reg)
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ DEF_HELPER_3(fsel, i64, i64, i64, i64)

#define dh_alias_avr ptr
#define dh_ctype_avr ppc_avr_t *
#define dh_is_signed_avr dh_is_signed_ptr

DEF_HELPER_3(vaddubm, void, avr, avr, avr)
DEF_HELPER_3(vadduhm, void, avr, avr, avr)
+1 −0
Original line number Diff line number Diff line
@@ -106,3 +106,4 @@ enum {
#define TCG_AREG0 TCG_REG_R27

#define TCG_TARGET_HAS_GUEST_BASE
#define TCG_TARGET_EXTEND_ARGS 1
+2 −0
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ enum {
#define TCG_TARGET_STACK_ALIGN		8
#define TCG_TARGET_CALL_STACK_OFFSET	0

#define TCG_TARGET_EXTEND_ARGS 1

enum {
    /* Note: must be synced with dyngen-exec.h */
    TCG_AREG0 = TCG_REG_R10,
Loading