From 1cb36a981d95f29f37fef511b88a04c48cfa90cc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 2 Aug 1999 15:58:04 -0700 Subject: [PATCH] Jakub Jelinek * config/sparc/sparc.h (ASM_DECLARE_REGISTER_GLOBAL): New macro. (RTX_OK_FOR_OLO10): Likewise. (GO_IF_LEGITIMATE_ADDRESS): If assembler supports offsetable %lo(), allow it in addresses... (PRINT_OPERAND_ADDRESS): ... and print it appropriately. * config/sparc/sparc.md (sethi_di_medlow_embmedany_pic): sethi %lo() does not make sense. * config/sparc/sparc.c (sparc_hard_reg_printed): New array. (sparc_output_scratch_registers): New function. (output_function_prologue, sparc_flat_output_function_prologue): Use it. * varasm.c (make_decl_rtl): Use ASM_DECLARE_REGISTER_GLOBAL if defined. * tm.texi (ASM_DECLARE_REGISTER_GLOBAL): Document it. * configure.in: Add check for .register pseudo-op support in as and check for offsetable %lo(). * acconfig.h: Add templates for the above checks. * configure: Regenerate. Richard Henderson * sparc/linux64.h (TARGET_DEFAULT): Remove MASK_APP_REGS. * sparc/sol2-sld-64.h (TARGET_DEFAULT): Likewise. * sparc/sol2.h (TARGET_DEFAULT): Likewise. From-SVN: r28414 --- gcc/ChangeLog | 27 ++++++++++ gcc/acconfig.h | 6 +++ gcc/config/sparc/linux64.h | 2 +- gcc/config/sparc/sol2-sld-64.h | 2 +- gcc/config/sparc/sol2.h | 2 +- gcc/config/sparc/sparc.c | 32 ++++++++++++ gcc/config/sparc/sparc.h | 92 ++++++++++++++++++++++++++++++---- gcc/config/sparc/sparc.md | 2 +- gcc/configure | 66 +++++++++++++++++++++--- gcc/configure.in | 58 +++++++++++++++++++-- gcc/tm.texi | 9 ++++ gcc/varasm.c | 3 ++ 12 files changed, 277 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d8443197009..315a061272e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +1999-08-02 Jakub Jelinek + + * config/sparc/sparc.h (ASM_DECLARE_REGISTER_GLOBAL): New macro. + (RTX_OK_FOR_OLO10): Likewise. + (GO_IF_LEGITIMATE_ADDRESS): If assembler supports offsetable + %lo(), allow it in addresses... + (PRINT_OPERAND_ADDRESS): ... and print it appropriately. + * config/sparc/sparc.md (sethi_di_medlow_embmedany_pic): sethi %lo() + does not make sense. + * config/sparc/sparc.c (sparc_hard_reg_printed): New array. + (sparc_output_scratch_registers): New function. + (output_function_prologue, sparc_flat_output_function_prologue): Use + it. + * varasm.c (make_decl_rtl): Use ASM_DECLARE_REGISTER_GLOBAL if + defined. + * tm.texi (ASM_DECLARE_REGISTER_GLOBAL): Document it. + * configure.in: Add check for .register pseudo-op support in as and + check for offsetable %lo(). + * acconfig.h: Add templates for the above checks. + * configure: Regenerate. + +1999-08-02 Richard Henderson + + * sparc/linux64.h (TARGET_DEFAULT): Remove MASK_APP_REGS. + * sparc/sol2-sld-64.h (TARGET_DEFAULT): Likewise. + * sparc/sol2.h (TARGET_DEFAULT): Likewise. + Mon Aug 2 23:46:45 1999 J"orn Rennecke * loop.c (strength_reduce): When doing biv->giv conversion, fix up diff --git a/gcc/acconfig.h b/gcc/acconfig.h index d702b0e0222..18fe2115571 100644 --- a/gcc/acconfig.h +++ b/gcc/acconfig.h @@ -29,6 +29,12 @@ /* Define if your assembler supports .balign and .p2align. */ #undef HAVE_GAS_BALIGN_AND_P2ALIGN +/* Define if your assembler supports offsetable %lo(). */ +#undef HAVE_AS_OFFSETABLE_LO10 + +/* Define if your assembler supports .register. */ +#undef HAVE_AS_REGISTER_PSEUDO_OP + /* Define if your assembler supports .subsection and .subsection -1 starts emitting at the beginning of your section */ #undef HAVE_GAS_SUBSECTION_ORDERING diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h index cc01c76510c..36216761e30 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 aa107a8b9e4..ac4f53b247b 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 9274f9d9108..c6091b20747 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 e3cebf31cf4..1d3bbc722f9 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 0ed73fcd99a..e42554dddda 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 34e311f1620..e8390961dca 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")]) diff --git a/gcc/configure b/gcc/configure index dea5c9a83d9..634da9aae59 100755 --- a/gcc/configure +++ b/gcc/configure @@ -8325,10 +8325,62 @@ EOF fi echo "$ac_t""$gcc_cv_as_subsections" 1>&6 -echo $ac_n "checking assembler instructions""... $ac_c" 1>&6 -echo "configure:8330: checking assembler instructions" >&5 -gcc_cv_as_instructions= -if test x$gcc_cv_as != x; then +case "$target" in + sparc*-*-*) + echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6 +echo "configure:8332: checking assembler .register pseudo-op support" >&5 + gcc_cv_as_register_pseudo_op= + if test x$gcc_cv_as != x; then + # Check if we have .register + echo ".register %g2, #scratch" > conftest.s + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_register_pseudo_op=yes + cat >> confdefs.h <<\EOF +#define HAVE_AS_REGISTER_PSEUDO_OP 1 +EOF + + fi + rm -f conftest.s conftest.o + fi + echo "$ac_t""$gcc_cv_as_register_pseudo_op" 1>&6 + + echo $ac_n "checking assembler offsetable %lo() support""... $ac_c" 1>&6 +echo "configure:8349: checking assembler offsetable %lo() support" >&5 + gcc_cv_as_offsetable_lo10= + if test x$gcc_cv_as != x; then + # Check if assembler has offsetable %lo() + echo "or %g1, %lo(ab) + 12, %g1" > conftest.s + echo "or %g1, %lo(ab + 12), %g1" > conftest1.s + gcc_cv_as_flags64="-xarch=v9" + if ! $gcc_cv_as $gcc_cv_as_flags64 -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_flags64="-64" + if ! $gcc_cv_as $gcc_cv_as_flags64 -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_flags64="" + fi + fi + if test -n "$gcc_cv_as_flags64" ; then + if $gcc_cv_as $gcc_cv_as_flags64 -o conftest1.o conftest1.s > /dev/null 2>&1; then + if cmp conftest.o conftest1.o > /dev/null 2>&1; then + : + else + gcc_cv_as_offsetable_lo10=yes + cat >> confdefs.h <<\EOF +#define HAVE_AS_OFFSETABLE_LO10 1 +EOF + + fi + fi + fi + rm -f conftest.s conftest.o conftest1.s conftest1.o + fi + echo "$ac_t""$gcc_cv_as_offsetable_lo10" 1>&6 + ;; + + i[34567]86-*-*) + echo $ac_n "checking assembler instructions""... $ac_c" 1>&6 +echo "configure:8382: checking assembler instructions" >&5 + gcc_cv_as_instructions= + if test x$gcc_cv_as != x; then set "filds fists" "filds mem; fists mem" while test $# -gt 0 do @@ -8343,8 +8395,10 @@ EOF shift 2 done rm -f conftest.s conftest.o -fi -echo "$ac_t""$gcc_cv_as_instructions" 1>&6 + fi + echo "$ac_t""$gcc_cv_as_instructions" 1>&6 + ;; +esac # Figure out what language subdirectories are present. # Look if the user specified --enable-languages="..."; if not, use diff --git a/gcc/configure.in b/gcc/configure.in index a813cfc12ef..86027482798 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -4153,9 +4153,55 @@ EOF fi AC_MSG_RESULT($gcc_cv_as_subsections) -AC_MSG_CHECKING(assembler instructions) -gcc_cv_as_instructions= -if test x$gcc_cv_as != x; then +case "$target" in + sparc*-*-*) + AC_MSG_CHECKING(assembler .register pseudo-op support) + gcc_cv_as_register_pseudo_op= + if test x$gcc_cv_as != x; then + # Check if we have .register + echo ".register %g2, #scratch" > conftest.s + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_register_pseudo_op=yes + AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP) + fi + rm -f conftest.s conftest.o + fi + AC_MSG_RESULT($gcc_cv_as_register_pseudo_op) + + AC_MSG_CHECKING([assembler offsetable %lo() support]) + gcc_cv_as_offsetable_lo10= + if test x$gcc_cv_as != x; then + # Check if assembler has offsetable %lo() + echo "or %g1, %lo(ab) + 12, %g1" > conftest.s + echo "or %g1, %lo(ab + 12), %g1" > conftest1.s + gcc_cv_as_flags64="-xarch=v9" + if ! $gcc_cv_as $gcc_cv_as_flags64 -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_flags64="-64" + if ! $gcc_cv_as $gcc_cv_as_flags64 -o conftest.o conftest.s > /dev/null 2>&1; then + gcc_cv_as_flags64="" + fi + fi + if test -n "$gcc_cv_as_flags64" ; then + if $gcc_cv_as $gcc_cv_as_flags64 -o conftest1.o conftest1.s > /dev/null 2>&1; then + if cmp conftest.o conftest1.o > /dev/null 2>&1; then + : + else + gcc_cv_as_offsetable_lo10=yes + AC_DEFINE(HAVE_AS_OFFSETABLE_LO10) + fi + fi + fi + rm -f conftest.s conftest.o conftest1.s conftest1.o + fi + AC_MSG_RESULT($gcc_cv_as_offsetable_lo10) + ;; + +changequote(,)dnl + i[34567]86-*-*) +changequote([,])dnl + AC_MSG_CHECKING(assembler instructions) + gcc_cv_as_instructions= + if test x$gcc_cv_as != x; then set "filds fists" "filds mem; fists mem" while test $# -gt 0 do @@ -4167,8 +4213,10 @@ if test x$gcc_cv_as != x; then shift 2 done rm -f conftest.s conftest.o -fi -AC_MSG_RESULT($gcc_cv_as_instructions) + fi + AC_MSG_RESULT($gcc_cv_as_instructions) + ;; +esac # Figure out what language subdirectories are present. # Look if the user specified --enable-languages="..."; if not, use diff --git a/gcc/tm.texi b/gcc/tm.texi index 2641a9ded89..32593d9c7a5 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -5591,6 +5591,15 @@ label definition (perhaps using @code{ASM_OUTPUT_LABEL}). The argument If this macro is not defined, then the variable name is defined in the usual manner as a label (by means of @code{ASM_OUTPUT_LABEL}). +@findex ASM_DECLARE_REGISTER_GLOBAL +@item ASM_DECLARE_REGISTER_GLOBAL (@var{stream}, @var{decl}, @var{regno}, @var{name}) +A C statement (sans semicolon) to output to the stdio stream +@var{stream} any text necessary for claiming a register @var{regno} +for a global variable @var{decl} with name @var{name}. + +If you don't define this macro, that is equivalent to defining it to do +nothing. + @findex ASM_FINISH_DECLARE_OBJECT @item ASM_FINISH_DECLARE_OBJECT (@var{stream}, @var{decl}, @var{toplevel}, @var{atend}) A C statement (sans semicolon) to finish up declaring a variable name diff --git a/gcc/varasm.c b/gcc/varasm.c index 2c015fbc5ad..e429cd285fc 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -704,6 +704,9 @@ make_decl_rtl (decl, asmspec, top_level) { /* Make this register global, so not usable for anything else. */ +#ifdef ASM_DECLARE_REGISTER_GLOBAL + ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, name); +#endif nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl)); while (nregs > 0) globalize_reg (reg_number + --nregs); -- 2.30.2