aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r--gcc/config/sparc/linux64.h2
-rw-r--r--gcc/config/sparc/sol2-sld-64.h2
-rw-r--r--gcc/config/sparc/sol2.h2
-rw-r--r--gcc/config/sparc/sparc.c32
-rw-r--r--gcc/config/sparc/sparc.h92
-rw-r--r--gcc/config/sparc/sparc.md2
6 files changed, 119 insertions, 13 deletions
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index cc01c76..3621676 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \
- + MASK_STACK_BIAS + MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+ + MASK_STACK_BIAS + MASK_EPILOGUE + MASK_FPU)
#endif
/* Output at beginning of assembler file. */
diff --git a/gcc/config/sparc/sol2-sld-64.h b/gcc/config/sparc/sol2-sld-64.h
index aa107a8..ac4f53b 100644
--- a/gcc/config/sparc/sol2-sld-64.h
+++ b/gcc/config/sparc/sol2-sld-64.h
@@ -18,7 +18,7 @@
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ + \
- MASK_STACK_BIAS + MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+ MASK_STACK_BIAS + MASK_EPILOGUE + MASK_FPU)
#endif
/* The default code model. */
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 9274f9d..c6091b2 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -213,7 +213,7 @@ Boston, MA 02111-1307, USA. */
/* Solaris allows 64 bit out and global registers in 32 bit mode.
sparc_override_options will disable V8+ if not generating V9 code. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU + MASK_V8PLUS)
+#define TARGET_DEFAULT (MASK_EPILOGUE + MASK_FPU + MASK_V8PLUS)
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index e3cebf3..1d3bbc7 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -141,6 +141,8 @@ int sparc_align_loops;
int sparc_align_jumps;
int sparc_align_funcs;
+char sparc_hard_reg_printed[8];
+
struct sparc_cpu_select sparc_select[] =
{
/* switch name, tune arch */
@@ -3108,6 +3110,32 @@ build_big_number (file, num, reg)
}
}
+/* Output any necessary .register pseudo-ops. */
+void
+sparc_output_scratch_registers (file)
+ FILE *file;
+{
+#ifdef HAVE_AS_REGISTER_PSEUDO_OP
+ int i;
+
+ if (TARGET_ARCH32)
+ return;
+
+ /* Check if %g[2367] were used without
+ .register being printed for them already. */
+ for (i = 2; i < 8; i++)
+ {
+ if (regs_ever_live [i]
+ && ! sparc_hard_reg_printed [i])
+ {
+ sparc_hard_reg_printed [i] = 1;
+ fprintf (file, "\t.register\t%%g%d, #scratch\n", i);
+ }
+ if (i == 3) i = 5;
+ }
+#endif
+}
+
/* Output code for the function prologue. */
void
@@ -3116,6 +3144,8 @@ output_function_prologue (file, size, leaf_function)
int size;
int leaf_function;
{
+ sparc_output_scratch_registers (file);
+
/* Need to use actual_fsize, since we are also allocating
space for our callee (and our own register save area). */
actual_fsize = compute_frame_size (size, leaf_function);
@@ -5849,6 +5879,8 @@ sparc_flat_output_function_prologue (file, size)
char *sp_str = reg_names[STACK_POINTER_REGNUM];
unsigned long gmask = current_frame_info.gmask;
+ sparc_output_scratch_registers (file);
+
/* This is only for the human reader. */
fprintf (file, "\t%s#PROLOGUE# 0\n", ASM_COMMENT_START);
fprintf (file, "\t%s# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 0ed73fc..e42554d 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1822,6 +1822,31 @@ do { \
ASM_OUTPUT_LABEL (FILE, NAME); \
} while (0)
+/* Output the special assembly code needed to tell the assembler some
+ register is used as global register variable. */
+
+#ifdef HAVE_AS_REGISTER_PSEUDO_OP
+#define ASM_DECLARE_REGISTER_GLOBAL(FILE, DECL, REGNO, NAME) \
+do { \
+ if (TARGET_ARCH64) \
+ { \
+ int __end = HARD_REGNO_NREGS ((REGNO), DECL_MODE (decl)) + (REGNO); \
+ int __reg; \
+ extern char sparc_hard_reg_printed[8]; \
+ for (__reg = (REGNO); __reg < 8 && __reg < __end; __reg++) \
+ if ((__reg & ~1) == 2 || (__reg & ~1) == 6) \
+ { \
+ if (__reg == (REGNO)) \
+ fprintf ((FILE), "\t.register\t%%g%d, %s\n", __reg, (NAME)); \
+ else \
+ fprintf ((FILE), "\t.register\t%%g%d, .gnu.part%d.%s\n", \
+ __reg, __reg - (REGNO), (NAME)); \
+ sparc_hard_reg_printed[__reg] = 1; \
+ } \
+ } \
+} while (0)
+#endif
+
/* This macro generates the assembly code for function entry.
FILE is a stdio stream to output the code to.
SIZE is an int: how many units of temporary storage to allocate.
@@ -2233,6 +2258,14 @@ extern struct rtx_def *sparc_builtin_saveregs ();
: 0))
#endif
+/* Should gcc use [%reg+%lo(xx)+offset] addresses? */
+
+#ifdef HAVE_AS_OFFSETABLE_LO10
+#define USE_AS_OFFSETABLE_LO10 1
+#else
+#define USE_AS_OFFSETABLE_LO10 0
+#endif
+
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression
@@ -2257,6 +2290,9 @@ extern struct rtx_def *sparc_builtin_saveregs ();
#define RTX_OK_FOR_OFFSET_P(X) \
(GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000)
+
+#define RTX_OK_FOR_OLO10_P(X) \
+ (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (RTX_OK_FOR_BASE_P (X)) \
@@ -2308,6 +2344,30 @@ extern struct rtx_def *sparc_builtin_saveregs ();
|| RTX_OK_FOR_OFFSET_P (op0)) \
goto ADDR; \
} \
+ else if (USE_AS_OFFSETABLE_LO10 \
+ && GET_CODE (op0) == LO_SUM \
+ && TARGET_ARCH64 \
+ && ! TARGET_CM_MEDMID \
+ && RTX_OK_FOR_OLO10_P (op1)) \
+ { \
+ register rtx op00 = XEXP (op0, 0); \
+ register rtx op01 = XEXP (op0, 1); \
+ if (RTX_OK_FOR_BASE_P (op00) \
+ && CONSTANT_P (op01)) \
+ goto ADDR; \
+ } \
+ else if (USE_AS_OFFSETABLE_LO10 \
+ && GET_CODE (op1) == LO_SUM \
+ && TARGET_ARCH64 \
+ && ! TARGET_CM_MEDMID \
+ && RTX_OK_FOR_OLO10_P (op0)) \
+ { \
+ register rtx op10 = XEXP (op1, 0); \
+ register rtx op11 = XEXP (op1, 1); \
+ if (RTX_OK_FOR_BASE_P (op10) \
+ && CONSTANT_P (op11)) \
+ goto ADDR; \
+ } \
} \
else if (GET_CODE (X) == LO_SUM) \
{ \
@@ -3115,15 +3175,29 @@ do { \
offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
else \
base = XEXP (addr, 0), index = XEXP (addr, 1); \
- fputs (reg_names[REGNO (base)], FILE); \
- if (index == 0) \
- fprintf (FILE, "%+d", offset); \
- else if (GET_CODE (index) == REG) \
- fprintf (FILE, "+%s", reg_names[REGNO (index)]); \
- else if (GET_CODE (index) == SYMBOL_REF \
- || GET_CODE (index) == CONST) \
- fputc ('+', FILE), output_addr_const (FILE, index); \
- else abort (); \
+ if (GET_CODE (base) == LO_SUM) \
+ { \
+ if (! USE_AS_OFFSETABLE_LO10 \
+ || TARGET_ARCH32 \
+ || TARGET_CM_MEDMID) \
+ abort (); \
+ output_operand (XEXP (base, 0), 0); \
+ fputs ("+%lo(", FILE); \
+ output_address (XEXP (base, 1)); \
+ fprintf (FILE, ")+%d", offset); \
+ } \
+ else \
+ { \
+ fputs (reg_names[REGNO (base)], FILE); \
+ if (index == 0) \
+ fprintf (FILE, "%+d", offset); \
+ else if (GET_CODE (index) == REG) \
+ fprintf (FILE, "+%s", reg_names[REGNO (index)]); \
+ else if (GET_CODE (index) == SYMBOL_REF \
+ || GET_CODE (index) == CONST) \
+ fputc ('+', FILE), output_addr_const (FILE, index); \
+ else abort (); \
+ } \
} \
else if (GET_CODE (addr) == MINUS \
&& GET_CODE (XEXP (addr, 1)) == LABEL_REF) \
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 34e311f..e839096 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -2495,7 +2495,7 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
"(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
- "sethi\\t%%lo(%a1), %0"
+ "sethi\\t%%hi(%a1), %0"
[(set_attr "type" "move")
(set_attr "length" "1")])