sh.md (sibcalli, [...]): New insns.
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 25 Nov 2000 04:57:39 +0000 (04:57 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sat, 25 Nov 2000 04:57:39 +0000 (04:57 +0000)
* gcc/config/sh/sh.md (sibcalli, sibcalli_pcrel): New insns.
(sibcall_pcrel): New insn_and_split.
(sibcall, sibcall_value, sibcall_epilogue): New expands.

From-SVN: r37732

gcc/ChangeLog
gcc/config/sh/sh.md

index 7111b1345855933905a776cd43e932dcb22fd935..dfa01bb140ea22ee27f8ba13e3eff4078d652553 100644 (file)
@@ -1,5 +1,9 @@
 2000-11-25  Alexandre Oliva  <aoliva@redhat.com>
 
+       * gcc/config/sh/sh.md (sibcalli, sibcalli_pcrel): New insns.
+       (sibcall_pcrel): New insn_and_split.
+       (sibcall, sibcall_value, sibcall_epilogue): New expands.
+
        * config/sh/sh.md (GOTaddr2picreg, symGOT2reg, symGOTOFF2reg,
        symPLT_label2reg, call, call_value): Don't set
        current_function_uses_pic_offset_table.
index 9e8e6683b4571e003de76868fd0eeecbc633eee8..40a54ad46bdbe573195624591e5a85f37e5fbcf0 100644 (file)
     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
 }")
 
+(define_insn "sibcalli"
+  ;; FIXME: any call-clobbered register will do
+  [(call (mem:SI (match_operand:SI 0 "register_operand" "z"))
+        (match_operand 1 "" ""))
+   (use (reg:PSI FPSCR_REG))
+   (return)]
+  ""
+  "jmp @%0%#"
+  [(set_attr "needs_delay_slot" "yes")
+   (set_attr "type" "jump_ind")])
+
+(define_insn "sibcalli_pcrel"
+  ;; FIXME: any call-clobbered register will do
+  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "z"))
+        (match_operand 1 "" ""))
+   (use (match_operand 2 "" ""))
+   (use (reg:PSI FPSCR_REG))
+   (return)]
+  "TARGET_SH2"
+  "braf        %0\\n%O2:%#"
+  [(set_attr "needs_delay_slot" "yes")
+   (set_attr "type" "jump_ind")])
+
+(define_insn_and_split "sibcall_pcrel"
+  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
+        (match_operand 1 "" ""))
+   (use (reg:PSI FPSCR_REG))
+   ;; FIXME: any call-clobbered register will do
+   (clobber (match_scratch:SI 2 "=z"))
+   (return)]
+  "TARGET_SH2 && optimize"
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx lab = gen_call_site ();
+  rtx call_insn;
+
+  emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
+  call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
+                                                 lab));
+  SIBLING_CALL_P (call_insn) = 1;
+  DONE;
+}")
+
+(define_expand "sibcall"
+  [(parallel
+    [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
+          (match_operand 1 "" ""))
+     (use (reg:PSI FPSCR_REG))
+     (return)])]
+  ""
+  "
+{
+  if (flag_pic && TARGET_SH2 && optimize
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
+      /* The PLT needs the PIC register, but the epilogue would have
+        to restore it, so we can only use PC-relative PIC calls for
+        static functions.  */
+      && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
+    {
+      emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
+      DONE;
+    }
+  else
+    operands[0] = force_reg (SImode, XEXP (operands[0], 0));
+}")
+
+(define_expand "sibcall_value"
+  [(set (match_operand 0 "" "")
+       (call (match_operand 1 "" "")
+             (match_operand 2 "" "")))]
+  ""
+  "
+{
+  emit_call_insn (gen_sibcall (operands[1], operands[2]));
+  DONE;
+}")
+
+(define_expand "sibcall_epilogue"
+  [(return)]
+  ""
+  "
+{
+  sh_expand_epilogue ();
+  DONE;
+}")
+
 (define_insn "indirect_jump"
   [(set (pc)
        (match_operand:SI 0 "arith_reg_operand" "r"))]