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,*,*")

Reply via email to