diff options
author | Richard Henderson | 2014-04-30 20:39:20 +0200 |
---|---|---|
committer | Richard Henderson | 2014-06-23 16:31:58 +0200 |
commit | 796f1a689d935e74c7f8a1967ee2cf432e556800 (patch) | |
tree | a71e4759fc2d7c41650eded96ffb002ae5e10453 /tcg | |
parent | tcg-ppc64: Fix sub2 implementation (diff) | |
download | qemu-796f1a689d935e74c7f8a1967ee2cf432e556800.tar.gz qemu-796f1a689d935e74c7f8a1967ee2cf432e556800.tar.xz qemu-796f1a689d935e74c7f8a1967ee2cf432e556800.zip |
tcg-ppc64: Begin merging ppc32 with ppc64
Just enough to compile, assuming you edit config-host.mak manually.
It will still abort at runtime, due to missing brcond2, setcond2, mulu2.
Tested-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/ppc64/tcg-target.c | 104 | ||||
-rw-r--r-- | tcg/ppc64/tcg-target.h | 20 |
2 files changed, 81 insertions, 43 deletions
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 22cfa1e35b..8152ccfcbe 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -514,9 +514,9 @@ static const uint32_t tcg_to_isel[] = { [TCG_COND_GTU] = ISEL | BC_(7, CR_GT), }; -static inline void tcg_out_mov(TCGContext *s, TCGType type, - TCGReg ret, TCGReg arg) +static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { + tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); if (ret != arg) { tcg_out32(s, OR | SAB(arg, ret, arg)); } @@ -566,13 +566,14 @@ static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg) static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, tcg_target_long arg) { + tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); if (type == TCG_TYPE_I32 || arg == (int32_t)arg) { tcg_out_movi32(s, ret, arg); } else if (arg == (uint32_t)arg && !(arg & 0x8000)) { tcg_out32(s, ADDI | TAI(ret, 0, arg)); tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16)); } else { - int32_t high = arg >> 32; + int32_t high = arg >> 31 >> 1; tcg_out_movi32(s, ret, high); if (high) { tcg_out_shli64(s, ret, ret, 32); @@ -1984,7 +1985,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, args[3], args[4], const_args[2]); break; +#if TCG_TARGET_REG_BITS == 64 case INDEX_op_add2_i64: +#else + case INDEX_op_add2_i32: +#endif /* Note that the CA bit is defined based on the word size of the environment. So in 64-bit mode it's always carry-out of bit 63. The fallback code using deposit works just as well for 32-bit. */ @@ -2007,7 +2012,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, } break; +#if TCG_TARGET_REG_BITS == 64 case INDEX_op_sub2_i64: +#else + case INDEX_op_sub2_i32: +#endif a0 = args[0], a1 = args[1]; if (a0 == args[5] || (!const_args[3] && a0 == args[3])) { a0 = TCG_REG_R0; @@ -2054,21 +2063,10 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_ld16u_i32, { "r", "r" } }, { INDEX_op_ld16s_i32, { "r", "r" } }, { INDEX_op_ld_i32, { "r", "r" } }, - { INDEX_op_ld_i64, { "r", "r" } }, + { INDEX_op_st8_i32, { "r", "r" } }, - { INDEX_op_st8_i64, { "r", "r" } }, { INDEX_op_st16_i32, { "r", "r" } }, - { INDEX_op_st16_i64, { "r", "r" } }, { INDEX_op_st_i32, { "r", "r" } }, - { INDEX_op_st_i64, { "r", "r" } }, - { INDEX_op_st32_i64, { "r", "r" } }, - - { INDEX_op_ld8u_i64, { "r", "r" } }, - { INDEX_op_ld8s_i64, { "r", "r" } }, - { INDEX_op_ld16u_i64, { "r", "r" } }, - { INDEX_op_ld16s_i64, { "r", "r" } }, - { INDEX_op_ld32u_i64, { "r", "r" } }, - { INDEX_op_ld32s_i64, { "r", "r" } }, { INDEX_op_add_i32, { "r", "r", "ri" } }, { INDEX_op_mul_i32, { "r", "r", "rI" } }, @@ -2090,11 +2088,32 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_rotl_i32, { "r", "r", "ri" } }, { INDEX_op_rotr_i32, { "r", "r", "ri" } }, - { INDEX_op_brcond_i32, { "r", "ri" } }, - { INDEX_op_brcond_i64, { "r", "ri" } }, - { INDEX_op_neg_i32, { "r", "r" } }, { INDEX_op_not_i32, { "r", "r" } }, + { INDEX_op_ext8s_i32, { "r", "r" } }, + { INDEX_op_ext16s_i32, { "r", "r" } }, + { INDEX_op_bswap16_i32, { "r", "r" } }, + { INDEX_op_bswap32_i32, { "r", "r" } }, + + { INDEX_op_brcond_i32, { "r", "ri" } }, + { INDEX_op_setcond_i32, { "r", "r", "ri" } }, + { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } }, + + { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, + +#if TCG_TARGET_REG_BITS == 64 + { INDEX_op_ld8u_i64, { "r", "r" } }, + { INDEX_op_ld8s_i64, { "r", "r" } }, + { INDEX_op_ld16u_i64, { "r", "r" } }, + { INDEX_op_ld16s_i64, { "r", "r" } }, + { INDEX_op_ld32u_i64, { "r", "r" } }, + { INDEX_op_ld32s_i64, { "r", "r" } }, + { INDEX_op_ld_i64, { "r", "r" } }, + + { INDEX_op_st8_i64, { "r", "r" } }, + { INDEX_op_st16_i64, { "r", "r" } }, + { INDEX_op_st32_i64, { "r", "r" } }, + { INDEX_op_st_i64, { "r", "r" } }, { INDEX_op_add_i64, { "r", "r", "rT" } }, { INDEX_op_sub_i64, { "r", "rI", "rT" } }, @@ -2119,36 +2138,47 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_neg_i64, { "r", "r" } }, { INDEX_op_not_i64, { "r", "r" } }, - - { INDEX_op_qemu_ld_i32, { "r", "L" } }, - { INDEX_op_qemu_ld_i64, { "r", "L" } }, - { INDEX_op_qemu_st_i32, { "S", "S" } }, - { INDEX_op_qemu_st_i64, { "S", "S" } }, - - { INDEX_op_ext8s_i32, { "r", "r" } }, - { INDEX_op_ext16s_i32, { "r", "r" } }, { INDEX_op_ext8s_i64, { "r", "r" } }, { INDEX_op_ext16s_i64, { "r", "r" } }, { INDEX_op_ext32s_i64, { "r", "r" } }, - - { INDEX_op_setcond_i32, { "r", "r", "ri" } }, - { INDEX_op_setcond_i64, { "r", "r", "ri" } }, - { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } }, - { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } }, - - { INDEX_op_bswap16_i32, { "r", "r" } }, { INDEX_op_bswap16_i64, { "r", "r" } }, - { INDEX_op_bswap32_i32, { "r", "r" } }, { INDEX_op_bswap32_i64, { "r", "r" } }, { INDEX_op_bswap64_i64, { "r", "r" } }, - { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, + { INDEX_op_brcond_i64, { "r", "ri" } }, + { INDEX_op_setcond_i64, { "r", "r", "ri" } }, + { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } }, + { INDEX_op_deposit_i64, { "r", "0", "rZ" } }, - { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } }, - { INDEX_op_sub2_i64, { "r", "r", "rI", "rZM", "r", "r" } }, { INDEX_op_mulsh_i64, { "r", "r", "r" } }, { INDEX_op_muluh_i64, { "r", "r", "r" } }, +#endif + +#if TCG_TARGET_REG_BITS == 64 + { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } }, + { INDEX_op_sub2_i64, { "r", "r", "rI", "rZM", "r", "r" } }, +#else + { INDEX_op_add2_i32, { "r", "r", "r", "r", "rI", "rZM" } }, + { INDEX_op_sub2_i32, { "r", "r", "rI", "rZM", "r", "r" } }, +#endif + +#if TCG_TARGET_REG_BITS == 64 + { INDEX_op_qemu_ld_i32, { "r", "L" } }, + { INDEX_op_qemu_st_i32, { "S", "S" } }, + { INDEX_op_qemu_ld_i64, { "r", "L" } }, + { INDEX_op_qemu_st_i64, { "S", "S" } }, +#elif TARGET_LONG_BITS == 32 + { INDEX_op_qemu_ld_i32, { "r", "L" } }, + { INDEX_op_qemu_st_i32, { "S", "S" } }, + { INDEX_op_qemu_ld_i64, { "r", "r", "L" } }, + { INDEX_op_qemu_st_i64, { "S", "S", "S" } }, +#else + { INDEX_op_qemu_ld_i32, { "r", "L", "L" } }, + { INDEX_op_qemu_st_i32, { "S", "S", "S" } }, + { INDEX_op_qemu_ld_i64, { "r", "r", "L", "L" } }, + { INDEX_op_qemu_st_i64, { "S", "S", "S", "S" } }, +#endif { -1 }, }; diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index d3a1b5311d..726635f01e 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -24,6 +24,12 @@ #ifndef TCG_TARGET_PPC64 #define TCG_TARGET_PPC64 1 +#ifdef _ARCH_PPC64 +# define TCG_TARGET_REG_BITS 64 +#else +# define TCG_TARGET_REG_BITS 32 +#endif + #define TCG_TARGET_NB_REGS 32 #define TCG_TARGET_INSN_UNIT_SIZE 4 @@ -44,9 +50,6 @@ typedef enum { /* optional instructions automatically implemented */ #define TCG_TARGET_HAS_ext8u_i32 0 /* andi */ #define TCG_TARGET_HAS_ext16u_i32 0 -#define TCG_TARGET_HAS_ext8u_i64 0 -#define TCG_TARGET_HAS_ext16u_i64 0 -#define TCG_TARGET_HAS_ext32u_i64 0 /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 @@ -65,20 +68,24 @@ typedef enum { #define TCG_TARGET_HAS_nor_i32 1 #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_i32 1 -#define TCG_TARGET_HAS_add2_i32 0 -#define TCG_TARGET_HAS_sub2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0 #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 -#define TCG_TARGET_HAS_trunc_shr_i32 0 +#if TCG_TARGET_REG_BITS == 64 +#define TCG_TARGET_HAS_add2_i32 0 +#define TCG_TARGET_HAS_sub2_i32 0 +#define TCG_TARGET_HAS_trunc_shr_i32 0 #define TCG_TARGET_HAS_div_i64 1 #define TCG_TARGET_HAS_rem_i64 0 #define TCG_TARGET_HAS_rot_i64 1 #define TCG_TARGET_HAS_ext8s_i64 1 #define TCG_TARGET_HAS_ext16s_i64 1 #define TCG_TARGET_HAS_ext32s_i64 1 +#define TCG_TARGET_HAS_ext8u_i64 0 +#define TCG_TARGET_HAS_ext16u_i64 0 +#define TCG_TARGET_HAS_ext32u_i64 0 #define TCG_TARGET_HAS_bswap16_i64 1 #define TCG_TARGET_HAS_bswap32_i64 1 #define TCG_TARGET_HAS_bswap64_i64 1 @@ -97,5 +104,6 @@ typedef enum { #define TCG_TARGET_HAS_muls2_i64 0 #define TCG_TARGET_HAS_muluh_i64 1 #define TCG_TARGET_HAS_mulsh_i64 1 +#endif #endif |