elf.h: New file.

* config/xtensa/elf.h: New file.
        * config/xtensa/lib1funcs.asm: New file.
        * config/xtensa/lib2funcs.S: New file.
        * config/xtensa/linux.h: New file.
        * config/xtensa/t-xtensa: New file.
        * config/xtensa/xtensa-config.h: New file.
        * config/xtensa/xtensa-protos.h: New file.
        * config/xtensa/xtensa.c: New file.
        * config/xtensa/xtensa.h: New file.
        * config/xtensa/xtensa.md: New file.
        * config.gcc (xtensa-*-elf*): New target.
        (xtensa-*-linux*): New target.
        * cse.c (canon_hash): Compare rtx pointers instead of register
        numbers.  This is required for the Xtensa port.
        * integrate.c (copy_insn_list): Handle case where the static
        chain is in memory and the memory address has to be copied to
        a register.
        * doc/invoke.texi (Option Summary): Add Xtensa options.
        (Xtensa Options): New node.
        * doc/md.texi (Machine Constraints): Add Xtensa machine constraints.
        * gcc.c-torture/compile/20001226-1.x: xfail for Xtensa.

From-SVN: r49155
This commit is contained in:
Bob Wilson 2002-01-23 21:03:53 +00:00 committed by Bob Wilson
parent 5b1a76105b
commit 039843087a
18 changed files with 8137 additions and 11 deletions

View File

@ -1,3 +1,26 @@
2002-01-23 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/elf.h: New file.
* config/xtensa/lib1funcs.asm: New file.
* config/xtensa/lib2funcs.S: New file.
* config/xtensa/linux.h: New file.
* config/xtensa/t-xtensa: New file.
* config/xtensa/xtensa-config.h: New file.
* config/xtensa/xtensa-protos.h: New file.
* config/xtensa/xtensa.c: New file.
* config/xtensa/xtensa.h: New file.
* config/xtensa/xtensa.md: New file.
* config.gcc (xtensa-*-elf*): New target.
(xtensa-*-linux*): New target.
* cse.c (canon_hash): Compare rtx pointers instead of register
numbers. This is required for the Xtensa port.
* integrate.c (copy_insn_list): Handle case where the static
chain is in memory and the memory address has to be copied to
a register.
* doc/invoke.texi (Option Summary): Add Xtensa options.
(Xtensa Options): New node.
* doc/md.texi (Machine Constraints): Add Xtensa machine constraints.
2002-01-23 Zack Weinberg <zack@codesourcery.com>
* diagnostic.c (internal_error): Do ICE suppression only

View File

@ -3260,6 +3260,22 @@ xstormy16-*-elf)
tmake_file="stormy16/t-stormy16"
extra_parts="crtbegin.o crtend.o"
;;
xtensa-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h xtensa/elf.h"
with_newlib=yes
tmake_file=xtensa/t-xtensa
extra_parts="crtbegin.o crtend.o"
fixincludes=Makefile.in # newlib headers should be OK
;;
xtensa-*-linux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h xtensa/linux.h"
tmake_file="t-linux xtensa/t-xtensa"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
*)
echo "Configuration $machine not supported" 1>&2
exit 1

138
gcc/config/xtensa/elf.h Normal file
View File

@ -0,0 +1,138 @@
/* Xtensa/Elf configuration.
Derived from the configuration for GCC for Intel i386 running Linux.
Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (Xtensa/ELF)", stderr);
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#undef ASM_SPEC
#define ASM_SPEC "%{v} %{mno-density:--no-density} \
%{mtext-section-literals:--text-section-literals} \
%{mno-text-section-literals:--no-text-section-literals} \
%{mtarget-align:--target-align} \
%{mno-target-align:--no-target-align} \
%{mlongcalls:--longcalls} \
%{mno-longcalls:--no-longcalls}"
#undef ASM_FINAL_SPEC
#undef LIB_SPEC
#define LIB_SPEC "-lc -lsim -lc -lhandlers-sim"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt1-sim%O%s crti%O%s crtbegin%O%s _vectors%O%s"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
#undef LINK_SPEC
#define LINK_SPEC \
"%{shared:-shared} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{static:-static}}}"
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__XTENSA__ -D__ELF__ -Acpu=xtensa -Amachine=xtensa"
/* Local compiler-generated symbols must have a prefix that the assembler
understands. By default, this is $, although some targets (e.g.,
NetBSD-ELF) need to override this. */
#ifndef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
#endif
/* By default, external symbols do not have an underscore prepended. */
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
#endif
/* Define this macro if the assembler does not accept the character
"." in label names. By default constructors and destructors in G++
have names that use ".". If this macro is defined, these names
are rewritten to avoid ".". */
#define NO_DOT_IN_LABEL
/* Define NO_DOLLAR_IN_LABEL in your favorite tm file if your assembler
doesn't allow $ in symbol names. */
#undef NO_DOLLAR_IN_LABEL
/* Don't switch sections in the middle of a literal pool! */
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)
/* Do not force "-fpic" for this target. */
#define XTENSA_ALWAYS_PIC 0
/* Redefine the standard ELF version of ASM_DECLARE_FUNCTION_SIZE to
allow adding the ".end literal_prefix" directive at the end of the
function. */
#undef ASM_DECLARE_FUNCTION_SIZE
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
do \
{ \
if (!flag_inhibit_size_directive) \
{ \
char label[256]; \
static int labelno; \
\
labelno++; \
\
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
\
fprintf (FILE, "%s", SIZE_ASM_OP); \
assemble_name (FILE, (FNAME)); \
fprintf (FILE, ","); \
assemble_name (FILE, label); \
fprintf (FILE, "-"); \
assemble_name (FILE, (FNAME)); \
putc ('\n', FILE); \
} \
XTENSA_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL); \
} \
while (0)

View File

@ -0,0 +1,419 @@
/* Assembly functions for the Xtensa version of libgcc1.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "xtensa/xtensa-config.h"
#ifdef L_mulsi3
.align 4
.global __mulsi3
.type __mulsi3,@function
__mulsi3:
entry sp, 16
#if XCHAL_HAVE_MUL16
or a4, a2, a3
srai a4, a4, 16
bnez a4, .LMUL16
mul16u a2, a2, a3
retw
.LMUL16:
srai a4, a2, 16
srai a5, a3, 16
mul16u a7, a4, a3
mul16u a6, a5, a2
mul16u a4, a2, a3
add a7, a7, a6
slli a7, a7, 16
add a2, a7, a4
#elif XCHAL_HAVE_MAC16
mul.aa.hl a2, a3
mula.aa.lh a2, a3
rsr a5, 16 # ACCLO
umul.aa.ll a2, a3
rsr a4, 16 # ACCLO
slli a5, a5, 16
add a2, a4, a5
#else /* !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MAC16 */
# Multiply one bit at a time, but unroll the loop 4x to better
# exploit the addx instructions.
# Peel the first iteration to save a cycle on init
# avoid negative numbers
xor a5, a2, a3 # top bit is 1 iff one of the inputs is negative
abs a3, a3
abs a2, a2
# swap so that second argument is smaller
sub a7, a2, a3
mov a4, a3
movgez a4, a2, a7 # a4 = max(a2, a3)
movltz a3, a2, a7 # a3 = min(a2, a3)
movi a2, 0
extui a6, a3, 0, 1
movnez a2, a4, a6
addx2 a7, a4, a2
extui a6, a3, 1, 1
movnez a2, a7, a6
addx4 a7, a4, a2
extui a6, a3, 2, 1
movnez a2, a7, a6
addx8 a7, a4, a2
extui a6, a3, 3, 1
movnez a2, a7, a6
bgeui a3, 16, .Lmult_main_loop
neg a3, a2
movltz a2, a3, a5
retw
.align 4
.Lmult_main_loop:
srli a3, a3, 4
slli a4, a4, 4
add a7, a4, a2
extui a6, a3, 0, 1
movnez a2, a7, a6
addx2 a7, a4, a2
extui a6, a3, 1, 1
movnez a2, a7, a6
addx4 a7, a4, a2
extui a6, a3, 2, 1
movnez a2, a7, a6
addx8 a7, a4, a2
extui a6, a3, 3, 1
movnez a2, a7, a6
bgeui a3, 16, .Lmult_main_loop
neg a3, a2
movltz a2, a3, a5
#endif /* !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MAC16 */
retw
.Lfe0:
.size __mulsi3,.Lfe0-__mulsi3
#endif /* L_mulsi3 */
# Some Xtensa configurations include the NSAU (unsigned
# normalize shift amount) instruction which computes the number
# of leading zero bits. For other configurations, the "nsau"
# operation is implemented as a macro.
#if !XCHAL_HAVE_NSA
.macro nsau cnt, val, tmp, a
mov \a, \val
movi \cnt, 0
extui \tmp, \a, 16, 16
bnez \tmp, 0f
movi \cnt, 16
slli \a, \a, 16
0:
extui \tmp, \a, 24, 8
bnez \tmp, 1f
addi \cnt, \cnt, 8
slli \a, \a, 8
1:
movi \tmp, __nsau_data
extui \a, \a, 24, 8
add \tmp, \tmp, \a
l8ui \tmp, \tmp, 0
add \cnt, \cnt, \tmp
.endm
#endif /* !XCHAL_HAVE_NSA */
#ifdef L_nsau
.section .rodata
.align 4
.global __nsau_data
.type __nsau_data,@object
__nsau_data:
#if !XCHAL_HAVE_NSA
.byte 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4
.byte 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
.byte 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
.byte 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
.byte 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
.byte 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
.byte 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
.byte 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
#endif /* !XCHAL_HAVE_NSA */
.Lfe1:
.size __nsau_data,.Lfe1-__nsau_data
.hidden __nsau_data
#endif /* L_nsau */
#ifdef L_udivsi3
.align 4
.global __udivsi3
.type __udivsi3,@function
__udivsi3:
entry sp, 16
bltui a3, 2, .Lle_one # check if the divisor <= 1
mov a6, a2 # keep dividend in a6
#if XCHAL_HAVE_NSA
nsau a5, a6 # dividend_shift = nsau(dividend)
nsau a4, a3 # divisor_shift = nsau(divisor)
#else /* !XCHAL_HAVE_NSA */
nsau a5, a6, a2, a7 # dividend_shift = nsau(dividend)
nsau a4, a3, a2, a7 # divisor_shift = nsau(divisor)
#endif /* !XCHAL_HAVE_NSA */
bgeu a5, a4, .Lspecial
sub a4, a4, a5 # count = divisor_shift - dividend_shift
ssl a4
sll a3, a3 # divisor <<= count
movi a2, 0 # quotient = 0
# test-subtract-and-shift loop; one quotient bit on each iteration
loopnez a4, .Lloopend
bltu a6, a3, .Lzerobit
sub a6, a6, a3
addi a2, a2, 1
.Lzerobit:
slli a2, a2, 1
srli a3, a3, 1
.Lloopend:
bltu a6, a3, .Lreturn
addi a2, a2, 1 # increment quotient if dividend >= divisor
.Lreturn:
retw
.Lspecial:
# return dividend >= divisor
movi a2, 0
bltu a6, a3, .Lreturn2
movi a2, 1
.Lreturn2:
retw
.Lle_one:
beqz a3, .Lerror # if divisor == 1, return the dividend
retw
.Lerror:
movi a2, 0 # just return 0; could throw an exception
retw
.Lfe2:
.size __udivsi3,.Lfe2-__udivsi3
#endif /* L_udivsi3 */
#ifdef L_divsi3
.align 4
.global __divsi3
.type __divsi3,@function
__divsi3:
entry sp, 16
xor a7, a2, a3 # sign = dividend ^ divisor
abs a6, a2 # udividend = abs(dividend)
abs a3, a3 # udivisor = abs(divisor)
bltui a3, 2, .Lle_one # check if udivisor <= 1
#if XCHAL_HAVE_NSA
nsau a5, a6 # udividend_shift = nsau(udividend)
nsau a4, a3 # udivisor_shift = nsau(udivisor)
#else /* !XCHAL_HAVE_NSA */
nsau a5, a6, a2, a8 # udividend_shift = nsau(udividend)
nsau a4, a3, a2, a8 # udivisor_shift = nsau(udivisor)
#endif /* !XCHAL_HAVE_NSA */
bgeu a5, a4, .Lspecial
sub a4, a4, a5 # count = udivisor_shift - udividend_shift
ssl a4
sll a3, a3 # udivisor <<= count
movi a2, 0 # quotient = 0
# test-subtract-and-shift loop; one quotient bit on each iteration
loopnez a4, .Lloopend
bltu a6, a3, .Lzerobit
sub a6, a6, a3
addi a2, a2, 1
.Lzerobit:
slli a2, a2, 1
srli a3, a3, 1
.Lloopend:
bltu a6, a3, .Lreturn
addi a2, a2, 1 # increment quotient if udividend >= udivisor
.Lreturn:
neg a5, a2
movltz a2, a5, a7 # return (sign < 0) ? -quotient : quotient
retw
.Lspecial:
movi a2, 0
bltu a6, a3, .Lreturn2 # if dividend < divisor, return 0
movi a2, 1
movi a4, -1
movltz a2, a4, a7 # else return (sign < 0) ? -1 : 1
.Lreturn2:
retw
.Lle_one:
beqz a3, .Lerror
neg a2, a6 # if udivisor == 1, then return...
movgez a2, a6, a7 # (sign < 0) ? -udividend : udividend
retw
.Lerror:
movi a2, 0 # just return 0; could throw an exception
retw
.Lfe3:
.size __divsi3,.Lfe3-__divsi3
#endif /* L_divsi3 */
#ifdef L_umodsi3
.align 4
.global __umodsi3
.type __umodsi3,@function
__umodsi3:
entry sp, 16
bltui a3, 2, .Lle_one # check if the divisor is <= 1
#if XCHAL_HAVE_NSA
nsau a5, a2 # dividend_shift = nsau(dividend)
nsau a4, a3 # divisor_shift = nsau(divisor)
#else /* !XCHAL_HAVE_NSA */
nsau a5, a2, a6, a7 # dividend_shift = nsau(dividend)
nsau a4, a3, a6, a7 # divisor_shift = nsau(divisor)
#endif /* !XCHAL_HAVE_NSA */
bgeu a5, a4, .Lspecial
sub a4, a4, a5 # count = divisor_shift - dividend_shift
ssl a4
sll a3, a3 # divisor <<= count
# test-subtract-and-shift loop
loopnez a4, .Lloopend
bltu a2, a3, .Lzerobit
sub a2, a2, a3
.Lzerobit:
srli a3, a3, 1
.Lloopend:
bltu a2, a3, .Lreturn
sub a2, a2, a3 # subtract once more if dividend >= divisor
.Lreturn:
retw
.Lspecial:
bltu a2, a3, .Lreturn2
sub a2, a2, a3 # subtract once if dividend >= divisor
.Lreturn2:
retw
.Lle_one:
# the divisor is either 0 or 1, so just return 0.
# someday we may want to throw an exception if the divisor is 0.
movi a2, 0
retw
.Lfe4:
.size __umodsi3,.Lfe4-__umodsi3
#endif /* L_umodsi3 */
#ifdef L_modsi3
.align 4
.global __modsi3
.type __modsi3,@function
__modsi3:
entry sp, 16
mov a7, a2 # save original (signed) dividend
abs a2, a2 # udividend = abs(dividend)
abs a3, a3 # udivisor = abs(divisor)
bltui a3, 2, .Lle_one # check if udivisor <= 1
#if XCHAL_HAVE_NSA
nsau a5, a2 # udividend_shift = nsau(udividend)
nsau a4, a3 # udivisor_shift = nsau(udivisor)
#else /* !XCHAL_HAVE_NSA */
nsau a5, a2, a6, a8 # udividend_shift = nsau(udividend)
nsau a4, a3, a6, a8 # udivisor_shift = nsau(udivisor)
#endif /* !XCHAL_HAVE_NSA */
bgeu a5, a4, .Lspecial
sub a4, a4, a5 # count = udivisor_shift - udividend_shift
ssl a4
sll a3, a3 # udivisor <<= count
# test-subtract-and-shift loop
loopnez a4, .Lloopend
bltu a2, a3, .Lzerobit
sub a2, a2, a3
.Lzerobit:
srli a3, a3, 1
.Lloopend:
bltu a2, a3, .Lreturn
sub a2, a2, a3 # subtract once more if udividend >= udivisor
.Lreturn:
bgez a7, .Lpositive
neg a2, a2 # if (dividend < 0), return -udividend
.Lpositive:
retw
.Lspecial:
bltu a2, a3, .Lreturn2
sub a2, a2, a3 # subtract once if dividend >= divisor
.Lreturn2:
bgez a7, .Lpositive2
neg a2, a2 # if (dividend < 0), return -udividend
.Lpositive2:
retw
.Lle_one:
# udivisor is either 0 or 1, so just return 0.
# someday we may want to throw an exception if udivisor is 0.
movi a2, 0
retw
.Lfe5:
.size __modsi3,.Lfe5-__modsi3
#endif /* L_modsi3 */

View File

@ -0,0 +1,205 @@
/* Assembly functions for libgcc2.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "xtensa/xtensa-config.h"
/* __xtensa_libgcc_window_spill: This function uses a series of nested
calls to flush out all but the current register window. This is
used to set up the stack so that arbitrary frames can be accessed.
The functions used for the nested calls are also reused by the
nonlocal goto function below. */
.align 4
.global __xtensa_libgcc_window_spill
.type __xtensa_libgcc_window_spill,@function
__xtensa_libgcc_window_spill:
entry sp, 48
call4 .L__wdwspill_assist52 // called with call8, only need a call4
retw
.size __xtensa_libgcc_window_spill,.-__xtensa_libgcc_window_spill
.align 4
.L__wdwspill_assist56:
entry sp, 16
call4 .L__wdwspill_assist52
retw
.align 4
.L__wdwspill_assist52:
entry sp, 48
call12 .L__wdwspill_assist40
retw
.align 4
.L__wdwspill_assist40:
entry sp, 48
call12 .L__wdwspill_assist28
retw
.align 4
.L__wdwspill_assist28:
entry sp, 48
call12 .L__wdwspill_assist16
retw
.align 4
.L__wdwspill_assist16:
entry sp, 16
movi a15, 0
retw
/* __xtensa_nonlocal_goto: This code does all the hard work of a
nonlocal goto on Xtensa. It is here in the library to avoid the
code size bloat of generating it in-line. There are two
arguments:
a2 = frame pointer for the procedure containing the label
a3 = goto handler address
This function never returns to its caller but instead goes directly
to the address of the specified goto handler. */
.align 4
.global __xtensa_nonlocal_goto
.type __xtensa_nonlocal_goto,@function
__xtensa_nonlocal_goto:
entry sp, 32
/* flush registers */
call8 .L__wdwspill_assist56
/* Because the save area for a0-a3 is stored one frame below
the one identified by a2, the only way to restore those
registers is to unwind the stack. If alloca() were never
called, we could just unwind until finding the sp value
matching a2. However, a2 is a frame pointer, not a stack
pointer, and may not be encountered during the unwinding.
The solution is to unwind until going _past_ the value
given by a2. This involves keeping three stack pointer
values during the unwinding:
next = sp of frame N-1
cur = sp of frame N
prev = sp of frame N+1
When next > a2, the desired save area is stored relative
to prev. At this point, cur will be the same as a2
except in the alloca() case.
Besides finding the values to be restored to a0-a3, we also
need to find the current window size for the target
function. This can be extracted from the high bits of the
return address, initially in a0. As the unwinding
proceeds, the window size is taken from the value of a0
saved _two_ frames below the current frame. */
addi a5, sp, -16 # a5 = prev - save area
l32i a6, a5, 4
addi a6, a6, -16 # a6 = cur - save area
mov a8, a0 # a8 = return address (for window size)
j .Lfirstframe
.Lnextframe:
l32i a8, a5, 0 # next return address (for window size)
mov a5, a6 # advance prev
addi a6, a7, -16 # advance cur
.Lfirstframe:
l32i a7, a6, 4 # a7 = next
bge a2, a7, .Lnextframe
/* At this point, prev (a5) points to the save area with the saved
values of a0-a3. Copy those values into the save area at the
current sp so they will be reloaded when the return from this
function underflows. We don't have to worry about exceptions
while updating the current save area, because the windows have
already been flushed. */
addi a4, sp, -16 # a4 = save area of this function
l32i a6, a5, 0
l32i a7, a5, 4
s32i a6, a4, 0
s32i a7, a4, 4
l32i a6, a5, 8
l32i a7, a5, 12
s32i a6, a4, 8
s32i a7, a4, 12
/* Set return address to goto handler. Use the window size bits
from the return address two frames below the target. */
extui a8, a8, 30, 2 # get window size from return addr.
slli a3, a3, 2 # get goto handler addr. << 2
ssai 2
src a0, a8, a3 # combine them with a funnel shift
retw
.size __xtensa_nonlocal_goto,.-__xtensa_nonlocal_goto
/* __xtensa_sync_caches: This function is called after writing a trampoline
on the stack to force all the data writes to memory and invalidate the
instruction cache. a2 is the address of the new trampoline.
After the trampoline data is written out, it must be flushed out of
the data cache into memory. We use DHWB in case we have a writeback
cache. At least one DHWB instruction is needed for each data cache
line which may be touched by the trampoline. An ISYNC instruction
must follow the DHWBs.
We have to flush the i-cache to make sure that the new values get used.
At least one IHI instruction is needed for each i-cache line which may
be touched by the trampoline. An ISYNC instruction is also needed to
make sure that the modified instructions are loaded into the instruction
fetch buffer. */
#define TRAMPOLINE_SIZE 49
.text
.align 4
.global __xtensa_sync_caches
.type __xtensa_sync_caches,@function
__xtensa_sync_caches:
entry sp, 32
#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
# Flush the trampoline from the data cache
extui a4, a2, 0, XCHAL_DCACHE_LINEWIDTH
addi a4, a4, TRAMPOLINE_SIZE
addi a4, a4, (1 << XCHAL_DCACHE_LINEWIDTH) - 1
srli a4, a4, XCHAL_DCACHE_LINEWIDTH
mov a3, a2
.Ldcache_loop:
dhwb a3, 0
addi a3, a3, (1 << XCHAL_DCACHE_LINEWIDTH)
addi a4, a4, -1
bnez a4, .Ldcache_loop
isync
#endif
#if XCHAL_ICACHE_SIZE > 0
# Invalidate the corresponding lines in the instruction cache
extui a4, a2, 0, XCHAL_ICACHE_LINEWIDTH
addi a4, a4, TRAMPOLINE_SIZE
addi a4, a4, (1 << XCHAL_ICACHE_LINEWIDTH) - 1
srli a4, a4, XCHAL_ICACHE_LINEWIDTH
.Licache_loop:
ihi a2, 0
addi a2, a2, (1 << XCHAL_ICACHE_LINEWIDTH)
addi a4, a4, -1
bnez a4, .Licache_loop
isync
#endif
retw
.size __xtensa_sync_caches,.-__xtensa_sync_caches

94
gcc/config/xtensa/linux.h Normal file
View File

@ -0,0 +1,94 @@
/* Xtensa Linux configuration.
Derived from the configuration for GCC for Intel i386 running Linux.
Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (Xtensa GNU/Linux with ELF)", stderr);
#undef ASM_SPEC
#define ASM_SPEC "%{v} %{mno-density:--no-density} \
%{mtext-section-literals:--text-section-literals} \
%{mno-text-section-literals:--no-text-section-literals} \
%{mtarget-align:--target-align} \
%{mno-target-align:--no-target-align} \
%{mlongcalls:--longcalls} \
%{mno-longcalls:--no-longcalls}"
#undef ASM_FINAL_SPEC
#undef LIB_SPEC
#define LIB_SPEC \
"%{shared: -lc} \
%{!shared: %{pthread:-lpthread} \
%{profile:-lc_p} %{!profile: -lc}}"
#undef LINK_SPEC
#define LINK_SPEC \
"%{shared:-shared} \
%{!shared: \
%{!ibcs: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
%{static:-static}}}"
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-D__XTENSA__ -D__ELF__ -Acpu=xtensa -Amachine=xtensa \
-Dunix -Dlinux -Asystem=posix"
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
/* Don't switch sections in the middle of a literal pool! */
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)
/* Always enable "-fpic" for Xtensa Linux. */
#define XTENSA_ALWAYS_PIC 1
/* Redefine the standard ELF version of ASM_DECLARE_FUNCTION_SIZE to
allow adding the ".end literal_prefix" directive at the end of the
function. */
#undef ASM_DECLARE_FUNCTION_SIZE
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
do \
{ \
if (!flag_inhibit_size_directive) \
{ \
char label[256]; \
static int labelno; \
\
labelno++; \
\
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
\
fprintf (FILE, "%s", SIZE_ASM_OP); \
assemble_name (FILE, (FNAME)); \
fprintf (FILE, ","); \
assemble_name (FILE, label); \
fprintf (FILE, "-"); \
assemble_name (FILE, (FNAME)); \
putc ('\n', FILE); \
} \
XTENSA_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL); \
} \
while (0)

View File

@ -0,0 +1,28 @@
# Use GCC's floating-point emulation code
LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
dp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c > dp-bit.c
fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
########################################################################
# Skip the libgcc1 test.
LIBGCC1_TEST =
# Don't run fixproto
STMP_FIXPROTO =
# Build crtbegin and crtend with the "longcalls" option
CRTSTUFF_T_CFLAGS += -mlongcalls
CROSS_LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = xtensa/lib1funcs.asm
LIB1ASMFUNCS = _mulsi3 _nsau _divsi3 _modsi3 _udivsi3 _umodsi3
TARGET_LIBGCC2_CFLAGS += -mlongcalls
LIB2FUNCS_EXTRA += $(srcdir)/config/xtensa/lib2funcs.S

View File

@ -0,0 +1,50 @@
/* Xtensa configuration settings.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef XTENSA_CONFIG_H
#define XTENSA_CONFIG_H
#define XCHAL_HAVE_BE 1
#define XCHAL_HAVE_DENSITY 1
#define XCHAL_HAVE_MAC16 0
#define XCHAL_HAVE_MUL16 0
#define XCHAL_HAVE_MUL32 0
#define XCHAL_HAVE_DIV32 0
#define XCHAL_HAVE_NSA 1
#define XCHAL_HAVE_MINMAX 0
#define XCHAL_HAVE_SEXT 0
#define XCHAL_HAVE_BOOLEANS 0
#define XCHAL_HAVE_FP 0
#define XCHAL_HAVE_FP_DIV 0
#define XCHAL_HAVE_FP_RECIP 0
#define XCHAL_HAVE_FP_SQRT 0
#define XCHAL_HAVE_FP_RSQRT 0
#define XCHAL_ICACHE_SIZE 8192
#define XCHAL_DCACHE_SIZE 8192
#define XCHAL_ICACHE_LINESIZE 16
#define XCHAL_DCACHE_LINESIZE 16
#define XCHAL_ICACHE_LINEWIDTH 4
#define XCHAL_DCACHE_LINEWIDTH 4
#define XCHAL_DCACHE_IS_WRITEBACK 0
#define XCHAL_HAVE_MMU 1
#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 12
#endif /* !XTENSA_CONFIG_H */

View File

@ -0,0 +1,116 @@
/* Prototypes of target machine for GNU compiler for Xtensa.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef __XTENSA_PROTOS_H__
#define __XTENSA_PROTOS_H__
/* Functions to test whether an immediate fits in a given field. */
extern int xtensa_simm7 PARAMS ((int));
extern int xtensa_simm8 PARAMS ((int));
extern int xtensa_simm8x256 PARAMS ((int));
extern int xtensa_simm12b PARAMS ((int));
extern int xtensa_uimm8 PARAMS ((int));
extern int xtensa_uimm8x2 PARAMS ((int));
extern int xtensa_uimm8x4 PARAMS ((int));
extern int xtensa_ai4const PARAMS ((int));
extern int xtensa_lsi4x4 PARAMS ((int));
extern int xtensa_b4const PARAMS ((int));
extern int xtensa_b4constu PARAMS ((int));
extern int xtensa_tp7 PARAMS ((int));
/* Functions within xtensa.c that we reference. */
#ifdef RTX_CODE
extern int xt_true_regnum PARAMS ((rtx));
extern int add_operand PARAMS ((rtx, enum machine_mode));
extern int arith_operand PARAMS ((rtx, enum machine_mode));
extern int nonimmed_operand PARAMS ((rtx, enum machine_mode));
extern int mem_operand PARAMS ((rtx, enum machine_mode));
extern int non_acc_reg_operand PARAMS ((rtx, enum machine_mode));
extern int mask_operand PARAMS ((rtx, enum machine_mode));
extern int extui_fldsz_operand PARAMS ((rtx, enum machine_mode));
extern int sext_operand PARAMS ((rtx, enum machine_mode));
extern int sext_fldsz_operand PARAMS ((rtx, enum machine_mode));
extern int lsbitnum_operand PARAMS ((rtx, enum machine_mode));
extern int branch_operand PARAMS ((rtx, enum machine_mode));
extern int ubranch_operand PARAMS ((rtx, enum machine_mode));
extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
extern int move_operand PARAMS ((rtx, enum machine_mode));
extern int smalloffset_mem_p PARAMS ((rtx));
extern int smalloffset_double_mem_p PARAMS ((rtx));
extern int constantpool_address_p PARAMS ((rtx));
extern int constantpool_mem_p PARAMS ((rtx));
extern int non_const_move_operand PARAMS ((rtx, enum machine_mode));
extern int const_float_1_operand PARAMS ((rtx, enum machine_mode));
extern int fpmem_offset_operand PARAMS ((rtx, enum machine_mode));
extern void xtensa_extend_reg PARAMS ((rtx, rtx));
extern void xtensa_load_constant PARAMS ((rtx, rtx));
extern int branch_operator PARAMS ((rtx, enum machine_mode));
extern int ubranch_operator PARAMS ((rtx, enum machine_mode));
extern int boolean_operator PARAMS ((rtx, enum machine_mode));
extern void xtensa_expand_conditional_branch PARAMS ((rtx *, enum rtx_code));
extern int xtensa_expand_conditional_move PARAMS ((rtx *, int));
extern int xtensa_expand_scc PARAMS ((rtx *));
extern int xtensa_expand_block_move PARAMS ((rtx *));
extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));
extern void xtensa_expand_nonlocal_goto PARAMS ((rtx *));
extern void xtensa_emit_loop_end PARAMS ((rtx, rtx *));
extern char * xtensa_emit_call PARAMS ((int, rtx *));
#ifdef TREE_CODE
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
extern void xtensa_va_start PARAMS ((int, tree, rtx));
extern rtx xtensa_va_arg PARAMS ((tree, tree));
#endif /* TREE_CODE */
extern void print_operand PARAMS ((FILE *, rtx, int));
extern void print_operand_address PARAMS ((FILE *, rtx));
extern void xtensa_output_literal
PARAMS ((FILE *, rtx, enum machine_mode, int labelno));
extern void xtensa_reorg PARAMS ((rtx));
extern rtx xtensa_builtin_saveregs PARAMS ((void));
extern enum reg_class xtensa_secondary_reload_class
PARAMS ((enum reg_class, enum machine_mode, rtx, int));
extern int a7_overlap_mentioned_p PARAMS ((rtx x));
#endif /* RTX_CODE */
#ifdef TREE_CODE
extern void function_arg_advance
PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree));
extern struct rtx_def * function_arg
PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
extern tree xtensa_build_va_list PARAMS ((void));
#endif /* TREE_CODE */
extern int xtensa_mask_immediate PARAMS ((int));
extern int xtensa_mem_offset PARAMS ((unsigned, enum machine_mode));
extern void xtensa_setup_frame_addresses PARAMS ((void));
extern int xtensa_dbx_register_number PARAMS ((int));
extern void override_options PARAMS ((void));
extern void xtensa_declare_object
PARAMS ((FILE *, char *, char *, char *, int));
extern long compute_frame_size PARAMS ((int));
extern int xtensa_frame_pointer_required PARAMS ((void));
extern void xtensa_function_prologue PARAMS ((FILE *, int));
extern void xtensa_function_epilogue PARAMS ((FILE *, int));
extern void order_regs_for_local_alloc PARAMS ((void));
#endif /* !__XTENSA_PROTOS_H__ */

2658
gcc/config/xtensa/xtensa.c Normal file

File diff suppressed because it is too large Load Diff

1701
gcc/config/xtensa/xtensa.h Normal file

File diff suppressed because it is too large Load Diff

2415
gcc/config/xtensa/xtensa.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2272,10 +2272,10 @@ canon_hash (x, mode)
|| CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno))
|| (SMALL_REGISTER_CLASSES
&& ! fixed_regs[regno]
&& regno != FRAME_POINTER_REGNUM
&& regno != HARD_FRAME_POINTER_REGNUM
&& regno != ARG_POINTER_REGNUM
&& regno != STACK_POINTER_REGNUM
&& x != frame_pointer_rtx
&& x != hard_frame_pointer_rtx
&& x != arg_pointer_rtx
&& x != stack_pointer_rtx
&& GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
{
do_not_record = 1;

View File

@ -636,6 +636,24 @@ in the following sections.
@gccoptlist{
-msim}
@emph{Xtensa Options}
@gccoptlist{
-mbig-endian -mlittle-endian @gol
-mdensity -mno-density @gol
-mmac16 -mno-mac16 @gol
-mmul16 -mno-mul16 @gol
-mmul32 -mno-mul32 @gol
-mnsa -mno-nsa @gol
-mminmax -mno-minmax @gol
-msext -mno-sext @gol
-mbooleans -mno-booleans @gol
-mhard-float -msoft-float @gol
-mfused-madd -mno-fused-madd @gol
-mserialize-volatile -mno-serialize-volatile @gol
-mtext-section-literals -mno-text-section-literals @gol
-mtarget-align -mno-target-align @gol
-mlongcalls -mno-longcalls}
@item Code Generation Options
@xref{Code Gen Options,,Options for Code Generation Conventions}.
@gccoptlist{
@ -5116,6 +5134,7 @@ that macro, which enables you to change the defaults.
* MMIX Options::
* PDP-11 Options::
* Xstormy16 Options::
* Xtensa Options::
@end menu
@node M680x0 Options
@ -9604,6 +9623,179 @@ These options are defined for Xstormy16:
Choose startup files and linker script suitable for the simulator.
@end table
@node Xtensa Options
@subsection Xtensa Options
@cindex Xtensa Options
The Xtensa architecture is designed to support many different
configurations. The compiler's default options can be set to match a
particular Xtensa configuration by copying a configuration file into the
GCC sources when building GCC@. The options below may be used to
override the default options.
@table @gcctabopt
@item -mbig-endian
@itemx -mlittle-endian
@opindex mbig-endian
@opindex mlittle-endian
Specify big-endian or little-endian byte ordering for the target Xtensa
processor.
@item -mdensity
@itemx -mno-density
@opindex mdensity
@opindex mno-density
Enable or disable use of the optional Xtensa code density instructions.
@item -mmac16
@itemx -mno-mac16
@opindex mmac16
@opindex mno-mac16
Enable or disable use of the Xtensa MAC16 option. When enabled, GCC
will generate MAC16 instructions from standard C code, with the
limitation that it will use neither the MR register file nor any
instruction that operates on the MR registers. When this option is
disabled, GCC will translate 16-bit multiply/accumulate operations to a
combination of core instructions and library calls, depending on whether
any other multiplier options are enabled.
@item -mmul16
@itemx -mno-mul16
@opindex mmul16
@opindex mno-mul16
Enable or disable use of the 16-bit integer multiplier option. When
enabled, the compiler will generate 16-bit multiply instructions for
multiplications of 16 bits or smaller in standard C code. When this
option is disabled, the compiler will either use 32-bit multiply or
MAC16 instructions if they are available or generate library calls to
perform the multiply operations using shifts and adds.
@item -mmul32
@itemx -mno-mul32
@opindex mmul32
@opindex mno-mul32
Enable or disable use of the 32-bit integer multiplier option. When
enabled, the compiler will generate 32-bit multiply instructions for
multiplications of 32 bits or smaller in standard C code. When this
option is disabled, the compiler will generate library calls to perform
the multiply operations using either shifts and adds or 16-bit multiply
instructions if they are available.
@item -mnsa
@itemx -mno-nsa
@opindex mnsa
@opindex mno-nsa
Enable or disable use of the optional normalization shift amount
(@code{NSA}) instructions to implement the built-in @code{ffs} function.
@item -mminmax
@itemx -mno-minmax
@opindex mminmax
@opindex mno-minmax
Enable or disable use of the optional minimum and maximum value
instructions.
@item -msext
@itemx -mno-sext
@opindex msext
@opindex mno-sext
Enable or disable use of the optional sign extend (@code{SEXT})
instruction.
@item -mbooleans
@itemx -mno-booleans
@opindex mbooleans
@opindex mno-booleans
Enable or disable support for the boolean register file used by Xtensa
coprocessors. This is not typically useful by itself but may be
required for other options that make use of the boolean registers (e.g.,
the floating-point option).
@item -mhard-float
@itemx -msoft-float
@opindex mhard-float
@opindex msoft-float
Enable or disable use of the floating-point option. When enabled, GCC
generates floating-point instructions for 32-bit @code{float}
operations. When this option is disabled, GCC generates library calls
to emulate 32-bit floating-point operations using integer instructions.
Regardless of this option, 64-bit @code{double} operations are always
emulated with calls to library functions.
@item -mfused-madd
@itemx -mno-fused-madd
@opindex mfused-madd
@opindex mno-fused-madd
Enable or disable use of fused multiply/add and multiply/subtract
instructions in the floating-point option. This has no effect if the
floating-point option is not also enabled. Disabling fused multiply/add
and multiply/subtract instructions forces the compiler to use separate
instructions for the multiply and add/subtract operations. This may be
desirable in some cases where strict IEEE 754-compliant results are
required: the fused multiply add/subtract instructions do not round the
intermediate result, thereby producing results with @emph{more} bits of
precision than specified by the IEEE standard. Disabling fused multiply
add/subtract instructions also ensures that the program output is not
sensitive to the compiler's ability to combine multiply and add/subtract
operations.
@item -mserialize-volatile
@itemx -mno-serialize-volatile
@opindex mserialize-volatile
@opindex mno-serialize-volatile
When this option is enabled, GCC inserts @code{MEMW} instructions before
@code{volatile} memory references to guarantee sequential consistency.
The default is @option{-mserialize-volatile}. Use
@option{-mno-serialize-volatile} to omit the @code{MEMW} instructions.
@item -mtext-section-literals
@itemx -mno-text-section-literals
@opindex mtext-section-literals
@opindex mno-text-section-literals
Control the treatment of literal pools. The default is
@option{-mno-text-section-literals}, which places literals in a separate
section in the output file. This allows the literal pool to be placed
in a data RAM/ROM, and it also allows the linker to combine literal
pools from separate object files to remove redundant literals and
improve code size. With @option{-mtext-section-literals}, the literals
are interspersed in the text section in order to keep them as close as
possible to their references. This may be necessary for large assembly
files.
@item -mtarget-align
@itemx -mno-target-align
@opindex mtarget-align
@opindex mno-target-align
When this option is enabled, GCC instructs the assembler to
automatically align instructions to reduce branch penalties at the
expense of some code density. The assembler attempts to widen density
instructions to align branch targets and the instructions following call
instructions. If there are not enough preceding safe density
instructions to align a target, no widening will be performed. The
default is @option{-mtarget-align}. These options do not affect the
treatment of auto-aligned instructions like @code{LOOP}, which the
assembler will always align, either by widening density instructions or
by inserting no-op instructions.
@item -mlongcalls
@itemx -mno-longcalls
@opindex mlongcalls
@opindex mno-longcalls
When this option is enabled, GCC instructs the assembler to translate
direct calls to indirect calls unless it can determine that the target
of a direct call is in the range allowed by the call instruction. This
translation typically occurs for calls to functions in other source
files. Specifically, the assembler translates a direct @code{CALL}
instruction into an @code{L32R} followed by a @code{CALLX} instruction.
The default is @option{-mno-longcalls}. This option should be used in
programs where the call target can potentially be out of range. This
option is implemented in the assembler, not the compiler, so the
assembly code generated by GCC will still show direct call
instructions---look at the disassembled object code to see the actual
instructions. Note that the assembler will use an indirect call for
every cross-file call, not just those that really will be out of range.
@end table
@node Code Gen Options
@section Options for Code Generation Conventions
@cindex code generation conventions

View File

@ -2068,6 +2068,31 @@ A constant that is not between 2 and 15 inclusive.
@end table
@item Xtensa---@file{xtensa.h}
@table @code
@item a
General-purpose 32-bit register
@item b
One-bit boolean register
@item A
MAC16 40-bit accumulator register
@item I
Signed 12-bit integer constant, for use in MOVI instructions
@item J
Signed 8-bit integer constant, for use in ADDI instructions
@item K
Integer constant valid for BccI instructions
@item L
Unsigned constant valid for BccUI instructions
@end table
@end table
@ifset INTERNALS

View File

@ -1318,6 +1318,7 @@ copy_insn_list (insns, map, static_chain_value)
#ifdef HAVE_cc0
rtx cc0_insn = 0;
#endif
rtx static_chain_mem = 0;
/* Copy the insns one by one. Do this in two passes, first the insns and
then their REG_NOTES. */
@ -1381,25 +1382,62 @@ copy_insn_list (insns, map, static_chain_value)
&& REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
break;
/* Look for the address of the static chain slot. The
rtx_equal_p comparisons against the
static_chain_incoming_rtx below may fail if the static
chain is in memory and the address specified is not
"legitimate". This happens on Xtensa where the static
chain is at a negative offset from argp and where only
positive offsets are legitimate. When the RTL is
generated, the address is "legitimized" by copying it
into a register, causing the rtx_equal_p comparisons to
fail. This workaround looks for code that sets a
register to the address of the static chain. Subsequent
memory references via that register can then be
identified as static chain references. We assume that
the register is only assigned once, and that the static
chain address is only live in one register at a time. */
else if (static_chain_value != 0
&& set != 0
&& GET_CODE (static_chain_incoming_rtx) == MEM
&& GET_CODE (SET_DEST (set)) == REG
&& rtx_equal_p (SET_SRC (set),
XEXP (static_chain_incoming_rtx, 0)))
{
static_chain_mem =
gen_rtx_MEM (GET_MODE (static_chain_incoming_rtx),
SET_DEST (set));
/* emit the instruction in case it is used for something
other than setting the static chain; if it's not used,
it can always be removed as dead code */
copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
}
/* If this is setting the static chain rtx, omit it. */
else if (static_chain_value != 0
&& set != 0
&& GET_CODE (SET_DEST (set)) == REG
&& rtx_equal_p (SET_DEST (set),
static_chain_incoming_rtx))
&& (rtx_equal_p (SET_DEST (set),
static_chain_incoming_rtx)
|| (static_chain_mem
&& rtx_equal_p (SET_DEST (set), static_chain_mem))))
break;
/* If this is setting the static chain pseudo, set it from
the value we want to give it instead. */
else if (static_chain_value != 0
&& set != 0
&& rtx_equal_p (SET_SRC (set),
static_chain_incoming_rtx))
&& (rtx_equal_p (SET_SRC (set),
static_chain_incoming_rtx)
|| (static_chain_mem
&& rtx_equal_p (SET_SRC (set), static_chain_mem))))
{
rtx newdest = copy_rtx_and_substitute (SET_DEST (set), map, 1);
copy = emit_move_insn (newdest, static_chain_value);
static_chain_value = 0;
if (GET_CODE (static_chain_incoming_rtx) != MEM)
static_chain_value = 0;
}
/* If this is setting the virtual stack vars register, this must

View File

@ -1,3 +1,7 @@
2002-01-23 Bob Wilson <bob.wilson@acm.org>
* gcc.c-torture/compile/20001226-1.x: xfail for Xtensa.
2002-01-23 Janis Johnson <janis187@us.ibm.com>
* gcc.dg/20020122-3.c: New.

View File

@ -1,8 +1,12 @@
# This does not assemble on m68hc11 because the function is larger
# than 64K.
# It doesn't work on Xtensa with -O0 because the function is larger
# than the range of a jump instruction (+- 128K) and the assembler
# does not yet relax jumps to indirect jumps.
global target_triplet
if { [istarget "m6811-*-*"] || [istarget "m6812-*-*"] } {
if { [istarget "m6811-*-*"] || [istarget "m6812-*-*"] || [istarget "xtensa-*-*"]} {
set torture_compile_xfail "$target_triplet"
return 1
}