Hi there,

When compile below simple code:

terguo01@terry-pc01:mtpcs-frame$ cat test.c
int main(void)
{
    return 0;
}

I got ICE with option -mtpcs-leaf-frame (no error if remove this option).

terguo01@terry-pc01:mtpcs-frame$
/work/terguo01/tools/gcc-arm-none-eabi-5_0-2014q4/bin/arm-none-eabi-gcc
-mtpcs-leaf-frame test.c -c -mcpu=cortex-m0plus -mthumb -da
test.c: In function 'main':
test.c:4:1: error: unrecognizable insn:
 }
 ^
(insn 20 19 21 (set (reg:SI 2 r2)
        (reg:SI 15 pc)) test.c:2 -1
     (nil))
test.c:4:1: internal compiler error: in extract_insn, at recog.c:2327
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html\ for instructions.

This RTL is generated in function thumb1_expand_prologue. The expected insn
pattern is thumb1_movsi_insn in thumb1.md. And instruction like "mov r2, pc"
is a legal instruction. Because gcc returns NO_REG for PC register, so no
valid pattern to match instruction that move pc to low register. This patch
intends to add a new insn pattern to legalize such thing.

Tested with GCC regression test. No regression. Is it OK to trunk?

BR,
Terry

2014-12-08  Terry Guo  terry....@arm.com

     * config/arm/predicates.md (pc_register): New to match PC register.
     * config/arm/thumb1.md (*thumb1_movpc_insn): New insn pattern.

gcc/testsuite/ChangeLog:
2014-12-08  Terry Guo  terry....@arm.com

     * gcc.target/arm/thumb1-mov-pc.c: New test.
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 032808c..c5ef5ed 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -361,6 +361,10 @@
   (and (match_code "smin,smax,umin,umax")
        (match_test "mode == GET_MODE (op)")))
 
+(define_special_predicate "pc_register"
+  (and (match_code "reg")
+       (match_test "REGNO (op) == PC_REGNUM")))
+
 (define_special_predicate "cc_register"
   (and (match_code "reg")
        (and (match_test "REGNO (op) == CC_REGNUM")
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index ddedc39..8e6057c 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -1780,6 +1780,16 @@
   "
 )
 
+(define_insn "*thumb1_movpc_insn"
+  [(set (match_operand:SI 0 "low_register_operand")
+        (match_operand:SI 1 "pc_register"))]
+  "TARGET_THUMB1"
+  "mov\\t%0, pc"
+  [(set_attr "length" "2")
+   (set_attr "conds" "nocond")
+   (set_attr "type"   "mov_reg")]
+)
+
 ;; NB never uses BX.
 (define_insn "*thumb1_tablejump"
   [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
diff --git a/gcc/testsuite/gcc.target/arm/thumb1-mov-pc.c 
b/gcc/testsuite/gcc.target/arm/thumb1-mov-pc.c
new file mode 100644
index 0000000..9f94131
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb1-mov-pc.c
@@ -0,0 +1,7 @@
+/* { dg-options "-mtpcs-leaf-frame -O2" } */
+/* { dg-skip-if "" { ! { arm_thumb1 } } } */
+int
+main ()
+{
+  return 0;
+}

Reply via email to