diff options
Diffstat (limited to 'gcc/config/arm/arm.md')
| -rw-r--r-- | gcc/config/arm/arm.md | 93 |
1 files changed, 69 insertions, 24 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index fb13fe0..4b94f6e 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7377,12 +7377,22 @@ }" ) -(define_insn "*call_reg" +(define_insn "*call_reg_armv5" [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM" + "TARGET_ARM && arm_arch5" + "blx%?\\t%0" + [(set_attr "type" "call")] +) + +(define_insn "*call_reg_arm" + [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_ARM && !arm_arch5" "* return output_call (operands); " @@ -7404,35 +7414,29 @@ (set_attr "type" "call")] ) -(define_insn "*call_indirect" +(define_insn "*call_reg_thumb_v5" [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB" - "* - { - if (TARGET_CALLER_INTERWORKING) - return \"bl\\t%__interwork_call_via_%0\"; - else - return \"bl\\t%__call_via_%0\"; - }" - [(set_attr "type" "call")] + "TARGET_THUMB && arm_arch5" + "blx\\t%0" + [(set_attr "length" "2") + (set_attr "type" "call")] ) -(define_insn "*call_value_indirect" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) +(define_insn "*call_reg_thumb" + [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB" + "TARGET_THUMB && !arm_arch5" "* { if (TARGET_CALLER_INTERWORKING) - return \"bl\\t%__interwork_call_via_%1\"; + return \"bl\\t%__interwork_call_via_%0\"; else - return \"bl\\t%__call_via_%1\"; + return \"bl\\t%__call_via_%0\"; }" [(set_attr "type" "call")] ) @@ -7459,13 +7463,24 @@ }" ) -(define_insn "*call_value_reg" +(define_insn "*call_value_reg_armv5" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM" + "TARGET_ARM && arm_arch5" + "blx%?\\t%1" + [(set_attr "type" "call")] +) + +(define_insn "*call_value_reg_arm" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_ARM && !arm_arch5" "* return output_call (&operands[1]); " @@ -7487,6 +7502,35 @@ (set_attr "type" "call")] ) +(define_insn "*call_value_reg_thumb_v5" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB && arm_arch5" + "blx\\t%1" + [(set_attr "length" "2") + (set_attr "type" "call")] +) + +(define_insn "*call_value_reg_thumb" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB && !arm_arch5" + "* + { + if (TARGET_CALLER_INTERWORKING) + return \"bl\\t%__interwork_call_via_%1\"; + else + return \"bl\\t%__call_via_%1\"; + }" + [(set_attr "type" "call")] +) + ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. @@ -7786,6 +7830,7 @@ "" ) +;; NB Never uses BX. (define_insn "*arm_indirect_jump" [(set (pc) (match_operand:SI 0 "s_register_operand" "r"))] @@ -7794,8 +7839,6 @@ [(set_attr "predicable" "yes")] ) -;; Although not supported by the define_expand above, -;; cse/combine may generate this form. (define_insn "*load_indirect_jump" [(set (pc) (match_operand:SI 0 "memory_operand" "m"))] @@ -7807,6 +7850,7 @@ (set_attr "predicable" "yes")] ) +;; NB Never uses BX. (define_insn "*thumb_indirect_jump" [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))] @@ -10099,6 +10143,7 @@ " ) +;; NB never uses BX. (define_insn "*thumb_tablejump" [(set (pc) (match_operand:SI 0 "register_operand" "l*r")) (use (label_ref (match_operand 1 "" "")))] |
