Loading tcg/aarch64/tcg-target.c +34 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ static inline void patch_reloc(uint8_t *code_ptr, int type, #define TCG_CT_CONST_IS32 0x100 #define TCG_CT_CONST_AIMM 0x200 #define TCG_CT_CONST_LIMM 0x400 #define TCG_CT_CONST_ZERO 0x800 /* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, Loading Loading @@ -146,6 +147,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, case 'L': /* Valid for logical immediate. */ ct->ct |= TCG_CT_CONST_LIMM; break; case 'Z': /* zero */ ct->ct |= TCG_CT_CONST_ZERO; break; default: return -1; } Loading Loading @@ -197,6 +201,9 @@ static int tcg_target_const_match(tcg_target_long val, if ((ct & TCG_CT_CONST_LIMM) && is_limm(val)) { return 1; } if ((ct & TCG_CT_CONST_ZERO) && val == 0) { return 1; } return 0; } Loading Loading @@ -276,6 +283,10 @@ typedef enum { /* Add/subtract shifted register instructions (with a shift). */ I3502S_ADD_LSL = I3502_ADD, /* Conditional select instructions. */ I3506_CSEL = 0x1a800000, I3506_CSINC = 0x1a800400, /* Data-processing (2 source) instructions. */ I3508_LSLV = 0x1ac02000, I3508_LSRV = 0x1ac02400, Loading Loading @@ -421,6 +432,13 @@ static void tcg_out_insn_3502(TCGContext *s, AArch64Insn insn, TCGType ext, #define tcg_out_insn_3508 tcg_out_insn_3502 #define tcg_out_insn_3510 tcg_out_insn_3502 static void tcg_out_insn_3506(TCGContext *s, AArch64Insn insn, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, TCGCond c) { tcg_out32(s, insn | ext << 31 | rm << 16 | rn << 5 | rd | tcg_cond_to_aarch64[c] << 12); } static inline void tcg_out_ldst_9(TCGContext *s, enum aarch64_ldst_op_data op_data, Loading Loading @@ -1154,6 +1172,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGArg a2 = args[2]; int c2 = const_args[2]; /* Some operands are defined with "rZ" constraint, a register or the zero register. These need not actually test args[I] == 0. */ #define REG0(I) (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I]) switch (opc) { case INDEX_op_exit_tb: tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0); Loading Loading @@ -1372,6 +1394,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_cset(s, 0, a0, args[3]); break; case INDEX_op_movcond_i32: a2 = (int32_t)a2; /* FALLTHRU */ case INDEX_op_movcond_i64: tcg_out_cmp(s, ext, a1, a2, c2); tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]); break; case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0 | 0); break; Loading Loading @@ -1454,6 +1484,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, /* Opcode not implemented. */ tcg_abort(); } #undef REG0 } static const TCGTargetOpDef aarch64_op_defs[] = { Loading Loading @@ -1528,6 +1560,8 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_brcond_i64, { "r", "rA" } }, { INDEX_op_setcond_i32, { "r", "r", "rwA" } }, { INDEX_op_setcond_i64, { "r", "r", "rA" } }, { INDEX_op_movcond_i32, { "r", "r", "rwA", "rZ", "rZ" } }, { INDEX_op_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } }, { INDEX_op_qemu_ld8u, { "r", "l" } }, { INDEX_op_qemu_ld8s, { "r", "l" } }, Loading tcg/aarch64/tcg-target.h +2 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ typedef enum { #define TCG_TARGET_HAS_nand_i32 0 #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_deposit_i32 0 #define TCG_TARGET_HAS_movcond_i32 0 #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 Loading Loading @@ -84,7 +84,7 @@ typedef enum { #define TCG_TARGET_HAS_nand_i64 0 #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_movcond_i64 0 #define TCG_TARGET_HAS_movcond_i64 1 #define TCG_TARGET_HAS_add2_i64 0 #define TCG_TARGET_HAS_sub2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0 Loading Loading
tcg/aarch64/tcg-target.c +34 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ static inline void patch_reloc(uint8_t *code_ptr, int type, #define TCG_CT_CONST_IS32 0x100 #define TCG_CT_CONST_AIMM 0x200 #define TCG_CT_CONST_LIMM 0x400 #define TCG_CT_CONST_ZERO 0x800 /* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, Loading Loading @@ -146,6 +147,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, case 'L': /* Valid for logical immediate. */ ct->ct |= TCG_CT_CONST_LIMM; break; case 'Z': /* zero */ ct->ct |= TCG_CT_CONST_ZERO; break; default: return -1; } Loading Loading @@ -197,6 +201,9 @@ static int tcg_target_const_match(tcg_target_long val, if ((ct & TCG_CT_CONST_LIMM) && is_limm(val)) { return 1; } if ((ct & TCG_CT_CONST_ZERO) && val == 0) { return 1; } return 0; } Loading Loading @@ -276,6 +283,10 @@ typedef enum { /* Add/subtract shifted register instructions (with a shift). */ I3502S_ADD_LSL = I3502_ADD, /* Conditional select instructions. */ I3506_CSEL = 0x1a800000, I3506_CSINC = 0x1a800400, /* Data-processing (2 source) instructions. */ I3508_LSLV = 0x1ac02000, I3508_LSRV = 0x1ac02400, Loading Loading @@ -421,6 +432,13 @@ static void tcg_out_insn_3502(TCGContext *s, AArch64Insn insn, TCGType ext, #define tcg_out_insn_3508 tcg_out_insn_3502 #define tcg_out_insn_3510 tcg_out_insn_3502 static void tcg_out_insn_3506(TCGContext *s, AArch64Insn insn, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, TCGCond c) { tcg_out32(s, insn | ext << 31 | rm << 16 | rn << 5 | rd | tcg_cond_to_aarch64[c] << 12); } static inline void tcg_out_ldst_9(TCGContext *s, enum aarch64_ldst_op_data op_data, Loading Loading @@ -1154,6 +1172,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGArg a2 = args[2]; int c2 = const_args[2]; /* Some operands are defined with "rZ" constraint, a register or the zero register. These need not actually test args[I] == 0. */ #define REG0(I) (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I]) switch (opc) { case INDEX_op_exit_tb: tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0); Loading Loading @@ -1372,6 +1394,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_cset(s, 0, a0, args[3]); break; case INDEX_op_movcond_i32: a2 = (int32_t)a2; /* FALLTHRU */ case INDEX_op_movcond_i64: tcg_out_cmp(s, ext, a1, a2, c2); tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]); break; case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0 | 0); break; Loading Loading @@ -1454,6 +1484,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, /* Opcode not implemented. */ tcg_abort(); } #undef REG0 } static const TCGTargetOpDef aarch64_op_defs[] = { Loading Loading @@ -1528,6 +1560,8 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_brcond_i64, { "r", "rA" } }, { INDEX_op_setcond_i32, { "r", "r", "rwA" } }, { INDEX_op_setcond_i64, { "r", "r", "rA" } }, { INDEX_op_movcond_i32, { "r", "r", "rwA", "rZ", "rZ" } }, { INDEX_op_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } }, { INDEX_op_qemu_ld8u, { "r", "l" } }, { INDEX_op_qemu_ld8s, { "r", "l" } }, Loading
tcg/aarch64/tcg-target.h +2 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ typedef enum { #define TCG_TARGET_HAS_nand_i32 0 #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_deposit_i32 0 #define TCG_TARGET_HAS_movcond_i32 0 #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 Loading Loading @@ -84,7 +84,7 @@ typedef enum { #define TCG_TARGET_HAS_nand_i64 0 #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_deposit_i64 0 #define TCG_TARGET_HAS_movcond_i64 0 #define TCG_TARGET_HAS_movcond_i64 1 #define TCG_TARGET_HAS_add2_i64 0 #define TCG_TARGET_HAS_sub2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0 Loading