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 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" } },
... ...
tcg/arm/tcg-target.h
... ... @@ -55,6 +55,8 @@ enum {
55 55  
56 56 #define TCG_TARGET_NB_REGS 15
57 57  
  58 +#define TCG_CT_CONST_ARM 0x100
  59 +
58 60 /* used for function call generation */
59 61 #define TCG_REG_CALL_STACK TCG_REG_R13
60 62 #define TCG_TARGET_STACK_ALIGN 8
... ...