Commit cb4e581fae0b67fa33caa01131f929f5dd6e9ebf
Committed by
Andrzej Zaborowski
1 parent
d9885a0b
this patch improves the ARM back-end in the following way:
- use movw/movt to load immediate values for ARMv7-A - implement add/sub/and/or/xor with immediate (only 8-bit) Laurent Signed-off-by: Laurent Desnogues <laurent.desnogues@gmail.com> Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
Showing
2 changed files
with
37 additions
and
7 deletions
tcg/arm/tcg-target.c
| @@ -100,6 +100,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) | @@ -100,6 +100,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) | ||
| 100 | 100 | ||
| 101 | ct_str = *pct_str; | 101 | ct_str = *pct_str; |
| 102 | switch (ct_str[0]) { | 102 | switch (ct_str[0]) { |
| 103 | + case 'I': | ||
| 104 | + ct->ct |= TCG_CT_CONST_ARM; | ||
| 105 | + break; | ||
| 106 | + | ||
| 103 | case 'r': | 107 | case 'r': |
| 104 | #ifndef CONFIG_SOFTMMU | 108 | #ifndef CONFIG_SOFTMMU |
| 105 | case 'd': | 109 | case 'd': |
| @@ -175,6 +179,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) | @@ -175,6 +179,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) | ||
| 175 | return 0; | 179 | return 0; |
| 176 | } | 180 | } |
| 177 | 181 | ||
| 182 | + | ||
| 183 | +static inline int check_fit_imm(uint32_t imm) | ||
| 184 | +{ | ||
| 185 | + /* XXX: use rotation */ | ||
| 186 | + return (imm & ~0xff) == 0; | ||
| 187 | +} | ||
| 188 | + | ||
| 178 | /* Test if a constant matches the constraint. | 189 | /* Test if a constant matches the constraint. |
| 179 | * TODO: define constraints for: | 190 | * TODO: define constraints for: |
| 180 | * | 191 | * |
| @@ -190,6 +201,8 @@ static inline int tcg_target_const_match(tcg_target_long val, | @@ -190,6 +201,8 @@ static inline int tcg_target_const_match(tcg_target_long val, | ||
| 190 | ct = arg_ct->ct; | 201 | ct = arg_ct->ct; |
| 191 | if (ct & TCG_CT_CONST) | 202 | if (ct & TCG_CT_CONST) |
| 192 | return 1; | 203 | return 1; |
| 204 | + else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val)) | ||
| 205 | + return 1; | ||
| 193 | else | 206 | else |
| 194 | return 0; | 207 | return 0; |
| 195 | } | 208 | } |
| @@ -333,6 +346,16 @@ static inline void tcg_out_movi32(TCGContext *s, | @@ -333,6 +346,16 @@ static inline void tcg_out_movi32(TCGContext *s, | ||
| 333 | tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) : | 346 | tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) : |
| 334 | tcg_out_dat_imm(s, cond, ARITH_SUB, rd, 15, -offset); | 347 | tcg_out_dat_imm(s, cond, ARITH_SUB, rd, 15, -offset); |
| 335 | 348 | ||
| 349 | +#ifdef __ARM_ARCH_7A__ | ||
| 350 | + /* use movw/movt */ | ||
| 351 | + /* movw */ | ||
| 352 | + tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12) | ||
| 353 | + | ((arg << 4) & 0x000f0000) | (arg & 0xfff)); | ||
| 354 | + if (arg & 0xffff0000) | ||
| 355 | + /* movt */ | ||
| 356 | + tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12) | ||
| 357 | + | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff)); | ||
| 358 | +#else | ||
| 336 | tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0, arg & 0xff); | 359 | tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0, arg & 0xff); |
| 337 | if (arg & 0x0000ff00) | 360 | if (arg & 0x0000ff00) |
| 338 | tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, | 361 | tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, |
| @@ -343,6 +366,7 @@ static inline void tcg_out_movi32(TCGContext *s, | @@ -343,6 +366,7 @@ static inline void tcg_out_movi32(TCGContext *s, | ||
| 343 | if (arg & 0xff000000) | 366 | if (arg & 0xff000000) |
| 344 | tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, | 367 | tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, |
| 345 | ((arg >> 24) & 0xff) | 0x400); | 368 | ((arg >> 24) & 0xff) | 0x400); |
| 369 | +#endif | ||
| 346 | } | 370 | } |
| 347 | 371 | ||
| 348 | static inline void tcg_out_mul32(TCGContext *s, | 372 | static inline void tcg_out_mul32(TCGContext *s, |
| @@ -1383,8 +1407,12 @@ static inline void tcg_out_op(TCGContext *s, int opc, | @@ -1383,8 +1407,12 @@ static inline void tcg_out_op(TCGContext *s, int opc, | ||
| 1383 | c = ARITH_EOR; | 1407 | c = ARITH_EOR; |
| 1384 | /* Fall through. */ | 1408 | /* Fall through. */ |
| 1385 | gen_arith: | 1409 | gen_arith: |
| 1386 | - tcg_out_dat_reg(s, COND_AL, c, | ||
| 1387 | - args[0], args[1], args[2], SHIFT_IMM_LSL(0)); | 1410 | + if (const_args[2]) |
| 1411 | + tcg_out_dat_imm(s, COND_AL, c, | ||
| 1412 | + args[0], args[1], args[2]); | ||
| 1413 | + else | ||
| 1414 | + tcg_out_dat_reg(s, COND_AL, c, | ||
| 1415 | + args[0], args[1], args[2], SHIFT_IMM_LSL(0)); | ||
| 1388 | break; | 1416 | break; |
| 1389 | case INDEX_op_add2_i32: | 1417 | case INDEX_op_add2_i32: |
| 1390 | tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC, | 1418 | tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC, |
| @@ -1523,15 +1551,15 @@ static const TCGTargetOpDef arm_op_defs[] = { | @@ -1523,15 +1551,15 @@ static const TCGTargetOpDef arm_op_defs[] = { | ||
| 1523 | { INDEX_op_st_i32, { "r", "r" } }, | 1551 | { INDEX_op_st_i32, { "r", "r" } }, |
| 1524 | 1552 | ||
| 1525 | /* TODO: "r", "r", "ri" */ | 1553 | /* TODO: "r", "r", "ri" */ |
| 1526 | - { INDEX_op_add_i32, { "r", "r", "r" } }, | ||
| 1527 | - { INDEX_op_sub_i32, { "r", "r", "r" } }, | 1554 | + { INDEX_op_add_i32, { "r", "r", "rI" } }, |
| 1555 | + { INDEX_op_sub_i32, { "r", "r", "rI" } }, | ||
| 1528 | { INDEX_op_mul_i32, { "r", "r", "r" } }, | 1556 | { INDEX_op_mul_i32, { "r", "r", "r" } }, |
| 1529 | { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, | 1557 | { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, |
| 1530 | { INDEX_op_div2_i32, { "r", "r", "r", "1", "2" } }, | 1558 | { INDEX_op_div2_i32, { "r", "r", "r", "1", "2" } }, |
| 1531 | { INDEX_op_divu2_i32, { "r", "r", "r", "1", "2" } }, | 1559 | { INDEX_op_divu2_i32, { "r", "r", "r", "1", "2" } }, |
| 1532 | - { INDEX_op_and_i32, { "r", "r", "r" } }, | ||
| 1533 | - { INDEX_op_or_i32, { "r", "r", "r" } }, | ||
| 1534 | - { INDEX_op_xor_i32, { "r", "r", "r" } }, | 1560 | + { INDEX_op_and_i32, { "r", "r", "rI" } }, |
| 1561 | + { INDEX_op_or_i32, { "r", "r", "rI" } }, | ||
| 1562 | + { INDEX_op_xor_i32, { "r", "r", "rI" } }, | ||
| 1535 | { INDEX_op_neg_i32, { "r", "r" } }, | 1563 | { INDEX_op_neg_i32, { "r", "r" } }, |
| 1536 | 1564 | ||
| 1537 | { INDEX_op_shl_i32, { "r", "r", "ri" } }, | 1565 | { INDEX_op_shl_i32, { "r", "r", "ri" } }, |
tcg/arm/tcg-target.h
| @@ -55,6 +55,8 @@ enum { | @@ -55,6 +55,8 @@ enum { | ||
| 55 | 55 | ||
| 56 | #define TCG_TARGET_NB_REGS 15 | 56 | #define TCG_TARGET_NB_REGS 15 |
| 57 | 57 | ||
| 58 | +#define TCG_CT_CONST_ARM 0x100 | ||
| 59 | + | ||
| 58 | /* used for function call generation */ | 60 | /* used for function call generation */ |
| 59 | #define TCG_REG_CALL_STACK TCG_REG_R13 | 61 | #define TCG_REG_CALL_STACK TCG_REG_R13 |
| 60 | #define TCG_TARGET_STACK_ALIGN 8 | 62 | #define TCG_TARGET_STACK_ALIGN 8 |