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:
parent
5b1a76105b
commit
039843087a
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
|
@ -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 */
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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 */
|
|
@ -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__ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue