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