Jakub Jelinek <jj@ultra.linux.cz>

* 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  <rth@cygnus.com>

        * 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
This commit is contained in:
Richard Henderson 1999-08-02 15:58:04 -07:00
parent e76d23764b
commit 1cb36a981d
12 changed files with 277 additions and 24 deletions

View File

@ -1,3 +1,30 @@
1999-08-02 Jakub Jelinek <jj@ultra.linux.cz>
* 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 <rth@cygnus.com>
* 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 <amylaar@cygnus.co.uk> Mon Aug 2 23:46:45 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* loop.c (strength_reduce): When doing biv->giv conversion, fix up * loop.c (strength_reduce): When doing biv->giv conversion, fix up

View File

@ -29,6 +29,12 @@
/* Define if your assembler supports .balign and .p2align. */ /* Define if your assembler supports .balign and .p2align. */
#undef HAVE_GAS_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 /* Define if your assembler supports .subsection and .subsection -1 starts
emitting at the beginning of your section */ emitting at the beginning of your section */
#undef HAVE_GAS_SUBSECTION_ORDERING #undef HAVE_GAS_SUBSECTION_ORDERING

View File

@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT #undef TARGET_DEFAULT
#define TARGET_DEFAULT \ #define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \ (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 #endif
/* Output at beginning of assembler file. */ /* Output at beginning of assembler file. */

View File

@ -18,7 +18,7 @@
#undef TARGET_DEFAULT #undef TARGET_DEFAULT
#define TARGET_DEFAULT \ #define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ + \ (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 #endif
/* The default code model. */ /* The default code model. */

View File

@ -213,7 +213,7 @@ Boston, MA 02111-1307, USA. */
/* Solaris allows 64 bit out and global registers in 32 bit mode. /* Solaris allows 64 bit out and global registers in 32 bit mode.
sparc_override_options will disable V8+ if not generating V9 code. */ sparc_override_options will disable V8+ if not generating V9 code. */
#undef TARGET_DEFAULT #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 /* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes traps available which can get and set the condition codes

View File

@ -141,6 +141,8 @@ int sparc_align_loops;
int sparc_align_jumps; int sparc_align_jumps;
int sparc_align_funcs; int sparc_align_funcs;
char sparc_hard_reg_printed[8];
struct sparc_cpu_select sparc_select[] = struct sparc_cpu_select sparc_select[] =
{ {
/* switch name, tune arch */ /* 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. */ /* Output code for the function prologue. */
void void
@ -3116,6 +3144,8 @@ output_function_prologue (file, size, leaf_function)
int size; int size;
int leaf_function; int leaf_function;
{ {
sparc_output_scratch_registers (file);
/* Need to use actual_fsize, since we are also allocating /* Need to use actual_fsize, since we are also allocating
space for our callee (and our own register save area). */ space for our callee (and our own register save area). */
actual_fsize = compute_frame_size (size, leaf_function); 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]; char *sp_str = reg_names[STACK_POINTER_REGNUM];
unsigned long gmask = current_frame_info.gmask; unsigned long gmask = current_frame_info.gmask;
sparc_output_scratch_registers (file);
/* This is only for the human reader. */ /* This is only for the human reader. */
fprintf (file, "\t%s#PROLOGUE# 0\n", ASM_COMMENT_START); fprintf (file, "\t%s#PROLOGUE# 0\n", ASM_COMMENT_START);
fprintf (file, "\t%s# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n", fprintf (file, "\t%s# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",

View File

@ -1822,6 +1822,31 @@ do { \
ASM_OUTPUT_LABEL (FILE, NAME); \ ASM_OUTPUT_LABEL (FILE, NAME); \
} while (0) } 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. /* This macro generates the assembly code for function entry.
FILE is a stdio stream to output the code to. FILE is a stdio stream to output the code to.
SIZE is an int: how many units of temporary storage to allocate. SIZE is an int: how many units of temporary storage to allocate.
@ -2233,6 +2258,14 @@ extern struct rtx_def *sparc_builtin_saveregs ();
: 0)) : 0))
#endif #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 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction. that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression The MODE argument is the machine mode for the MEM expression
@ -2258,6 +2291,9 @@ extern struct rtx_def *sparc_builtin_saveregs ();
#define RTX_OK_FOR_OFFSET_P(X) \ #define RTX_OK_FOR_OFFSET_P(X) \
(GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000) (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) \ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (RTX_OK_FOR_BASE_P (X)) \ { if (RTX_OK_FOR_BASE_P (X)) \
goto ADDR; \ goto ADDR; \
@ -2308,6 +2344,30 @@ extern struct rtx_def *sparc_builtin_saveregs ();
|| RTX_OK_FOR_OFFSET_P (op0)) \ || RTX_OK_FOR_OFFSET_P (op0)) \
goto ADDR; \ 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) \ else if (GET_CODE (X) == LO_SUM) \
{ \ { \
@ -3115,6 +3175,19 @@ do { \
offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\ offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
else \ else \
base = XEXP (addr, 0), index = XEXP (addr, 1); \ base = XEXP (addr, 0), index = XEXP (addr, 1); \
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); \ fputs (reg_names[REGNO (base)], FILE); \
if (index == 0) \ if (index == 0) \
fprintf (FILE, "%+d", offset); \ fprintf (FILE, "%+d", offset); \
@ -3125,6 +3198,7 @@ do { \
fputc ('+', FILE), output_addr_const (FILE, index); \ fputc ('+', FILE), output_addr_const (FILE, index); \
else abort (); \ else abort (); \
} \ } \
} \
else if (GET_CODE (addr) == MINUS \ else if (GET_CODE (addr) == MINUS \
&& GET_CODE (XEXP (addr, 1)) == LABEL_REF) \ && GET_CODE (XEXP (addr, 1)) == LABEL_REF) \
{ \ { \

View File

@ -2495,7 +2495,7 @@
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))] (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
"(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)" "(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 "type" "move")
(set_attr "length" "1")]) (set_attr "length" "1")])

66
gcc/configure vendored
View File

@ -8325,10 +8325,62 @@ EOF
fi fi
echo "$ac_t""$gcc_cv_as_subsections" 1>&6 echo "$ac_t""$gcc_cv_as_subsections" 1>&6
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6 case "$target" in
echo "configure:8330: checking assembler instructions" >&5 sparc*-*-*)
gcc_cv_as_instructions= echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
if test x$gcc_cv_as != x; then 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" set "filds fists" "filds mem; fists mem"
while test $# -gt 0 while test $# -gt 0
do do
@ -8343,8 +8395,10 @@ EOF
shift 2 shift 2
done done
rm -f conftest.s conftest.o rm -f conftest.s conftest.o
fi fi
echo "$ac_t""$gcc_cv_as_instructions" 1>&6 echo "$ac_t""$gcc_cv_as_instructions" 1>&6
;;
esac
# Figure out what language subdirectories are present. # Figure out what language subdirectories are present.
# Look if the user specified --enable-languages="..."; if not, use # Look if the user specified --enable-languages="..."; if not, use

View File

@ -4153,9 +4153,55 @@ EOF
fi fi
AC_MSG_RESULT($gcc_cv_as_subsections) AC_MSG_RESULT($gcc_cv_as_subsections)
AC_MSG_CHECKING(assembler instructions) case "$target" in
gcc_cv_as_instructions= sparc*-*-*)
if test x$gcc_cv_as != x; then 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" set "filds fists" "filds mem; fists mem"
while test $# -gt 0 while test $# -gt 0
do do
@ -4167,8 +4213,10 @@ if test x$gcc_cv_as != x; then
shift 2 shift 2
done done
rm -f conftest.s conftest.o rm -f conftest.s conftest.o
fi fi
AC_MSG_RESULT($gcc_cv_as_instructions) AC_MSG_RESULT($gcc_cv_as_instructions)
;;
esac
# Figure out what language subdirectories are present. # Figure out what language subdirectories are present.
# Look if the user specified --enable-languages="..."; if not, use # Look if the user specified --enable-languages="..."; if not, use

View File

@ -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 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}). 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 @findex ASM_FINISH_DECLARE_OBJECT
@item ASM_FINISH_DECLARE_OBJECT (@var{stream}, @var{decl}, @var{toplevel}, @var{atend}) @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 A C statement (sans semicolon) to finish up declaring a variable name

View File

@ -704,6 +704,9 @@ make_decl_rtl (decl, asmspec, top_level)
{ {
/* Make this register global, so not usable for anything /* Make this register global, so not usable for anything
else. */ 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)); nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
while (nregs > 0) while (nregs > 0)
globalize_reg (reg_number + --nregs); globalize_reg (reg_number + --nregs);