This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

SPARC: minor tweaks


(1) Remove a couple of dead #define from sparc.h.

(2) Address the following ??? note in sparc_compute_frame_size:

  /* Make sure nothing can clobber our register windows.
     If a SAVE must be done, or there is a stack-local variable,
     the register window area must be allocated.
     ??? For v8 we apparently need an additional 8 bytes of reserved space. */
   if (! leaf_function_p || size > 0)
    actual_fsize += (16 * UNITS_PER_WORD) + (TARGET_ARCH64 ? 0 : 8);

We actually need 4 bytes of space for the structure value pointer.  And then 
we round.  This is FIRST_PARM_OFFSET.

(3) Address the following ??? note in sparc_expand_prologue:

   ??? Historical cruft: "On SPARC, move-double insns between fpu and cpu need
   an 8-byte block of memory.  If any fpu reg is used in the function, we
   allocate such a block here, at the bottom of the frame, just in case it's
   needed."  Could this explain the -8 in emit_restore_regs?  */

It is outdated.  A 16-byte block is reserved through STARTING_FRAME_OFFSET and 
used by SECONDARY_MEMORY_NEEDED_RTX.  I think the -8 in emit_restore_regs is 
a convoluted way (4096 - 8) to write 4095. :-)

(4) Minor reorganization of sparc.md.  No actual change.


Bootstrapped/regtested on sparc64-sun-solaris2.9 and sparc-sun-solaris2.8, 
applied on mainline.


2005-05-12  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* config/sparc/sparc.h: Remove dead code.
	* config/sparc/sparc.c (sparc_compute_frame_size): Use
	FIRST_PARM_OFFSET for the size of the register window area.
	(emit_save_regs): Rename into emit_save_or_restore_regs.
	Add 'action' parameter.  Use 4095 as upper bound for the offset.
	Pass 'action' to save_or_restore_regs.
	(emit_restore_regs): Delete.
	(sparc_expand_prologue): Call emit_save_or_restore_regs.
	(sparc_expand_epilogue): Likewise.
	* config/sparc/sparc.md (mode macro P): Move.
	(movdi_insn_sp32_v9, movdi_insn_sp32): Swap.
	(mov<V32:mode> expander): Move to the top of the V32 section.
	(movdf_insn_sp32_v9_no_fpu, movdf_insn_sp32_v9): Swap.
	(movtf_insn_sp64_hq, movtf_insn_sp64): Swap.
	(sibcall_epilogue): Move.


--
Eric Botcazou
Index: config/sparc/sparc.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.md,v
retrieving revision 1.234
diff -u -r1.234 sparc.md
--- config/sparc/sparc.md	10 May 2005 07:50:33 -0000	1.234
+++ config/sparc/sparc.md	10 May 2005 08:03:16 -0000
@@ -68,14 +68,13 @@
    (UNSPECV_SAVEW		6)
   ])
 
-(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
-
 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
 
+
 ;; Attribute for cpu type.
 ;; These must match the values for enum processor_type in sparc.h.
 (define_attr "cpu"
@@ -300,6 +299,7 @@
 (define_delay (eq_attr "type" "return")
   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
 
+
 ;; Include SPARC DFA schedulers
 
 (include "cypress.md")
@@ -309,6 +309,7 @@
 (include "ultra1_2.md")
 (include "ultra3.md")
 
+
 ;; Operand and operator predicates.
 
 (include "predicates.md")
@@ -329,8 +330,6 @@
 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
 ;; insns that actually require more than one machine instruction.
 
-;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
-
 (define_expand "cmpsi"
   [(set (reg:CC 100)
 	(compare:CC (match_operand:SI 0 "compare_operand" "")
@@ -1694,7 +1693,10 @@
 }
   [(set_attr "type" "branch")
    (set_attr "branch_type" "reg")])
-
+
+
+(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
+
 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
 ;; that adds the PC value at the call point to operand 0.
@@ -1716,8 +1718,9 @@
 	(if_then_else (eq_attr "delayed_branch" "true")
 		      (const_int 3)
 		      (const_int 4)))])
-
-;; Move instructions
+
+
+;; Integer move instructions
 
 (define_expand "movqi"
   [(set (match_operand:QI 0 "general_operand" "")
@@ -2121,17 +2124,15 @@
 ;;      (reg:DI 2 %g2))
 ;;
 
-(define_insn "*movdi_insn_sp32_v9"
+(define_insn "*movdi_insn_sp32"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-					"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
+				"=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
         (match_operand:DI 1 "input_operand"
-					" J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
-  "! TARGET_ARCH64
-   && TARGET_V9
+				" J,U,T,r,o,i,r, f, T, o, f, f"))]
+  "! TARGET_V9
    && (register_operand (operands[0], DImode)
-       || register_or_zero_operand (operands[1], DImode))"
+       || register_operand (operands[1], DImode))"
   "@
-   stx\t%%g0, %0
    #
    std\t%1, %0
    ldd\t%1, %0
@@ -2143,22 +2144,21 @@
    ldd\t%1, %0
    #
    #
-   fmovd\\t%1, %0
-   ldd\\t%1, %0
-   std\\t%1, %0"
-  [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
-   (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
-   (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
+   #"
+  [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
+   (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
 
-(define_insn "*movdi_insn_sp32"
+(define_insn "*movdi_insn_sp32_v9"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-				"=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
+					"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
         (match_operand:DI 1 "input_operand"
-				" J,U,T,r,o,i,r, f, T, o, f, f"))]
-  "! TARGET_V9
+					" J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
+  "! TARGET_ARCH64
+   && TARGET_V9
    && (register_operand (operands[0], DImode)
-       || register_operand (operands[1], DImode))"
+       || register_or_zero_operand (operands[1], DImode))"
   "@
+   stx\t%%g0, %0
    #
    std\t%1, %0
    ldd\t%1, %0
@@ -2170,13 +2170,12 @@
    ldd\t%1, %0
    #
    #
-   #"
-  [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
-   (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
-
-;; We don't define V1SI because SI should work just fine.
-(define_mode_macro V64 [DF V2SI V4HI V8QI])
-(define_mode_macro V32 [SF V2HI V4QI])
+   fmovd\\t%1, %0
+   ldd\\t%1, %0
+   std\\t%1, %0"
+  [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
+   (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
+   (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
 
 (define_insn "*movdi_insn_sp64"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
@@ -2552,6 +2551,72 @@
 
 ;; Floating point and vector move instructions
 
+;; We don't define V1SI because SI should work just fine.
+(define_mode_macro V32 [SF V2HI V4QI])
+
+;; Yes, you guessed it right, the former movsf expander.
+(define_expand "mov<V32:mode>"
+  [(set (match_operand:V32 0 "general_operand" "")
+	(match_operand:V32 1 "general_operand" ""))]
+  "<V32:MODE>mode == SFmode || TARGET_VIS"
+{
+  /* Force constants into memory.  */
+  if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
+    {
+      /* emit_group_store will send such bogosity to us when it is
+         not storing directly into memory.  So fix this up to avoid
+         crashes in output_constant_pool.  */
+      if (operands [1] == const0_rtx)
+        operands[1] = CONST0_RTX (<V32:MODE>mode);
+
+      if ((TARGET_VIS || REGNO (operands[0]) < 32)
+	  && const_zero_operand (operands[1], <V32:MODE>mode))
+	goto movsf_is_ok;
+
+      /* We are able to build any SF constant in integer registers
+	 with at most 2 instructions.  */
+      if (REGNO (operands[0]) < 32
+	  && <V32:MODE>mode == SFmode)
+	goto movsf_is_ok;
+
+      operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
+                                                   operands[1]));
+    }
+
+  /* Handle sets of MEM first.  */
+  if (GET_CODE (operands[0]) == MEM)
+    {
+      if (register_or_zero_operand (operands[1], <V32:MODE>mode))
+	goto movsf_is_ok;
+
+      if (! reload_in_progress)
+	{
+	  operands[0] = validize_mem (operands[0]);
+	  operands[1] = force_reg (<V32:MODE>mode, operands[1]);
+	}
+    }
+
+  /* Fixup PIC cases.  */
+  if (flag_pic)
+    {
+      if (CONSTANT_P (operands[1])
+	  && pic_address_needs_scratch (operands[1]))
+	operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
+
+      if (symbolic_operand (operands[1], <V32:MODE>mode))
+	{
+	  operands[1] = legitimize_pic_address (operands[1],
+						<V32:MODE>mode,
+						(reload_in_progress ?
+						 operands[0] :
+						 NULL_RTX));
+	}
+    }
+
+ movsf_is_ok:
+  ;
+})
+
 (define_insn "*movsf_insn"
   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,*r,f,m,m")
 	(match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
@@ -2676,68 +2741,7 @@
   [(set (match_dup 0) (high:SF (match_dup 1)))
    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
 
-;; Yes, you guessed it right, the former movsf expander.
-(define_expand "mov<V32:mode>"
-  [(set (match_operand:V32 0 "general_operand" "")
-	(match_operand:V32 1 "general_operand" ""))]
-  "<V32:MODE>mode == SFmode || TARGET_VIS"
-{
-  /* Force constants into memory.  */
-  if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
-    {
-      /* emit_group_store will send such bogosity to us when it is
-         not storing directly into memory.  So fix this up to avoid
-         crashes in output_constant_pool.  */
-      if (operands [1] == const0_rtx)
-        operands[1] = CONST0_RTX (<V32:MODE>mode);
-
-      if ((TARGET_VIS || REGNO (operands[0]) < 32)
-	  && const_zero_operand (operands[1], <V32:MODE>mode))
-	goto movsf_is_ok;
-
-      /* We are able to build any SF constant in integer registers
-	 with at most 2 instructions.  */
-      if (REGNO (operands[0]) < 32
-	  && <V32:MODE>mode == SFmode)
-	goto movsf_is_ok;
-
-      operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
-                                                   operands[1]));
-    }
-
-  /* Handle sets of MEM first.  */
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (register_or_zero_operand (operands[1], <V32:MODE>mode))
-	goto movsf_is_ok;
-
-      if (! reload_in_progress)
-	{
-	  operands[0] = validize_mem (operands[0]);
-	  operands[1] = force_reg (<V32:MODE>mode, operands[1]);
-	}
-    }
-
-  /* Fixup PIC cases.  */
-  if (flag_pic)
-    {
-      if (CONSTANT_P (operands[1])
-	  && pic_address_needs_scratch (operands[1]))
-	operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
-
-      if (symbolic_operand (operands[1], <V32:MODE>mode))
-	{
-	  operands[1] = legitimize_pic_address (operands[1],
-						<V32:MODE>mode,
-						(reload_in_progress ?
-						 operands[0] :
-						 NULL_RTX));
-	}
-    }
-
- movsf_is_ok:
-  ;
-})
+(define_mode_macro V64 [DF V2SI V4HI V8QI])
 
 ;; Yes, you again guessed it right, the former movdf expander.
 (define_expand "mov<V64:mode>"
@@ -2840,23 +2844,6 @@
   [(set_attr "type" "load,store,*,*,*")
    (set_attr "length" "*,*,2,2,2")])
 
-(define_insn "*movdf_insn_sp32_v9_no_fpu"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
-	(match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
-  "! TARGET_FPU
-   && TARGET_V9
-   && ! TARGET_ARCH64
-   && (register_operand (operands[0], DFmode)
-       || register_or_zero_operand (operands[1], DFmode))"
-  "@
-  ldd\t%1, %0
-  std\t%1, %0
-  stx\t%r1, %0
-  #
-  #"
-  [(set_attr "type" "load,store,store,*,*")
-   (set_attr "length" "*,*,*,2,2")])
-
 ;; We have available v9 double floats but not 64-bit integer registers.
 (define_insn "*movdf_insn_sp32_v9"
   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
@@ -2881,6 +2868,23 @@
    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
 
+(define_insn "*movdf_insn_sp32_v9_no_fpu"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
+	(match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
+  "! TARGET_FPU
+   && TARGET_V9
+   && ! TARGET_ARCH64
+   && (register_operand (operands[0], DFmode)
+       || register_or_zero_operand (operands[1], DFmode))"
+  "@
+  ldd\t%1, %0
+  std\t%1, %0
+  stx\t%r1, %0
+  #
+  #"
+  [(set_attr "type" "load,store,store,*,*")
+   (set_attr "length" "*,*,*,2,2")])
+
 ;; We have available both v9 double floats and 64-bit integer registers.
 (define_insn "*movdf_insn_sp64"
   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
@@ -3217,6 +3221,17 @@
   "#"
   [(set_attr "length" "4")])
 
+(define_insn "*movtf_insn_sp64"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
+        (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
+  "TARGET_FPU
+   && TARGET_ARCH64
+   && ! TARGET_HARD_QUAD
+   && (register_operand (operands[0], TFmode)
+       || register_or_zero_operand (operands[1], TFmode))"
+  "#"
+  [(set_attr "length" "2")])
+
 (define_insn "*movtf_insn_sp64_hq"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
@@ -3235,17 +3250,6 @@
   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
    (set_attr "length" "2,*,*,*,2,2")])
 
-(define_insn "*movtf_insn_sp64"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
-        (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
-  "TARGET_FPU
-   && TARGET_ARCH64
-   && ! TARGET_HARD_QUAD
-   && (register_operand (operands[0], TFmode)
-       || register_or_zero_operand (operands[1], TFmode))"
-  "#"
-  [(set_attr "length" "2")])
-
 (define_insn "*movtf_insn_sp64_no_fpu"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
         (match_operand:TF 1 "input_operand"    "orG,rG"))]
@@ -3373,8 +3377,9 @@
 			gen_df_reg (set_src, 1)));
   DONE;
 })
-
-;; SPARC V9 conditional move instructions.
+
+
+;; SPARC-V9 conditional move instructions.
 
 ;; We can handle larger constants here for some flavors, but for now we keep
 ;; it simple and only allow those constants supported by all flavors.
@@ -3865,7 +3870,7 @@
   [(set_attr "length" "2")])
 
 
-;;- zero extension instructions
+;; Zero-extension instructions
 
 ;; These patterns originally accepted general_operands, however, slightly
 ;; better code is generated by only accepting register_operands, and then
@@ -3981,7 +3986,6 @@
   [(set_attr "type" "load")
    (set_attr "us3load_type" "3cycle")])
 
-
 ;; ??? Write truncdisi pattern using sra?
 
 (define_expand "zero_extendsidi2"
@@ -4145,7 +4149,8 @@
   "andcc\t%1, 0xff, %0"
   [(set_attr "type" "compare")])
 
-;;- sign extension instructions
+
+;; Sign-extension instructions
 
 ;; These patterns originally accepted general_operands, however, slightly
 ;; better code is generated by only accepting register_operands, and then
@@ -4330,7 +4335,8 @@
   ldsw\t%1, %0"
   [(set_attr "type" "shift,sload")
    (set_attr "us3load_type" "*,3cycle")])
-
+
+
 ;; Special pattern for optimizing bit-field compares.  This is needed
 ;; because combine uses this as a canonical form.
 
@@ -4367,7 +4373,8 @@
   return "andcc\t%0, %1, %%g0";
 }
   [(set_attr "type" "compare")])
-
+
+
 ;; Conversions between float, double and long double.
 
 (define_insn "extendsfdf2"
@@ -4447,7 +4454,8 @@
   "TARGET_FPU && TARGET_HARD_QUAD"
   "fqtod\t%1, %0"
   [(set_attr "type" "fp")])
-
+
+
 ;; Conversion between fixed point and floating point.
 
 (define_insn "floatsisf2"
@@ -4621,7 +4629,8 @@
   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
 
-;; Integer Addition/Subtraction.
+
+;; Integer addition/subtraction instructions.
 
 (define_expand "adddi3"
   [(set (match_operand:DI 0 "register_operand" "")
@@ -4967,8 +4976,9 @@
   "TARGET_ARCH64"
   "subcc\t%1, %2, %0"
   [(set_attr "type" "compare")])
-
-;; Integer Multiply/Divide.
+
+
+;; Integer multiply/divide instructions.
 
 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
@@ -5632,8 +5642,10 @@
   "TARGET_SPARCLET"
   "umacd\t%1, %2, %L0"
   [(set_attr "type" "imul")])
-
-;; Boolean instructions
+
+
+;; Boolean instructions.
+
 ;; We define DImode `and' so with DImode `not' we can get
 ;; DImode `andn'.  Other combinations are possible.
 
@@ -6331,7 +6343,8 @@
   "TARGET_ARCH64"
   "orcc\t%1, 0, %0"
    [(set_attr "type" "compare")])
-
+
+
 ;; Floating point arithmetic instructions.
 
 (define_expand "addtf3"
@@ -6691,8 +6704,9 @@
   "TARGET_FPU"
   "fsqrts\t%1, %0"
   [(set_attr "type" "fpsqrts")])
-
-;;- arithmetic shift instructions
+
+
+;; Arithmetic shift instructions.
 
 (define_insn "ashlsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -6990,8 +7004,10 @@
   return "srlx\t%1, %2, %0";
 }
   [(set_attr "type" "shift")])
-
-;; Unconditional and other jump instructions
+
+
+;; Unconditional and other jump instructions.
+
 (define_insn "jump"
   [(set (pc) (label_ref (match_operand 0 "" "")))]
   ""
@@ -7034,7 +7050,9 @@
   "jmp\t%a0%#"
   [(set_attr "type" "uncond_branch")])
 
-;;- jump to subroutine
+
+;; Jump to subroutine instructions.
+
 (define_expand "call"
   ;; Note that this expression is not used for generating RTL.
   ;; All the RTL is generated explicitly below.
@@ -7293,7 +7311,8 @@
   DONE;
 })
 
-;;- tail calls
+;;  Tail call instructions.
+
 (define_expand "sibcall"
   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
 	      (return)])]
@@ -7341,13 +7360,8 @@
   "* return output_sibcall(insn, operands[1]);"
   [(set_attr "type" "sibcall")])
 
-(define_expand "sibcall_epilogue"
-  [(return)]
-  ""
-{
-  sparc_expand_epilogue ();
-  DONE;
-})
+
+;; Special instructions.
 
 (define_expand "prologue"
   [(const_int 0)]
@@ -7381,6 +7395,14 @@
   sparc_expand_epilogue ();
 })
 
+(define_expand "sibcall_epilogue"
+  [(return)]
+  ""
+{
+  sparc_expand_epilogue ();
+  DONE;
+})
+
 (define_expand "return"
   [(return)]
   "sparc_can_use_return_insn_p ()"
@@ -7650,8 +7672,8 @@
   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
   [(set_attr "type" "iflush")])
 
-
-;; find first set.
+
+;; Find first set instructions.
 
 ;; The scan instruction searches from the most significant bit while ffs
 ;; searches from the least significant bit.  The bit index and treatment of
@@ -7847,6 +7869,9 @@
 		   (compare:CCX (match_dup 1) (const_int 0)))])]
   "")
 
+
+;; Prefetch instructions.
+
 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
@@ -7913,7 +7938,10 @@
   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
 }
   [(set_attr "type" "load")])
-
+
+
+;; Trap instructions.
+
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 5))]
   ""
@@ -7949,7 +7977,9 @@
   "t%C0\t%%xcc, %1"
   [(set_attr "type" "trap")])
 
-;; TLS support
+
+;; TLS support instructions.
+
 (define_insn "tgd_hi22"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
@@ -8512,6 +8542,7 @@
   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
 
+
 ;; Vector instructions.
 
 (define_insn "addv2si3"
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.369
diff -u -p -r1.369 sparc.c
--- config/sparc/sparc.c	10 May 2005 15:59:16 -0000	1.369
+++ config/sparc/sparc.c	10 May 2005 17:06:28 -0000
@@ -318,8 +318,7 @@ static int set_extends (rtx);
 static void emit_pic_helper (void);
 static void load_pic_register (bool);
 static int save_or_restore_regs (int, int, rtx, int, int);
-static void emit_save_regs (void);
-static void emit_restore_regs (void);
+static void emit_save_or_restore_regs (int);
 static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT);
 static void sparc_asm_function_epilogue (FILE *, HOST_WIDE_INT);
 #ifdef OBJECT_FORMAT_ELF
@@ -3508,10 +3507,9 @@ sparc_compute_frame_size (HOST_WIDE_INT 
 
   /* Make sure nothing can clobber our register windows.
      If a SAVE must be done, or there is a stack-local variable,
-     the register window area must be allocated.
-     ??? For v8 we apparently need an additional 8 bytes of reserved space.  */
+     the register window area must be allocated.  */
   if (! leaf_function_p || size > 0)
-    actual_fsize += (16 * UNITS_PER_WORD) + (TARGET_ARCH64 ? 0 : 8);
+    actual_fsize += FIRST_PARM_OFFSET (current_function_decl);
 
   return SPARC_STACK_ALIGN (actual_fsize);
 }
@@ -3623,14 +3621,14 @@ save_or_restore_regs (int low, int high,
 /* Emit code to save call-saved registers.  */
 
 static void
-emit_save_regs (void)
+emit_save_or_restore_regs (int action)
 {
   HOST_WIDE_INT offset;
   rtx base;
 
   offset = frame_base_offset - apparent_fsize;
 
-  if (offset < -4096 || offset + num_gfregs * 4 > 4096)
+  if (offset < -4096 || offset + num_gfregs * 4 > 4095)
     {
       /* ??? This might be optimized a little as %g1 might already have a
 	 value close enough that a single add insn will do.  */
@@ -3648,34 +3646,8 @@ emit_save_regs (void)
   else
     base = frame_base_reg;
 
-  offset = save_or_restore_regs (0, 8, base, offset, SORR_SAVE);
-  save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, SORR_SAVE);
-}
-
-/* Emit code to restore call-saved registers.  */
-
-static void
-emit_restore_regs (void)
-{
-  HOST_WIDE_INT offset;
-  rtx base;
-
-  offset = frame_base_offset - apparent_fsize;
-
-  if (offset < -4096 || offset + num_gfregs * 4 > 4096 - 8 /*double*/)
-    {
-      base = gen_rtx_REG (Pmode, 1);
-      emit_move_insn (base, GEN_INT (offset));
-      emit_insn (gen_rtx_SET (VOIDmode,
-			      base,
-			      gen_rtx_PLUS (Pmode, frame_base_reg, base)));
-      offset = 0;
-    }
-  else
-    base = frame_base_reg;
-
-  offset = save_or_restore_regs (0, 8, base, offset, SORR_RESTORE);
-  save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, SORR_RESTORE);
+  offset = save_or_restore_regs (0, 8, base, offset, action);
+  save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, action);
 }
 
 /* Generate a save_register_window insn.  */
@@ -3814,9 +3786,8 @@ sparc_expand_prologue (void)
         RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, i)) = 1;
     }
 
-  /* Call-saved registers are saved just above the outgoing argument area.  */
   if (num_gfregs)
-    emit_save_regs ();
+    emit_save_or_restore_regs (SORR_SAVE);
 
   /* Load the PIC register if needed.  */
   if (flag_pic && current_function_uses_pic_offset_table)
@@ -3824,12 +3795,7 @@ sparc_expand_prologue (void)
 }
  
 /* This function generates the assembly code for function entry, which boils
-   down to emitting the necessary .register directives.
-
-   ??? Historical cruft: "On SPARC, move-double insns between fpu and cpu need
-   an 8-byte block of memory.  If any fpu reg is used in the function, we
-   allocate such a block here, at the bottom of the frame, just in case it's
-   needed."  Could this explain the -8 in emit_restore_regs?  */
+   down to emitting the necessary .register directives.  */
 
 static void
 sparc_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
@@ -3847,7 +3813,7 @@ void
 sparc_expand_epilogue (void)
 {
   if (num_gfregs)
-    emit_restore_regs ();
+    emit_save_or_restore_regs (SORR_RESTORE);
 
   if (actual_fsize == 0)
     /* do nothing.  */ ;
Index: config/sparc/sparc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.h,v
retrieving revision 1.282
diff -u -p -r1.282 sparc.h
--- config/sparc/sparc.h	27 Apr 2005 09:12:00 -0000	1.282
+++ config/sparc/sparc.h	10 May 2005 17:06:29 -0000
@@ -906,9 +906,6 @@ extern int sparc_mode_class[];
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
 
-/* SPARC pc isn't overloaded on a register that the compiler knows about.  */
-/* #define PC_REGNUM  */
-
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM 14
 
@@ -1375,16 +1372,12 @@ extern char leaf_reg_remap[];
    If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
    first local allocated.  Otherwise, it is the offset to the BEGINNING
    of the first local allocated.  */
-/* This allows space for one TFmode floating point value.  */
+/* This allows space for one TFmode floating point value, which is used
+   by SECONDARY_MEMORY_NEEDED_RTX.  */
 #define STARTING_FRAME_OFFSET \
   (TARGET_ARCH64 ? -16 \
    : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
 
-/* If we generate an insn to push BYTES bytes,
-   this says how many the stack pointer really advances by.
-   On SPARC, don't define this because there are no push insns.  */
-/*  #define PUSH_ROUNDING(BYTES) */
-
 /* Offset of first parameter from the argument pointer register value.
    !v9: This is 64 for the ins and locals, plus 4 for the struct-return reg
    even if this function isn't going to use it.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]