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 | 100 | |
| 101 | 101 | ct_str = *pct_str; |
| 102 | 102 | switch (ct_str[0]) { |
| 103 | + case 'I': | |
| 104 | + ct->ct |= TCG_CT_CONST_ARM; | |
| 105 | + break; | |
| 106 | + | |
| 103 | 107 | case 'r': |
| 104 | 108 | #ifndef CONFIG_SOFTMMU |
| 105 | 109 | case 'd': |
| ... | ... | @@ -175,6 +179,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) |
| 175 | 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 | 189 | /* Test if a constant matches the constraint. |
| 179 | 190 | * TODO: define constraints for: |
| 180 | 191 | * |
| ... | ... | @@ -190,6 +201,8 @@ static inline int tcg_target_const_match(tcg_target_long val, |
| 190 | 201 | ct = arg_ct->ct; |
| 191 | 202 | if (ct & TCG_CT_CONST) |
| 192 | 203 | return 1; |
| 204 | + else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val)) | |
| 205 | + return 1; | |
| 193 | 206 | else |
| 194 | 207 | return 0; |
| 195 | 208 | } |
| ... | ... | @@ -333,6 +346,16 @@ static inline void tcg_out_movi32(TCGContext *s, |
| 333 | 346 | tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) : |
| 334 | 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 | 359 | tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0, arg & 0xff); |
| 337 | 360 | if (arg & 0x0000ff00) |
| 338 | 361 | tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, |
| ... | ... | @@ -343,6 +366,7 @@ static inline void tcg_out_movi32(TCGContext *s, |
| 343 | 366 | if (arg & 0xff000000) |
| 344 | 367 | tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd, |
| 345 | 368 | ((arg >> 24) & 0xff) | 0x400); |
| 369 | +#endif | |
| 346 | 370 | } |
| 347 | 371 | |
| 348 | 372 | static inline void tcg_out_mul32(TCGContext *s, |
| ... | ... | @@ -1383,8 +1407,12 @@ static inline void tcg_out_op(TCGContext *s, int opc, |
| 1383 | 1407 | c = ARITH_EOR; |
| 1384 | 1408 | /* Fall through. */ |
| 1385 | 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 | 1416 | break; |
| 1389 | 1417 | case INDEX_op_add2_i32: |
| 1390 | 1418 | tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC, |
| ... | ... | @@ -1523,15 +1551,15 @@ static const TCGTargetOpDef arm_op_defs[] = { |
| 1523 | 1551 | { INDEX_op_st_i32, { "r", "r" } }, |
| 1524 | 1552 | |
| 1525 | 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 | 1556 | { INDEX_op_mul_i32, { "r", "r", "r" } }, |
| 1529 | 1557 | { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, |
| 1530 | 1558 | { INDEX_op_div2_i32, { "r", "r", "r", "1", "2" } }, |
| 1531 | 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 | 1563 | { INDEX_op_neg_i32, { "r", "r" } }, |
| 1536 | 1564 | |
| 1537 | 1565 | { INDEX_op_shl_i32, { "r", "r", "ri" } }, | ... | ... |