When running the testsuite with -fdisable-rtl-fwprop2 and -mpure-code
for cortex-m0, I noticed that some testcases were failing because we
still generate "ldr rX, .LCY", which is what we want to avoid with
-mpure-code. This is latent since a recent improvement in fwprop
(PR88833).
In this patch I change the thumb1_movsi_insn pattern so that it emits
the desired instruction sequence when arm_disable_literal_pool is set.
I tried to add a define_split instead, but couldn't make it work: the
compiler then complains it cannot split the instruction, while my new
define_split accepts the same operand types as thumb1_movsi_insn:
c-c++-common/torture/complex-sign-mixed-add.c:41:1: error: could not split insn
(insn 2989 425 4844 (set (reg/f:SI 3 r3 [1342])
(symbol_ref/u:SI ("*.LC6") [flags 0x2])) 836 {*thumb1_movsi_insn}
(expr_list:REG_EQUIV (symbol_ref/u:SI ("*.LC6") [flags 0x2])
(nil)))
during RTL pass: final
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "general_operand" ""))]
"TARGET_THUMB1
&& arm_disable_literal_pool
&& GET_CODE (operands[1]) == SYMBOL_REF"
[(clobber (const_int 0))]
"
gen_thumb1_movsi_symbol_ref(operands[0], operands[1]);
DONE;
"
)
and I put this in thumb1_movsi_insn:
if (GET_CODE (operands[1]) == SYMBOL_REF && arm_disable_literal_pool)
{
return \"#\";
}
return \"ldr\\t%0, %1\";
2020-02-07 Christophe Lyon <[email protected]>
* config/arm/thumb1.md (thumb1_movsi_insn): Fix ldr alternative to
work with -mpure-code.
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index 613cf9c..a722194 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -696,17 +696,43 @@
"TARGET_THUMB1
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
- "@
- movs %0, %1
- movs %0, %1
- movw %0, %1
- #
- #
- ldmia\\t%1, {%0}
- stmia\\t%0, {%1}
- ldr\\t%0, %1
- str\\t%1, %0
- mov\\t%0, %1"
+ "*
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return \"movs %0, %1\";
+ case 2:
+ return \"movw %0, %1\";
+ case 3:
+ case 4:
+ return \"#\";
+ case 5:
+ return \"ldmia\\t%1, {%0}\";
+ case 6:
+ return \"stmia\\t%0, {%1}\";
+ case 7:
+ /* Cannot load it directly, split to build it via MOV / LSLS / ADDS. */
+ if (GET_CODE (operands[1]) == SYMBOL_REF && arm_disable_literal_pool)
+ {
+ output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
+ output_asm_insn (\"lsls\\t%0, #8\", operands);
+ output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
+ output_asm_insn (\"lsls\\t%0, #8\", operands);
+ output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
+ output_asm_insn (\"lsls\\t%0, #8\", operands);
+ output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
+ return \"\";
+ }
+ else
+ return \"ldr\\t%0, %1\";
+ case 8:
+ return \"str\\t%1, %0\";
+ case 9:
+ return \"mov\\t%0, %1\";
+ default:
+ gcc_unreachable ();
+ }"
[(set_attr "length" "2,2,4,4,4,2,2,2,2,2")
(set_attr "type"
"mov_reg,mov_imm,mov_imm,multiple,multiple,load_4,store_4,load_4,store_4,mov_reg")
(set_attr "pool_range" "*,*,*,*,*,*,*,1018,*,*")