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" } }, | ... | ... |