Commit cb4e581fae0b67fa33caa01131f929f5dd6e9ebf

Authored by Laurent Desnogues
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>
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