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 <christophe.l...@linaro.org> * 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,*,*")