diff mbox

[ARM/Thumb1] Add a Thumb1 insn pattern to legalize the instruction that moves pc to low register

Message ID 000501d012c0$6dc3be70$494b3b50$@arm.com
State New
Headers show

Commit Message

Terry Guo Dec. 8, 2014, 8:24 a.m. UTC
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.guo@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.guo@arm.com

     * gcc.target/arm/thumb1-mov-pc.c: New test.

Comments

Richard Earnshaw Dec. 8, 2014, 11:30 a.m. UTC | #1
On 08/12/14 08:24, Terry Guo wrote:
> 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.guo@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.guo@arm.com
> 
>      * gcc.target/arm/thumb1-mov-pc.c: New test.
> 
> 
> thumb1-move-pc-v1.txt
> 
> 
> 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")

This needs constraints.

> +        (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;
> +}
>
diff mbox

Patch

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;
+}