OSDN Git Service

* doc/invoke.texi (SPARC options): Document -mfix-at697f.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Oct 2011 12:59:34 +0000 (12:59 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Oct 2011 12:59:34 +0000 (12:59 +0000)
* config/sparc/sparc.opt (mfix-at697f): New option.
* config/sparc/sparc.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
(sparc_reorg): New function.

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

gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.opt
gcc/doc/invoke.texi

index fa790b3..5ecfe95 100644 (file)
@@ -444,6 +444,7 @@ static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
                                   HOST_WIDE_INT, tree);
 static bool sparc_can_output_mi_thunk (const_tree, HOST_WIDE_INT,
                                       HOST_WIDE_INT, const_tree);
+static void sparc_reorg (void);
 static struct machine_function * sparc_init_machine_status (void);
 static bool sparc_cannot_force_const_mem (enum machine_mode, rtx);
 static rtx sparc_tls_get_addr (void);
@@ -582,6 +583,9 @@ char sparc_hard_reg_printed[8];
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK sparc_can_output_mi_thunk
 
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG sparc_reorg
+
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS sparc_rtx_costs
 #undef TARGET_ADDRESS_COST
@@ -10389,6 +10393,104 @@ sparc_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED,
   return (vcall_offset >= -32768 || ! fixed_regs[5]);
 }
 
+/* We use the machine specific reorg pass to enable workarounds for errata.  */
+
+static void
+sparc_reorg (void)
+{
+  rtx insn, next;
+
+  /* The only erratum we handle for now is that of the AT697F processor.  */
+  if (!sparc_fix_at697f)
+    return;
+
+  /* We need to have the (essentially) final form of the insn stream in order
+     to properly detect the various hazards.  Run delay slot scheduling.  */
+  if (optimize > 0 && flag_delayed_branch)
+    dbr_schedule (get_insns ());
+
+  /* Now look for specific patterns in the insn stream.  */
+  for (insn = get_insns (); insn; insn = next)
+    {
+      bool insert_nop = false;
+      rtx set;
+
+      /* Look for a single-word load into an odd-numbered FP register.  */
+      if (NONJUMP_INSN_P (insn)
+         && (set = single_set (insn)) != NULL_RTX
+         && GET_MODE_SIZE (GET_MODE (SET_SRC (set))) == 4
+         && MEM_P (SET_SRC (set))
+         && REG_P (SET_DEST (set))
+         && REGNO (SET_DEST (set)) > 31
+         && REGNO (SET_DEST (set)) % 2 != 0)
+       {
+         /* The wrong dependency is on the enclosing double register.  */
+         unsigned int x = REGNO (SET_DEST (set)) - 1;
+         unsigned int src1, src2, dest;
+         int code;
+
+         /* If the insn has a delay slot, then it cannot be problematic.  */
+         next = next_active_insn (insn);
+         if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
+           code = -1;
+         else
+           {
+             extract_insn (next);
+             code = INSN_CODE (next);
+           }
+
+         switch (code)
+           {
+           case CODE_FOR_adddf3:
+           case CODE_FOR_subdf3:
+           case CODE_FOR_muldf3:
+           case CODE_FOR_divdf3:
+             dest = REGNO (recog_data.operand[0]);
+             src1 = REGNO (recog_data.operand[1]);
+             src2 = REGNO (recog_data.operand[2]);
+             if (src1 != src2)
+               {
+                 /* Case [1-4]:
+                                ld [address], %fx+1
+                                FPOPd %f{x,y}, %f{y,x}, %f{x,y}  */
+                 if ((src1 == x || src2 == x)
+                     && (dest == src1 || dest == src2))
+                   insert_nop = true;
+               }
+             else
+               {
+                 /* Case 5:
+                            ld [address], %fx+1
+                            FPOPd %fx, %fx, %fx  */
+                 if (src1 == x
+                     && dest == src1
+                     && (code == CODE_FOR_adddf3 || code == CODE_FOR_muldf3))
+                   insert_nop = true;
+               }
+             break;
+
+           case CODE_FOR_sqrtdf2:
+             dest = REGNO (recog_data.operand[0]);
+             src1 = REGNO (recog_data.operand[1]);
+             /* Case 6:
+                        ld [address], %fx+1
+                        fsqrtd %fx, %fx  */
+             if (src1 == x && dest == src1)
+               insert_nop = true;
+             break;
+
+           default:
+             break;
+           }
+       }
+      else
+       next = NEXT_INSN (insn);
+
+      if (insert_nop)
+       emit_insn_after (gen_nop (), insn);
+    }
+}
+
 /* How to allocate a 'struct machine_function'.  */
 
 static struct machine_function *
index 131db42..ca16e6d 100644 (file)
@@ -184,6 +184,11 @@ mstd-struct-return
 Target Report RejectNegative Var(sparc_std_struct_return)
 Enable strict 32-bit psABI struct return checking.
 
+mfix-at697f
+Target Report RejectNegative Var(sparc_fix_at697f)
+Enable workaround for single erratum of AT697F processor
+(corresponding to erratum #13 of AT697E processor)
+
 Mask(LITTLE_ENDIAN)
 ;; Generate code for little-endian
 
index 8be5e25..4df10ab 100644 (file)
@@ -885,7 +885,8 @@ See RS/6000 and PowerPC Options.
 -munaligned-doubles  -mno-unaligned-doubles @gol
 -mv8plus  -mno-v8plus  -mvis  -mno-vis @gol
 -mvis2  -mno-vis2  -mvis3  -mno-vis3 @gol
--mfmaf  -mno-fmaf  -mpopc  -mno-popc}
+-mfmaf  -mno-fmaf  -mpopc  -mno-popc @gol
+-mfix-at697f}
 
 @emph{SPU Options}
 @gccoptlist{-mwarn-reloc -merror-reloc @gol
@@ -4001,19 +4002,19 @@ The message is in keeping with the output of @option{-fstack-usage}.
 If the stack usage is fully static but exceeds the specified amount, it's:
 
 @smallexample
-  warning: stack usage is 1120 bytes
+  warning: stack usage is 1120 bytes
 @end smallexample
 @item
 If the stack usage is (partly) dynamic but bounded, it's:
 
 @smallexample
-  warning: stack usage might be 1648 bytes
+  warning: stack usage might be 1648 bytes
 @end smallexample
 @item
 If the stack usage is (partly) dynamic and not bounded, it's:
 
 @smallexample
-  warning: stack usage might be unbounded
+  warning: stack usage might be unbounded
 @end smallexample
 @end itemize
 
@@ -17549,6 +17550,11 @@ With @option{-mfmaf}, GCC generates code that takes advantage of the UltraSPARC
 Fused Multiply-Add Floating-point extensions.  The default is @option{-mfmaf}
 when targetting a cpu that supports such instructions, such as Niagara-3 and
 later.
+
+@item -mfix-at697f
+@opindex mfix-at697f
+Enable the documented workaround for the single erratum of the Atmel AT697F
+processor (which corresponds to erratum #13 of the AT697E processor).
 @end table
 
 These @samp{-m} options are supported in addition to the above