OSDN Git Service

(call): Use struct value pattern is struct size is not
authorwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Sep 1994 00:05:20 +0000 (00:05 +0000)
committerwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Sep 1994 00:05:20 +0000 (00:05 +0000)
equal to zero instead of greater than zero.
(call+7, call+8): New patterns for untyped calls.
(untyped_call): Revise to emit explicit rtl for all operation.
Delete four old patterns that matched the unexpanded untyped_call
pattern.
(blockage): New pattern.
(flush_register_windows): Modify from 0 to 1.
(goto_handler_and_restore): Modify from 1 to 2.
(flush): Modify from 2 to 3.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@8172 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/sparc/sparc.md

index ef777ba..2b68258 100644 (file)
         call-clobbered registers?  We lose this if it is a JUMP_INSN.
         Why cannot we have delay slots filled if it were a CALL?  */
 
-      if (! TARGET_V9 && INTVAL (operands[3]) > 0)
+      if (! TARGET_V9 && INTVAL (operands[3]) != 0)
        emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
                                 gen_rtx (SET, VOIDmode, pc_rtx,
                                          XEXP (operands[0], 0)),
   nregs_rtx = const0_rtx;
 #endif
 
-  if (! TARGET_V9 && INTVAL (operands[3]) > 0)
+  if (! TARGET_V9 && INTVAL (operands[3]) != 0)
     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
                             operands[3],
 }"
   [(set_attr "type" "call_no_delay_slot")])
 
+;; This is a call that may want a structure value.  This is used for
+;; untyped_calls.
+(define_insn ""
+  [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
+        (match_operand 1 "" ""))
+   (match_operand 2 "immediate_operand" "")
+   (clobber (reg:SI 15))]
+  ;;- Do not use operand 1 for most machines.
+  "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
+  "*
+{
+  return \"call %a0,%1\;nop\;nop\";
+}"
+  [(set_attr "type" "call_no_delay_slot")])
+
+;; This is a call that wants a structure value.
+(define_insn ""
+  [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
+        (match_operand 1 "" ""))
+   (match_operand 2 "immediate_operand" "")
+   (clobber (reg:SI 15))]
+  ;;- Do not use operand 1 for most machines.
+  "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
+  "*
+{
+  return \"call %a0,%1\;nop\;nop\";
+}"
+  [(set_attr "type" "call_no_delay_slot")])
+
 (define_expand "call_value"
   ;; Note that this expression is not used for generating RTL.
   ;; All the RTL is generated explicitly below.
   [(set_attr "type" "call")])
 
 (define_expand "untyped_call"
-  [(parallel [(call (match_operand:SI 0 "call_operand" "")
+  [(parallel [(call (match_operand 0 "" "")
                    (const_int 0))
-             (match_operand:BLK 1 "memory_operand" "")
-             (match_operand 2 "" "")
-;; ??? v9: mode is wrong here.
-             (clobber (reg:SI 15))])]
+             (match_operand 1 "" "")
+             (match_operand 2 "" "")])]
   ""
   "
 {
-  operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
-}")
-
-;; Make a call followed by two nops in case the function being called
-;; returns a structure value and expects to skip an unimp instruction.
+  int i;
 
-(define_insn ""
-  [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
-        (const_int 0))
-   (match_operand:DI 1 "memory_operand" "o")
-   (match_operand 2 "" "")
-   (clobber (reg:SI 15))]
-  "! TARGET_V9"
-  "*
-{
-  operands[2] = adj_offsettable_operand (operands[1], 8);
-  return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
-}"
-  [(set_attr "type" "multi")])
+  /* Pass constm1 to indicate that it may expect a structure value, but
+     we don't know what size it is.  */
+  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
 
-;; Make a call followed by two nops in case the function being called
-;; returns a structure value and expects to skip an unimp instruction.
+  for (i = 0; i < XVECLEN (operands[2], 0); i++)
+    {
+      rtx set = XVECEXP (operands[2], 0, i);
+      emit_move_insn (SET_DEST (set), SET_SRC (set));
+    }
 
-(define_insn ""
-  [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
-        (const_int 0))
-   (match_operand:DI 1 "memory_operand" "o")
-   (match_operand 2 "" "")
-   (clobber (reg:SI 15))]
-  ""
-  "*
-{
-  operands[2] = adj_offsettable_operand (operands[1], 8);
-  return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
-}"
-  [(set_attr "type" "multi")])
+  /* The optimizer does not know that the call sets the function value
+     registers we stored in the result block.  We avoid problems by
+     claiming that all hard registers are used and clobbered at this
+     point.  */
+  emit_insn (gen_blockage ());
 
-;; V9 version of untyped_call.
+  DONE;
+}")
 
-(define_insn ""
-  [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
-        (const_int 0))
-   (match_operand:DI 1 "memory_operand" "o")
-   (match_operand 2 "" "")
-;; ??? Mode is wrong here, but it must match the define_expand.
-   (clobber (reg:SI 15))]
-  "TARGET_V9"
-  "*
-{
-  operands[2] = adj_offsettable_operand (operands[1], 8);
-  return \"call %a0,0\;nop\;stx %%o0,%1\;stq %%f0,%2\";
-}"
-  [(set_attr "type" "multi")])
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory.  This blocks insns from being moved across this point.
 
-(define_insn ""
-  [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
-        (const_int 0))
-   (match_operand:DI 1 "memory_operand" "o")
-   (match_operand 2 "" "")
-;; ??? Mode is wrong here, but it must match the define_expand.
-   (clobber (reg:SI 15))]
-  "TARGET_V9"
-  "*
-{
-  operands[2] = adj_offsettable_operand (operands[1], 8);
-  return \"call %a0,0\;nop\;stx %%o0,%1\;stq %%f0,%2\";
-}"
-  [(set_attr "type" "multi")])
+(define_insn "blockage"
+  [(unspec_volatile [(const_int 0)] 0)]
+  ""
+  "")
 
 ;; Prepare to return any type including a structure value.
 
 
 ;; Special trap insn to flush register windows.
 (define_insn "flush_register_windows"
-  [(unspec_volatile [(const_int 0)] 0)]
+  [(unspec_volatile [(const_int 0)] 1)]
   ""
   "* return TARGET_V9 ? \"flushw\" : \"ta 3\";"
   [(set_attr "type" "misc")])
 
 (define_insn "goto_handler_and_restore"
-  [(unspec_volatile [(const_int 0)] 1)]
+  [(unspec_volatile [(const_int 0)] 2)]
   ""
   "jmp %%o0+0\;restore"
   [(set_attr "type" "misc")
 ;; Special pattern for the FLUSH instruction.
 
 (define_insn "flush"
-  [(unspec_volatile [(match_operand 0 "" "")] 2)]
+  [(unspec_volatile [(match_operand 0 "" "")] 3)]
   ""
   "* return TARGET_V9 ? \"flush %a0\" : \"iflush %a0\";"
   [(set_attr "type" "misc")])