Add Xtensa port

This commit is contained in:
Nick Clifton 2003-04-01 15:50:31 +00:00
parent ce0c72625a
commit e0001a05d2
75 changed files with 28789 additions and 392 deletions

View File

@ -1,3 +1,33 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* Makefile.am (ALL_MACHINES): Add cpu-xtensa.lo.
(ALL_MACHINES_CFILES): Add cpu-xtensa.c.
(BFD32_BACKENDS): Add elf32-xtensa.lo, xtensa-isa.lo, and
xtensa-modules.lo.
(BFD32_BACKENDS_CFILES): Add elf32-xtensa.c, xtensa-isa.c, and
xtensa-modules.c.
(cpu-xtensa.lo): New target.
(elf32-xtensa.lo): Likewise.
(xtensa-isa.lo): Likewise.
(xtensa-modules.lo): Likewise.
* Makefile.in: Regenerate.
* archures.c (bfd_architecture): Add bfd_{arch,mach}_xtensa.
(bfd_archures_list): Add bfd_xtensa_arch.
* config.bfd: Handle xtensa-*-*.
* configure.in: Handle bfd_elf32_xtensa_{le,be}_vec.
* configure: Regenerate.
* reloc.c: Add BFD_RELOC_XTENSA_{RTLD,GLOB_DAT,JMP_SLOT,RELATIVE,
PLT,OP0,OP1,OP2,ASM_EXPAND,ASM_SIMPLIFY}.
* targets.c (bfd_elf32_xtensa_be_vec): Declare.
(bfd_elf32_xtensa_le_vec): Likewise.
(bfd_target_vector): Add bfd_elf32_xtensa_{be,le}_vec.
* cpu-xtensa.c: New file.
* elf32-xtensa.c: Likewise.
* xtensa-isa.c: Likewise.
* xtensa-modules.c: Likewise.
* libbfd.h: Regenerate.
* bfd-in2.h: Likewise.
2003-04-01 Nick Clifton <nickc@redhat.com>
* archures.c (bfd_mach_arm_unknown): Define.

View File

@ -101,6 +101,7 @@ ALL_MACHINES = \
cpu-we32k.lo \
cpu-w65.lo \
cpu-xstormy16.lo \
cpu-xtensa.lo \
cpu-z8k.lo
ALL_MACHINES_CFILES = \
@ -155,6 +156,7 @@ ALL_MACHINES_CFILES = \
cpu-we32k.c \
cpu-w65.c \
cpu-xstormy16.c \
cpu-xtensa.c \
cpu-z8k.c
# The .o files needed by all of the 32 bit vectors that are configured into
@ -249,6 +251,7 @@ BFD32_BACKENDS = \
elf32-v850.lo \
elf32-vax.lo \
elf32-xstormy16.lo \
elf32-xtensa.lo \
elf32.lo \
elflink.lo \
elf-strtab.lo \
@ -317,7 +320,9 @@ BFD32_BACKENDS = \
vms-misc.lo \
vms-tir.lo \
xcofflink.lo \
xsym.lo
xsym.lo \
xtensa-isa.lo \
xtensa-modules.lo
BFD32_BACKENDS_CFILES = \
aout-adobe.c \
@ -408,6 +413,7 @@ BFD32_BACKENDS_CFILES = \
elf32-v850.c \
elf32-vax.c \
elf32-xstormy16.c \
elf32-xtensa.c \
elf32.c \
elflink.c \
elf-strtab.c \
@ -475,7 +481,9 @@ BFD32_BACKENDS_CFILES = \
vms-misc.c \
vms-tir.c \
xcofflink.c \
xsym.c
xsym.c \
xtensa-isa.c \
xtensa-modules.c
# The .o files needed by all of the 64 bit vectors that are configured into
# target_vector in targets.c if configured with --enable-targets=all
@ -957,6 +965,7 @@ cpu-vax.lo: cpu-vax.c $(INCDIR)/filenames.h
cpu-we32k.lo: cpu-we32k.c $(INCDIR)/filenames.h
cpu-w65.lo: cpu-w65.c $(INCDIR)/filenames.h
cpu-xstormy16.lo: cpu-xstormy16.c $(INCDIR)/filenames.h
cpu-xtensa.lo: cpu-xtensa.c $(INCDIR)/filenames.h
cpu-z8k.lo: cpu-z8k.c $(INCDIR)/filenames.h
aout-adobe.lo: aout-adobe.c $(INCDIR)/filenames.h $(INCDIR)/aout/adobe.h \
$(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h \
@ -1286,6 +1295,9 @@ elf32-xstormy16.lo: elf32-xstormy16.c $(INCDIR)/filenames.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/xstormy16.h \
$(INCDIR)/elf/reloc-macros.h $(INCDIR)/libiberty.h \
elf32-target.h
elf32-xtensa.lo: elf32-xtensa.c $(INCDIR)/bfdlink.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/elf/xtensa.h $(INCDIR)/xtensa-isa.h elf32-target.h
elf32.lo: elf32.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
$(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elfcore.h \
@ -1490,6 +1502,10 @@ xcofflink.lo: xcofflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/xcoff.h libcoff.h \
libxcoff.h
xsym.lo: xsym.c xsym.h $(INCDIR)/filenames.h
xtensa-isa.lo: xtensa-isa.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/xtensa-isa-internal.h
xtensa-modules.lo: xtensa-modules.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/xtensa-isa-internal.h
aix5ppc-core.lo: aix5ppc-core.c
aout64.lo: aout64.c aoutx.h $(INCDIR)/filenames.h $(INCDIR)/safe-ctype.h \
$(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \

View File

@ -1,4 +1,4 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
@ -226,6 +226,7 @@ ALL_MACHINES = \
cpu-we32k.lo \
cpu-w65.lo \
cpu-xstormy16.lo \
cpu-xtensa.lo \
cpu-z8k.lo
@ -281,6 +282,7 @@ ALL_MACHINES_CFILES = \
cpu-we32k.c \
cpu-w65.c \
cpu-xstormy16.c \
cpu-xtensa.c \
cpu-z8k.c
@ -376,6 +378,7 @@ BFD32_BACKENDS = \
elf32-v850.lo \
elf32-vax.lo \
elf32-xstormy16.lo \
elf32-xtensa.lo \
elf32.lo \
elflink.lo \
elf-strtab.lo \
@ -444,7 +447,9 @@ BFD32_BACKENDS = \
vms-misc.lo \
vms-tir.lo \
xcofflink.lo \
xsym.lo
xsym.lo \
xtensa-isa.lo \
xtensa-modules.lo
BFD32_BACKENDS_CFILES = \
@ -536,6 +541,7 @@ BFD32_BACKENDS_CFILES = \
elf32-v850.c \
elf32-vax.c \
elf32-xstormy16.c \
elf32-xtensa.c \
elf32.c \
elflink.c \
elf-strtab.c \
@ -603,7 +609,9 @@ BFD32_BACKENDS_CFILES = \
vms-misc.c \
vms-tir.c \
xcofflink.c \
xsym.c
xsym.c \
xtensa-isa.c \
xtensa-modules.c
# The .o files needed by all of the 64 bit vectors that are configured into
@ -799,7 +807,7 @@ configure.in version.h
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES)
OBJECTS = $(libbfd_a_OBJECTS) $(libbfd_la_OBJECTS)
@ -1490,6 +1498,7 @@ cpu-vax.lo: cpu-vax.c $(INCDIR)/filenames.h
cpu-we32k.lo: cpu-we32k.c $(INCDIR)/filenames.h
cpu-w65.lo: cpu-w65.c $(INCDIR)/filenames.h
cpu-xstormy16.lo: cpu-xstormy16.c $(INCDIR)/filenames.h
cpu-xtensa.lo: cpu-xtensa.c $(INCDIR)/filenames.h
cpu-z8k.lo: cpu-z8k.c $(INCDIR)/filenames.h
aout-adobe.lo: aout-adobe.c $(INCDIR)/filenames.h $(INCDIR)/aout/adobe.h \
$(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h \
@ -1819,6 +1828,9 @@ elf32-xstormy16.lo: elf32-xstormy16.c $(INCDIR)/filenames.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/xstormy16.h \
$(INCDIR)/elf/reloc-macros.h $(INCDIR)/libiberty.h \
elf32-target.h
elf32-xtensa.lo: elf32-xtensa.c $(INCDIR)/bfdlink.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/elf/xtensa.h $(INCDIR)/xtensa-isa.h elf32-target.h
elf32.lo: elf32.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
$(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elfcore.h \
@ -2023,6 +2035,10 @@ xcofflink.lo: xcofflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/xcoff.h libcoff.h \
libxcoff.h
xsym.lo: xsym.c xsym.h $(INCDIR)/filenames.h
xtensa-isa.lo: xtensa-isa.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/xtensa-isa-internal.h
xtensa-modules.lo: xtensa-modules.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/xtensa-isa-internal.h
aix5ppc-core.lo: aix5ppc-core.c
aout64.lo: aout64.c aoutx.h $(INCDIR)/filenames.h $(INCDIR)/safe-ctype.h \
$(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \

View File

@ -308,6 +308,8 @@ DESCRIPTION
.#define bfd_mach_msp44 44
.#define bfd_mach_msp15 15
.#define bfd_mach_msp16 16
. bfd_arch_xtensa, {* Tensilica's Xtensa cores. *}
.#define bfd_mach_xtensa 1
. bfd_arch_last
. };
*/
@ -399,6 +401,7 @@ extern const bfd_arch_info_type bfd_vax_arch;
extern const bfd_arch_info_type bfd_we32k_arch;
extern const bfd_arch_info_type bfd_w65_arch;
extern const bfd_arch_info_type bfd_xstormy16_arch;
extern const bfd_arch_info_type bfd_xtensa_arch;
extern const bfd_arch_info_type bfd_z8k_arch;
static const bfd_arch_info_type * const bfd_archures_list[] =
@ -456,6 +459,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
&bfd_w65_arch,
&bfd_we32k_arch,
&bfd_xstormy16_arch,
&bfd_xtensa_arch,
&bfd_z8k_arch,
#endif
0

View File

@ -1774,6 +1774,8 @@ enum bfd_architecture
#define bfd_mach_msp44 44
#define bfd_mach_msp15 15
#define bfd_mach_msp16 16
bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
#define bfd_mach_xtensa 1
bfd_arch_last
};
@ -3437,6 +3439,38 @@ to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */
BFD_RELOC_IQ2000_OFFSET_16,
BFD_RELOC_IQ2000_OFFSET_21,
BFD_RELOC_IQ2000_UHI16,
/* Special Xtensa relocation used only by PLT entries in ELF shared
objects to indicate that the runtime linker should set the value
to one of its own internal functions or data structures. */
BFD_RELOC_XTENSA_RTLD,
/* Xtensa relocations for ELF shared objects. */
BFD_RELOC_XTENSA_GLOB_DAT,
BFD_RELOC_XTENSA_JMP_SLOT,
BFD_RELOC_XTENSA_RELATIVE,
/* Xtensa relocation used in ELF object files for symbols that may require
PLT entries. Otherwise, this is just a generic 32-bit relocation. */
BFD_RELOC_XTENSA_PLT,
/* Generic Xtensa relocations. Only the operand number is encoded
in the relocation. The details are determined by extracting the
instruction opcode. */
BFD_RELOC_XTENSA_OP0,
BFD_RELOC_XTENSA_OP1,
BFD_RELOC_XTENSA_OP2,
/* Xtensa relocation to mark that the assembler expanded the
instructions from an original target. The expansion size is
encoded in the reloc size. */
BFD_RELOC_XTENSA_ASM_EXPAND,
/* Xtensa relocation to mark that the linker should simplify
assembler-expanded instructions. This is commonly used
internally by the linker after analysis of a
BFD_RELOC_XTENSA_ASM_EXPAND. */
BFD_RELOC_XTENSA_ASM_SIMPLIFY,
BFD_RELOC_UNUSED };
typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
reloc_howto_type *

View File

@ -58,6 +58,7 @@ thumb*) targ_archs=bfd_arm_arch ;;
v850*) targ_archs=bfd_v850_arch ;;
x86_64) targ_archs=bfd_i386_arch ;;
xscale*) targ_archs=bfd_arm_arch ;;
xtensa*) targ_archs=bfd_xtensa_arch ;;
z8k*) targ_archs=bfd_z8k_arch ;;
*) targ_archs=bfd_${targ_cpu}_arch ;;
esac
@ -1214,6 +1215,11 @@ case "${targ}" in
targ_defvec=bfd_elf32_xstormy16_vec
;;
xtensa-*-*)
targ_defvec=bfd_elf32_xtensa_le_vec
targ_selvecs=bfd_elf32_xtensa_be_vec
;;
z8k*-*-*)
targ_defvec=z8kcoff_vec
targ_underscore=yes

30
bfd/configure vendored
View File

@ -6155,6 +6155,8 @@ do
bfd_elf32_v850_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
bfd_elf32_vax_vec) tb="$tb elf32-vax.lo elf32.lo $elf" ;;
bfd_elf32_xstormy16_vec) tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;;
bfd_elf32_xtensa_le_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
bfd_elf32_xtensa_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
@ -6372,10 +6374,10 @@ case ${host64}-${target64}-${want64} in
if test -n "$GCC" ; then
bad_64bit_gcc=no;
echo $ac_n "checking for gcc version with buggy 64-bit support""... $ac_c" 1>&6
echo "configure:6376: checking for gcc version with buggy 64-bit support" >&5
echo "configure:6378: checking for gcc version with buggy 64-bit support" >&5
# Add more tests for gcc versions with non-working 64-bit support here.
cat > conftest.$ac_ext <<EOF
#line 6379 "configure"
#line 6381 "configure"
#include "confdefs.h"
:__GNUC__:__GNUC_MINOR__:__i386__:
EOF
@ -6421,17 +6423,17 @@ for ac_hdr in unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:6425: checking for $ac_hdr" >&5
echo "configure:6427: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 6430 "configure"
#line 6432 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:6435: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:6437: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -6460,12 +6462,12 @@ done
for ac_func in getpagesize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:6464: checking for $ac_func" >&5
echo "configure:6466: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 6469 "configure"
#line 6471 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -6488,7 +6490,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:6492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:6494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -6513,7 +6515,7 @@ fi
done
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
echo "configure:6517: checking for working mmap" >&5
echo "configure:6519: checking for working mmap" >&5
if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -6521,7 +6523,7 @@ else
ac_cv_func_mmap_fixed_mapped=no
else
cat > conftest.$ac_ext <<EOF
#line 6525 "configure"
#line 6527 "configure"
#include "confdefs.h"
/* Thanks to Mike Haertel and Jim Avera for this test.
@ -6661,7 +6663,7 @@ main()
}
EOF
if { (eval echo configure:6665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
if { (eval echo configure:6667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_mmap_fixed_mapped=yes
else
@ -6686,12 +6688,12 @@ fi
for ac_func in madvise mprotect
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:6690: checking for $ac_func" >&5
echo "configure:6692: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 6695 "configure"
#line 6697 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -6714,7 +6716,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:6718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:6720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else

View File

@ -639,6 +639,8 @@ do
bfd_elf32_v850_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
bfd_elf32_vax_vec) tb="$tb elf32-vax.lo elf32.lo $elf" ;;
bfd_elf32_xstormy16_vec) tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;;
bfd_elf32_xtensa_le_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
bfd_elf32_xtensa_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;

38
bfd/cpu-xtensa.c Normal file
View File

@ -0,0 +1,38 @@
/* BFD support for the Xtensa processor.
Copyright 2003 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
const bfd_arch_info_type bfd_xtensa_arch =
{
32, /* Bits per word. */
32, /* Bits per address. */
8, /* Bits per byte. */
bfd_arch_xtensa, /* Architecture. */
bfd_mach_xtensa, /* Machine. */
"xtensa", /* Architecture name. */
"xtensa", /* Printable name. */
4, /* Section align power. */
TRUE, /* The default? */
bfd_default_compatible, /* Architecture comparison fn. */
bfd_default_scan, /* String to architecture convert fn. */
NULL /* Next in list. */
};

5846
bfd/elf32-xtensa.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1475,6 +1475,16 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_IQ2000_OFFSET_16",
"BFD_RELOC_IQ2000_OFFSET_21",
"BFD_RELOC_IQ2000_UHI16",
"BFD_RELOC_XTENSA_RTLD",
"BFD_RELOC_XTENSA_GLOB_DAT",
"BFD_RELOC_XTENSA_JMP_SLOT",
"BFD_RELOC_XTENSA_RELATIVE",
"BFD_RELOC_XTENSA_PLT",
"BFD_RELOC_XTENSA_OP0",
"BFD_RELOC_XTENSA_OP1",
"BFD_RELOC_XTENSA_OP2",
"BFD_RELOC_XTENSA_ASM_EXPAND",
"BFD_RELOC_XTENSA_ASM_SIMPLIFY",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif

View File

@ -3850,6 +3850,49 @@ ENUMX
ENUMDOC
IQ2000 Relocations.
ENUM
BFD_RELOC_XTENSA_RTLD
ENUMDOC
Special Xtensa relocation used only by PLT entries in ELF shared
objects to indicate that the runtime linker should set the value
to one of its own internal functions or data structures.
ENUM
BFD_RELOC_XTENSA_GLOB_DAT
ENUMX
BFD_RELOC_XTENSA_JMP_SLOT
ENUMX
BFD_RELOC_XTENSA_RELATIVE
ENUMDOC
Xtensa relocations for ELF shared objects.
ENUM
BFD_RELOC_XTENSA_PLT
ENUMDOC
Xtensa relocation used in ELF object files for symbols that may require
PLT entries. Otherwise, this is just a generic 32-bit relocation.
ENUM
BFD_RELOC_XTENSA_OP0
ENUMX
BFD_RELOC_XTENSA_OP1
ENUMX
BFD_RELOC_XTENSA_OP2
ENUMDOC
Generic Xtensa relocations. Only the operand number is encoded
in the relocation. The details are determined by extracting the
instruction opcode.
ENUM
BFD_RELOC_XTENSA_ASM_EXPAND
ENUMDOC
Xtensa relocation to mark that the assembler expanded the
instructions from an original target. The expansion size is
encoded in the reloc size.
ENUM
BFD_RELOC_XTENSA_ASM_SIMPLIFY
ENUMDOC
Xtensa relocation to mark that the linker should simplify
assembler-expanded instructions. This is commonly used
internally by the linker after analysis of a
BFD_RELOC_XTENSA_ASM_EXPAND.
ENDSENUM
BFD_RELOC_UNUSED
CODE_FRAGMENT

View File

@ -579,6 +579,8 @@ extern const bfd_target bfd_elf32_us_cris_vec;
extern const bfd_target bfd_elf32_v850_vec;
extern const bfd_target bfd_elf32_vax_vec;
extern const bfd_target bfd_elf32_xstormy16_vec;
extern const bfd_target bfd_elf32_xtensa_be_vec;
extern const bfd_target bfd_elf32_xtensa_le_vec;
extern const bfd_target bfd_elf64_alpha_freebsd_vec;
extern const bfd_target bfd_elf64_alpha_vec;
extern const bfd_target bfd_elf64_big_generic_vec;
@ -871,6 +873,8 @@ static const bfd_target * const _bfd_target_vector[] = {
&bfd_elf32_v850_vec,
&bfd_elf32_vax_vec,
&bfd_elf32_xstormy16_vec,
&bfd_elf32_xtensa_be_vec,
&bfd_elf32_xtensa_le_vec,
#ifdef BFD64
&bfd_elf64_alpha_freebsd_vec,
&bfd_elf64_alpha_vec,

593
bfd/xtensa-isa.c Normal file
View File

@ -0,0 +1,593 @@
/* Configurable Xtensa ISA support.
Copyright 2003 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "xtensa-isa.h"
#include "xtensa-isa-internal.h"
xtensa_isa xtensa_default_isa = NULL;
static int
opname_lookup_compare (const void *v1, const void *v2)
{
opname_lookup_entry *e1 = (opname_lookup_entry *)v1;
opname_lookup_entry *e2 = (opname_lookup_entry *)v2;
return strcmp (e1->key, e2->key);
}
xtensa_isa
xtensa_isa_init (void)
{
xtensa_isa isa;
int mod;
isa = xtensa_load_isa (0);
if (isa == 0)
{
fprintf (stderr, "Failed to initialize Xtensa base ISA module\n");
return NULL;
}
for (mod = 1; xtensa_isa_modules[mod].get_num_opcodes_fn; mod++)
{
if (!xtensa_extend_isa (isa, mod))
{
fprintf (stderr, "Failed to initialize Xtensa TIE ISA module\n");
return NULL;
}
}
return isa;
}
/* ISA information. */
static int
xtensa_check_isa_config (xtensa_isa_internal *isa,
struct config_struct *config_table)
{
int i, j;
if (!config_table)
{
fprintf (stderr, "Error: Empty configuration table in ISA DLL\n");
return 0;
}
/* For the first module, save a pointer to the table and record the
specified endianness and availability of the density option. */
if (isa->num_modules == 0)
{
int found_memory_order = 0;
isa->config = config_table;
isa->has_density = 1; /* Default to have density option. */
for (i = 0; config_table[i].param_name; i++)
{
if (!strcmp (config_table[i].param_name, "IsaMemoryOrder"))
{
isa->is_big_endian =
(strcmp (config_table[i].param_value, "BigEndian") == 0);
found_memory_order = 1;
}
if (!strcmp (config_table[i].param_name, "IsaUseDensityInstruction"))
{
isa->has_density = atoi (config_table[i].param_value);
}
}
if (!found_memory_order)
{
fprintf (stderr, "Error: \"IsaMemoryOrder\" missing from "
"configuration table in ISA DLL\n");
return 0;
}
return 1;
}
/* For subsequent modules, check that the parameters match. Note: This
code is sufficient to handle the current model where there are never
more than 2 modules; we might at some point want to handle cases where
module N > 0 specifies some parameters not included in the base table,
and we would then add those to isa->config so that subsequent modules
would check against them. */
for (i = 0; config_table[i].param_name; i++)
{
for (j = 0; isa->config[j].param_name; j++)
{
if (!strcmp (config_table[i].param_name, isa->config[j].param_name))
{
int mismatch;
if (!strcmp (config_table[i].param_name, "IsaCoprocessorCount"))
{
/* Only require the coprocessor count to be <= the base. */
int tiecnt = atoi (config_table[i].param_value);
int basecnt = atoi (isa->config[j].param_value);
mismatch = (tiecnt > basecnt);
}
else
mismatch = strcmp (config_table[i].param_value,
isa->config[j].param_value);
if (mismatch)
{
#define MISMATCH_MESSAGE \
"Error: Configuration mismatch in the \"%s\" parameter:\n\
the configuration used when the TIE file was compiled had a value of\n\
\"%s\", while the current configuration has a value of\n\
\"%s\". Please rerun the TIE compiler with a matching\n\
configuration.\n"
fprintf (stderr, MISMATCH_MESSAGE,
config_table[i].param_name,
config_table[i].param_value,
isa->config[j].param_value);
return 0;
}
break;
}
}
}
return 1;
}
static int
xtensa_add_isa (xtensa_isa_internal *isa, libisa_module_specifier libisa)
{
const int (*get_num_opcodes_fn) (void);
struct config_struct *(*get_config_table_fn) (void);
xtensa_opcode_internal **(*get_opcodes_fn) (void);
int (*decode_insn_fn) (const xtensa_insnbuf);
xtensa_opcode_internal **opcodes;
int opc, insn_size, prev_num_opcodes, new_num_opcodes, this_module;
get_num_opcodes_fn = xtensa_isa_modules[libisa].get_num_opcodes_fn;
get_opcodes_fn = xtensa_isa_modules[libisa].get_opcodes_fn;
decode_insn_fn = xtensa_isa_modules[libisa].decode_insn_fn;
get_config_table_fn = xtensa_isa_modules[libisa].get_config_table_fn;
if (!get_num_opcodes_fn || !get_opcodes_fn || !decode_insn_fn
|| (!get_config_table_fn && isa->num_modules == 0))
return 0;
if (get_config_table_fn
&& !xtensa_check_isa_config (isa, get_config_table_fn ()))
return 0;
prev_num_opcodes = isa->num_opcodes;
new_num_opcodes = (*get_num_opcodes_fn) ();
isa->num_opcodes += new_num_opcodes;
isa->opcode_table = (xtensa_opcode_internal **)
realloc (isa->opcode_table, isa->num_opcodes *
sizeof (xtensa_opcode_internal *));
isa->opname_lookup_table = (opname_lookup_entry *)
realloc (isa->opname_lookup_table, isa->num_opcodes *
sizeof (opname_lookup_entry));
opcodes = (*get_opcodes_fn) ();
insn_size = isa->insn_size;
for (opc = 0; opc < new_num_opcodes; opc++)
{
xtensa_opcode_internal *intopc = opcodes[opc];
int newopc = prev_num_opcodes + opc;
isa->opcode_table[newopc] = intopc;
isa->opname_lookup_table[newopc].key = intopc->name;
isa->opname_lookup_table[newopc].opcode = newopc;
if (intopc->length > insn_size)
insn_size = intopc->length;
}
isa->insn_size = insn_size;
isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
sizeof (xtensa_insnbuf_word));
qsort (isa->opname_lookup_table, isa->num_opcodes,
sizeof (opname_lookup_entry), opname_lookup_compare);
/* Check for duplicate opcode names. */
for (opc = 1; opc < isa->num_opcodes; opc++)
{
if (!opname_lookup_compare (&isa->opname_lookup_table[opc-1],
&isa->opname_lookup_table[opc]))
{
fprintf (stderr, "Error: Duplicate TIE opcode \"%s\"\n",
isa->opname_lookup_table[opc].key);
return 0;
}
}
this_module = isa->num_modules;
isa->num_modules += 1;
isa->module_opcode_base = (int *) realloc (isa->module_opcode_base,
isa->num_modules * sizeof (int));
isa->module_decode_fn = (xtensa_insn_decode_fn *)
realloc (isa->module_decode_fn, isa->num_modules *
sizeof (xtensa_insn_decode_fn));
isa->module_opcode_base[this_module] = prev_num_opcodes;
isa->module_decode_fn[this_module] = decode_insn_fn;
xtensa_default_isa = isa;
return 1; /* Library was successfully added. */
}
xtensa_isa
xtensa_load_isa (libisa_module_specifier libisa)
{
xtensa_isa_internal *isa;
isa = (xtensa_isa_internal *) malloc (sizeof (xtensa_isa_internal));
memset (isa, 0, sizeof (xtensa_isa_internal));
if (!xtensa_add_isa (isa, libisa))
{
xtensa_isa_free (isa);
return NULL;
}
return (xtensa_isa) isa;
}
int
xtensa_extend_isa (xtensa_isa isa, libisa_module_specifier libisa)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
return xtensa_add_isa (intisa, libisa);
}
void
xtensa_isa_free (xtensa_isa isa)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
if (intisa->opcode_table)
free (intisa->opcode_table);
if (intisa->opname_lookup_table)
free (intisa->opname_lookup_table);
if (intisa->module_opcode_base)
free (intisa->module_opcode_base);
if (intisa->module_decode_fn)
free (intisa->module_decode_fn);
free (intisa);
}
int
xtensa_insn_maxlength (xtensa_isa isa)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
return intisa->insn_size;
}
int
xtensa_insnbuf_size (xtensa_isa isa)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
return intisa->insnbuf_size;
}
int
xtensa_num_opcodes (xtensa_isa isa)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
return intisa->num_opcodes;
}
xtensa_opcode
xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
opname_lookup_entry entry, *result;
entry.key = opname;
result = bsearch (&entry, intisa->opname_lookup_table, intisa->num_opcodes,
sizeof (opname_lookup_entry), opname_lookup_compare);
if (!result) return XTENSA_UNDEFINED;
return result->opcode;
}
xtensa_opcode
xtensa_decode_insn (xtensa_isa isa, const xtensa_insnbuf insn)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
int n, opc;
for (n = 0; n < intisa->num_modules; n++) {
opc = (intisa->module_decode_fn[n]) (insn);
if (opc != XTENSA_UNDEFINED)
return intisa->module_opcode_base[n] + opc;
}
return XTENSA_UNDEFINED;
}
/* Opcode information. */
void
xtensa_encode_insn (xtensa_isa isa, xtensa_opcode opc, xtensa_insnbuf insn)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
xtensa_insnbuf template = intisa->opcode_table[opc]->template();
int len = intisa->opcode_table[opc]->length;
int n;
/* Convert length to 32-bit words. */
len = (len + 3) / 4;
/* Copy the template. */
for (n = 0; n < len; n++)
insn[n] = template[n];
/* Fill any unused buffer space with zeros. */
for ( ; n < intisa->insnbuf_size; n++)
insn[n] = 0;
}
const char *
xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
return intisa->opcode_table[opc]->name;
}
int
xtensa_insn_length (xtensa_isa isa, xtensa_opcode opc)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
return intisa->opcode_table[opc]->length;
}
int
xtensa_insn_length_from_first_byte (xtensa_isa isa, char first_byte)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
int is_density = (first_byte & (intisa->is_big_endian ? 0x80 : 0x08)) != 0;
return (intisa->has_density && is_density ? 2 : 3);
}
int
xtensa_num_operands (xtensa_isa isa, xtensa_opcode opc)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
return intisa->opcode_table[opc]->iclass->num_operands;
}
xtensa_operand
xtensa_get_operand (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
xtensa_iclass_internal *iclass = intisa->opcode_table[opc]->iclass;
if (opnd >= iclass->num_operands)
return NULL;
return (xtensa_operand) iclass->operands[opnd];
}
/* Operand information. */
char *
xtensa_operand_kind (xtensa_operand opnd)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return intop->operand_kind;
}
char
xtensa_operand_inout (xtensa_operand opnd)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return intop->inout;
}
uint32
xtensa_operand_get_field (xtensa_operand opnd, const xtensa_insnbuf insn)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return (*intop->get_field) (insn);
}
void
xtensa_operand_set_field (xtensa_operand opnd, xtensa_insnbuf insn, uint32 val)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return (*intop->set_field) (insn, val);
}
xtensa_encode_result
xtensa_operand_encode (xtensa_operand opnd, uint32 *valp)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return (*intop->encode) (valp);
}
uint32
xtensa_operand_decode (xtensa_operand opnd, uint32 val)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return (*intop->decode) (val);
}
int
xtensa_operand_isPCRelative (xtensa_operand opnd)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
return intop->isPCRelative;
}
uint32
xtensa_operand_do_reloc (xtensa_operand opnd, uint32 addr, uint32 pc)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
if (!intop->isPCRelative)
return addr;
return (*intop->do_reloc) (addr, pc);
}
uint32
xtensa_operand_undo_reloc (xtensa_operand opnd, uint32 offset, uint32 pc)
{
xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
if (!intop->isPCRelative)
return offset;
return (*intop->undo_reloc) (offset, pc);
}
/* Instruction buffers. */
xtensa_insnbuf
xtensa_insnbuf_alloc (xtensa_isa isa)
{
return (xtensa_insnbuf) malloc (xtensa_insnbuf_size (isa) *
sizeof (xtensa_insnbuf_word));
}
void
xtensa_insnbuf_free (xtensa_insnbuf buf)
{
free( buf );
}
/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
internal representation of a xtensa instruction word, return the index of
its word and the bit index of its low order byte in the xtensa_insnbuf. */
static inline int
byte_to_word_index (int byte_index)
{
return byte_index / sizeof (xtensa_insnbuf_word);
}
static inline int
byte_to_bit_index (int byte_index)
{
return (byte_index & 0x3) * 8;
}
/* Copy an instruction in the 32 bit words pointed at by <insn> to characters
pointed at by <cp>. This is more complicated than you might think because
we want 16 bit instructions in bytes 2,3 for big endian. This function
allows us to specify which byte in <insn> to start with and which way to
increment, allowing trivial implementation for both big and little endian.
And it seems to make pretty good code for both. */
void
xtensa_insnbuf_to_chars (xtensa_isa isa, const xtensa_insnbuf insn, char *cp)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
int insn_size = xtensa_insn_maxlength (intisa);
int fence_post, start, increment, i, byte_count;
xtensa_opcode opc;
if (intisa->is_big_endian)
{
start = insn_size - 1;
increment = -1;
}
else
{
start = 0;
increment = 1;
}
/* Find the opcode; do nothing if the buffer does not contain a valid
instruction since we need to know how many bytes to copy. */
opc = xtensa_decode_insn (isa, insn);
if (opc == XTENSA_UNDEFINED)
return;
byte_count = xtensa_insn_length (isa, opc);
fence_post = start + (byte_count * increment);
for (i = start; i != fence_post; i += increment, ++cp)
{
int word_inx = byte_to_word_index (i);
int bit_inx = byte_to_bit_index (i);
*cp = (insn[word_inx] >> bit_inx) & 0xff;
}
}
/* Inward conversion from byte stream to xtensa_insnbuf. See
xtensa_insnbuf_to_chars for a discussion of why this is
complicated by endianness. */
void
xtensa_insnbuf_from_chars (xtensa_isa isa, xtensa_insnbuf insn, const char* cp)
{
xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
int insn_size = xtensa_insn_maxlength (intisa);
int fence_post, start, increment, i;
if (intisa->is_big_endian)
{
start = insn_size - 1;
increment = -1;
}
else
{
start = 0;
increment = 1;
}
fence_post = start + (insn_size * increment);
memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
for ( i = start; i != fence_post; i += increment, ++cp )
{
int word_inx = byte_to_word_index (i);
int bit_inx = byte_to_bit_index (i);
insn[word_inx] |= (*cp & 0xff) << bit_inx;
}
}

6090
bfd/xtensa-modules.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,32 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* Makefile.am (CPU_TYPES): Add xtensa.
(TARGET_CPU_CFILES): Add config/tc-xtensa.c.
(TARGET_CPU_HFILES): Add config/tc-xtensa.h.
(xtensa-relax.o): New target.
Run "make dep-am".
* Makefile.in: Regenerate.
* configure.in: Handle xtensa-*-*. Add xtensa-relax.o to
extra_objects for xtensa targets.
* configure: Regenerate.
* write.c (write_object_file): Add new md_post_relax_hook.
* config/tc-xtensa.c: New file.
* config/tc-xtensa.h: Likewise.
* config/xtensa-istack.h: Likewise.
* config/xtensa-relax.c: Likewise.
* config/xtensa-relax.h: Likewise.
* doc/Makefile.am (CPU_DOCS): Add c-xtensa.texi.
* doc/Makefile.in: Regenerate.
* doc/all.texi: Set new XTENSA variable.
* doc/as.texinfo: Set new Xtensa variable. Describe
Xtensa-specific options. Define line comment character for
Xtensa. Add Xtensa processors to list of ELF targets where
alignment is specified in bytes. Add new Xtensa-Dependent node.
Add acknowledgements for those contributing to the Xtensa port.
* doc/internals.texi: Describe new md_post_relax_hook.
* doc/c-xtensa.texi: New file.
2003-04-01 Nick Clifton <nickc@redhat.com>
Richard Earnshaw <rearnsha@arm.com>

View File

@ -86,6 +86,7 @@ CPU_TYPES = \
w65 \
v850 \
xstormy16 \
xtensa \
z8k
# Object format types. This is only used for dependency information.
@ -278,6 +279,7 @@ TARGET_CPU_CFILES = \
config/tc-w65.c \
config/tc-v850.c \
config/tc-xstormy16.c \
config/tc-xtensa.c \
config/tc-z8k.c
TARGET_CPU_HFILES = \
@ -329,6 +331,7 @@ TARGET_CPU_HFILES = \
config/tc-w65.h \
config/tc-v850.h \
config/tc-xstormy16.h \
config/tc-xtensa.h \
config/tc-z8k.h
# OBJ files in config
@ -601,6 +604,10 @@ e-crisaout.o: $(srcdir)/config/e-crisaout.c
e-criself.o: $(srcdir)/config/e-criself.c
$(COMPILE) -c $(srcdir)/config/e-criself.c
xtensa-relax.o: $(srcdir)/config/xtensa-relax.c
$(COMPILE) -c $(srcdir)/config/xtensa-relax.c
# The m68k operand parser.
EXTRA_as_new_SOURCES = config/m68k-parse.y
@ -1517,6 +1524,13 @@ DEPTC_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/xstormy16-desc.h \
$(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/xstormy16-opc.h \
cgen.h
DEPTC_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
$(INCDIR)/xtensa-config.h sb.h $(INCDIR)/safe-ctype.h \
subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/xtensa-relax.h \
$(INCDIR)/xtensa-isa.h $(srcdir)/config/xtensa-istack.h \
dwarf2dbg.h struc-symbol.h
DEPTC_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@ -1915,8 +1929,8 @@ DEPOBJ_sh64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
$(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
$(BFDDIR)/elf32-sh64.h $(INCDIR)/safe-ctype.h subsegs.h \
$(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_sparc_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
$(srcdir)/config/tc-sparc.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
$(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
@ -2023,6 +2037,11 @@ DEPOBJ_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
$(INCDIR)/xtensa-config.h $(INCDIR)/safe-ctype.h subsegs.h \
$(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@ -2363,6 +2382,10 @@ DEP_xstormy16_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-xstormy16.h
DEP_xstormy16_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h
DEP_xtensa_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
$(INCDIR)/xtensa-config.h
DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h \
$(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h

View File

@ -1,4 +1,4 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
@ -197,6 +197,7 @@ CPU_TYPES = \
w65 \
v850 \
xstormy16 \
xtensa \
z8k
@ -395,6 +396,7 @@ TARGET_CPU_CFILES = \
config/tc-w65.c \
config/tc-v850.c \
config/tc-xstormy16.c \
config/tc-xtensa.c \
config/tc-z8k.c
@ -447,6 +449,7 @@ TARGET_CPU_HFILES = \
config/tc-w65.h \
config/tc-v850.h \
config/tc-xstormy16.h \
config/tc-xtensa.h \
config/tc-z8k.h
@ -1333,6 +1336,14 @@ DEPTC_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/xstormy16-opc.h \
cgen.h
DEPTC_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
$(INCDIR)/xtensa-config.h sb.h $(INCDIR)/safe-ctype.h \
subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/xtensa-relax.h \
$(INCDIR)/xtensa-isa.h $(srcdir)/config/xtensa-istack.h \
dwarf2dbg.h struc-symbol.h
DEPTC_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@ -1822,8 +1833,8 @@ DEPOBJ_sh64_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh64.h \
$(srcdir)/config/tc-sh.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
$(BFDDIR)/elf32-sh64.h $(INCDIR)/safe-ctype.h subsegs.h \
$(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_sparc_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
$(srcdir)/config/tc-sparc.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
@ -1956,6 +1967,12 @@ DEPOBJ_xstormy16_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_xtensa_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
$(INCDIR)/xtensa-config.h $(INCDIR)/safe-ctype.h subsegs.h \
$(INCDIR)/obstack.h struc-symbol.h $(INCDIR)/aout/aout64.h
DEPOBJ_z8k_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
$(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/z8k.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@ -2411,6 +2428,11 @@ DEP_xstormy16_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xstormy16.h
DEP_xtensa_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-xtensa.h \
$(INCDIR)/xtensa-config.h
DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h \
$(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
@ -2471,7 +2493,7 @@ configure configure.in gdbinit.in itbl-lex.c itbl-parse.c
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = $(itbl_test_SOURCES) $(as_new_SOURCES) $(EXTRA_as_new_SOURCES)
OBJECTS = $(itbl_test_OBJECTS) $(as_new_OBJECTS)
@ -2807,7 +2829,7 @@ distclean-generic:
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
-test -z "itbl-lex.cconfig/m68k-parse.hconfig/m68k-parse.citbl-parse.hitbl-parse.c" || rm -f itbl-lex.c config/m68k-parse.h config/m68k-parse.c itbl-parse.h itbl-parse.c
-test -z "itbl-lexlconfig/m68k-parsehconfig/m68k-parsecitbl-parsehitbl-parsec" || rm -f itbl-lexl config/m68k-parseh config/m68k-parsec itbl-parseh itbl-parsec
mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \
mostlyclean-compile mostlyclean-libtool \
mostlyclean-tags mostlyclean-generic
@ -2955,6 +2977,9 @@ e-crisaout.o: $(srcdir)/config/e-crisaout.c
e-criself.o: $(srcdir)/config/e-criself.c
$(COMPILE) -c $(srcdir)/config/e-criself.c
xtensa-relax.o: $(srcdir)/config/xtensa-relax.c
$(COMPILE) -c $(srcdir)/config/xtensa-relax.c
# If m68k-parse.y is in a different directory, then ylwrap will use an
# absolute path when it invokes yacc, which will cause yacc to put the
# absolute path into the generated file. That's a pain when it comes

9014
gas/config/tc-xtensa.c Normal file

File diff suppressed because it is too large Load Diff

200
gas/config/tc-xtensa.h Normal file
View File

@ -0,0 +1,200 @@
/* tc-xtensa.h -- Header file for tc-xtensa.c.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS 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.
GAS 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 GAS; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef TC_XTENSA
#define TC_XTENSA 1
#ifdef ANSI_PROTOTYPES
struct fix;
#endif
#ifndef BFD_ASSEMBLER
#error Xtensa support requires BFD_ASSEMBLER
#endif
#ifndef OBJ_ELF
#error Xtensa support requires ELF object format
#endif
#include "xtensa-config.h"
#define TARGET_BYTES_BIG_ENDIAN XCHAL_HAVE_BE
struct xtensa_frag_type
{
unsigned is_literal:1;
unsigned is_text:1;
unsigned is_loop_target:1;
unsigned is_branch_target:1;
unsigned is_insn:1;
/* Info about the current state of assembly, i.e., density, relax,
generics, freeregs, longcalls. These need to be passed to the
backend and then to the linking file. */
unsigned is_no_density:1;
unsigned is_relax:1;
unsigned is_generics:1;
unsigned is_longcalls:1;
/* For text fragments that can generate literals at relax time, this
variable points to the frag where the literal will be stored. For
literal frags, this variable points to the nearest literal pool
location frag. This literal frag will be moved to after this
location. */
fragS *literal_frag;
/* The destination segment for literal frags. (Note that this is only
valid after xtensa_move_literals. */
segT lit_seg;
/* For the relaxation scheme, some literal fragments can have their
expansions modified by an instruction that relaxes. */
unsigned text_expansion;
unsigned literal_expansion;
unsigned unreported_expansion;
};
typedef struct xtensa_block_info_struct
{
segT sec;
bfd_vma offset;
size_t size;
struct xtensa_block_info_struct *next;
} xtensa_block_info;
typedef enum
{
xt_insn_sec,
xt_literal_sec,
max_xt_sec
} xt_section_type;
typedef struct xtensa_segment_info_struct
{
fragS *literal_pool_loc;
xtensa_block_info *blocks[max_xt_sec];
} xtensa_segment_info;
typedef struct xtensa_symfield_type_struct
{
unsigned int plt : 1;
} xtensa_symfield_type;
/* Section renaming is only supported in Tensilica's version of GAS. */
#define XTENSA_SECTION_RENAME 1
#ifdef XTENSA_SECTION_RENAME
extern const char *xtensa_section_rename
PARAMS ((const char *));
#else
/* Tensilica's section renaming feature is not included here. */
#define xtensa_section_rename(name) (name)
#endif /* XTENSA_SECTION_RENAME */
extern const char *xtensa_target_format
PARAMS ((void));
extern void xtensa_frag_init
PARAMS ((fragS *));
extern void xtensa_cons_fix_new
PARAMS ((fragS *, int, int, expressionS *));
extern void xtensa_frob_label
PARAMS ((struct symbol *));
extern void xtensa_end
PARAMS ((void));
extern void xtensa_post_relax_hook
PARAMS ((void));
extern void xtensa_file_arch_init
PARAMS ((bfd *));
extern void xtensa_flush_pending_output
PARAMS ((void));
extern bfd_boolean xtensa_fix_adjustable
PARAMS ((struct fix *));
extern void xtensa_symbol_new_hook
PARAMS ((symbolS *));
extern long xtensa_relax_frag
PARAMS ((fragS *, long, int *));
#define TARGET_FORMAT xtensa_target_format ()
#define TARGET_ARCH bfd_arch_xtensa
#define TC_SEGMENT_INFO_TYPE xtensa_segment_info
#define TC_SYMFIELD_TYPE xtensa_symfield_type
#define TC_FRAG_TYPE struct xtensa_frag_type
#define TC_FRAG_INIT(frag) xtensa_frag_init (frag)
#define TC_CONS_FIX_NEW xtensa_cons_fix_new
#define tc_canonicalize_symbol_name(s) xtensa_section_rename (s)
#define tc_init_after_args() xtensa_file_arch_init (stdoutput)
#define tc_fix_adjustable(fix) xtensa_fix_adjustable (fix)
#define tc_frob_label(sym) xtensa_frob_label (sym)
#define tc_symbol_new_hook(s) xtensa_symbol_new_hook (s)
#define md_elf_section_rename(name) xtensa_section_rename (name)
#define md_end xtensa_end
#define md_flush_pending_output() xtensa_flush_pending_output ()
#define md_operand(x)
#define TEXT_SECTION_NAME xtensa_section_rename (".text")
#define DATA_SECTION_NAME xtensa_section_rename (".data")
#define BSS_SECTION_NAME xtensa_section_rename (".bss")
/* The renumber_section function must be mapped over all the sections
after calling xtensa_post_relax_hook. That function is static in
write.c so it cannot be called from xtensa_post_relax_hook itself. */
#define md_post_relax_hook \
do \
{ \
int i = 0; \
xtensa_post_relax_hook (); \
bfd_map_over_sections (stdoutput, renumber_sections, &i); \
} \
while (0)
/* Because xtensa relaxation can insert a new literal into the middle of
fragment and thus require re-running the relaxation pass on the
section, we need an explicit flag here. We explicitly use the name
"stretched" here to avoid changing the source code in write.c. */
#define md_relax_frag(segment, fragP, stretch) \
xtensa_relax_frag (fragP, stretch, &stretched)
#define LOCAL_LABELS_FB 1
#define WORKING_DOT_WORD 1
#define DOUBLESLASH_LINE_COMMENTS
#define TC_HANDLES_FX_DONE
#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 0
#define MD_APPLY_SYM_VALUE(FIX) 0
/* The default literal sections should always be marked as "code" (i.e.,
SHF_EXECINSTR). This is particularly important for the Linux kernel
module loader so that the literals are not placed after the text. */
#define ELF_TC_SPECIAL_SECTIONS \
{ ".literal", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, \
{ ".init.literal", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, \
{ ".fini.literal", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
#endif /* TC_XTENSA */

1766
gas/config/xtensa-relax.c Normal file

File diff suppressed because it is too large Load Diff

142
gas/config/xtensa-relax.h Normal file
View File

@ -0,0 +1,142 @@
/* Table of relaxations for Xtensa assembly.
Copyright 2003 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS 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.
GAS 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 GAS; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
#ifndef XTENSA_RELAX_H
#define XTENSA_RELAX_H
#include "xtensa-isa.h"
/* Data structures for the table-driven relaxations for Xtensa processors.
See xtensa-relax.c for details. */
typedef struct transition_list TransitionList;
typedef struct transition_table TransitionTable;
typedef struct transition_rule TransitionRule;
typedef struct precondition_list PreconditionList;
typedef struct precondition Precondition;
struct transition_table
{
int num_opcodes;
TransitionList **table; /* Possible transitions for each opcode. */
};
struct transition_list
{
TransitionRule *rule;
TransitionList *next;
};
struct precondition_list
{
Precondition *precond;
PreconditionList *next;
};
/* Operand types and constraints on operands: */
typedef enum op_type OpType;
typedef enum cmp_op CmpOp;
enum op_type
{
OP_CONSTANT,
OP_OPERAND,
OP_OPERAND_LOW8, /* Sign-extended low 8 bits of immed. */
OP_OPERAND_HI24S, /* high 24 bits of immed,
plus 0x100 if low 8 bits are signed. */
OP_OPERAND_F32MINUS, /* 32 - immed. */
OP_LITERAL,
OP_LABEL
};
enum cmp_op
{
OP_EQUAL,
OP_NOTEQUAL,
};
struct precondition
{
CmpOp cmp;
int op_num;
OpType typ; /* CONSTANT: op_data is a constant.
OPERAND: operand op_num must equal op_data.
Cannot be LITERAL or LABEL. */
int op_data;
};
typedef struct build_op BuildOp;
struct build_op
{
int op_num;
OpType typ;
unsigned op_data; /* CONSTANT: op_data is the value to encode.
OPERAND: op_data is the field in the
source instruction to take the value from
and encode in the op_num field here.
LITERAL or LABEL: op_data is the ordinal
that identifies the appropriate one, i.e.,
there can be more than one literal or
label in an expansion. */
BuildOp *next;
};
typedef struct build_instr BuildInstr;
typedef enum instr_type InstrType;
enum instr_type
{
INSTR_INSTR,
INSTR_LITERAL_DEF,
INSTR_LABEL_DEF
};
struct build_instr
{
InstrType typ;
unsigned id; /* LITERAL_DEF or LABEL_DEF: an ordinal to
identify which one. */
xtensa_opcode opcode; /* unused for LITERAL_DEF or LABEL_DEF. */
BuildOp *ops;
BuildInstr *next;
};
struct transition_rule
{
xtensa_opcode opcode;
PreconditionList *conditions;
BuildInstr *to_instr;
};
extern TransitionTable *xg_build_simplify_table
PARAMS ((void));
extern TransitionTable *xg_build_widen_table
PARAMS ((void));
extern bfd_boolean xg_has_userdef_op_fn
PARAMS ((OpType));
extern long xg_apply_userdef_op_fn
PARAMS ((OpType, long));
#endif /* !XTENSA_RELAX_H */

370
gas/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -153,6 +153,7 @@ changequote([,])dnl
sparc86x*) cpu_type=sparc arch=sparc86x ;;
sparc*) cpu_type=sparc arch=sparclite ;; # ??? See tc-sparc.c.
v850*) cpu_type=v850 ;;
xtensa*) cpu_type=xtensa arch=xtensa ;;
*) cpu_type=${cpu} ;;
esac
@ -482,6 +483,8 @@ changequote([,])dnl
xstormy16-*-*) fmt=elf ;;
xtensa-*-*) fmt=elf ;;
z8k-*-coff | z8k-*-sim) fmt=coff ;;
*-*-aout | *-*-scout) fmt=aout ;;
@ -648,6 +651,13 @@ changequote([,])dnl
using_cgen=yes
;;
xtensa)
echo ${extra_objects} | grep -s "xtensa-relax.o"
if test $? -ne 0 ; then
extra_objects="$extra_objects xtensa-relax.o"
fi
;;
*)
;;
esac

View File

@ -55,6 +55,7 @@ CPU_DOCS = \
c-tic54x.texi \
c-vax.texi \
c-v850.texi \
c-xtensa.texi \
c-z8k.texi
gasver.texi: Makefile

View File

@ -167,6 +167,7 @@ CPU_DOCS = \
c-tic54x.texi \
c-vax.texi \
c-v850.texi \
c-xtensa.texi \
c-z8k.texi

View File

@ -58,6 +58,7 @@
@set V850
@set VAX
@set VXWORKS
@set XTENSA
@set Z8000
@c Does this version of the assembler use the difference-table kluge?

View File

@ -59,6 +59,7 @@
@set TIC54X
@set V850
@set VAX
@set XTENSA
@end ifset
@c man end
@c common OR combinations of conditions
@ -449,6 +450,13 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
@ifset Z8000
@c Z8000 has no machine-dependent assembler options
@end ifset
@ifset XTENSA
@emph{Target Xtensa options:}
[@b{--[no-]density}] [@b{--[no-]relax}] [@b{--[no-]generics}]
[@b{--[no-]text-section-literals}]
[@b{--[no-]target-align}] [@b{--[no-]longcalls}]
@end ifset
@c man end
@end smallexample
@ -1057,6 +1065,45 @@ Assemble for a little endian target.
See the info pages for documentation of the MMIX-specific options.
@end ifset
@ifset XTENSA
The following options are available when @value{AS} is configured for
an Xtensa processor.
@table @gcctabopt
@item --density | --no-density
Enable or disable use of instructions from the Xtensa code density
option. This is enabled by default when the Xtensa processor supports
the code density option.
@item --relax | --no-relax
Enable or disable instruction relaxation. This is enabled by default.
Note: In the current implementation, these options also control whether
assembler optimizations are performed, making these options equivalent
to @option{--generics} and @option{--no-generics}.
@item --generics | --no-generics
Enable or disable all assembler transformations of Xtensa instructions.
The default is @option{--generics};
@option{--no-generics} should be used only in the rare cases when the
instructions must be exactly as specified in the assembly source.
@item --text-section-literals | --no-text-section-literals
With @option{--text-@-section-@-literals}, literal pools are interspersed
in the text section. The default is
@option{--no-@-text-@-section-@-literals}, which places literals in a
separate section in the output file.
@item --target-align | --no-target-align
Enable or disable automatic alignment to reduce branch penalties at the
expense of some code density. The default is @option{--target-@-align}.
@item --longcalls | --no-longcalls
Enable or disable transformation of call instructions to allow calls
across a greater range of addresses. The default is
@option{--no-@-longcalls}.
@end table
@end ifset
@c man end
@menu
@ -2068,6 +2115,9 @@ is considered a comment and is ignored. The line comment character is
@ifset V850
@samp{#} on the V850;
@end ifset
@ifset XTENSA
@samp{#} for Xtensa systems;
@end ifset
see @ref{Machine Dependencies}. @refill
@c FIXME What about i860?
@ -3834,7 +3884,7 @@ required alignment; this can be useful if you want the alignment to be filled
with no-op instructions when appropriate.
The way the required alignment is specified varies from system to system.
For the a29k, hppa, m68k, m88k, w65, sparc, and Hitachi SH, and i386 using ELF
For the a29k, hppa, m68k, m88k, w65, sparc, Xtensa, and Hitachi SH, and i386 using ELF
format,
the first expression is the
alignment request in bytes. For example @samp{.align 8} advances
@ -5865,6 +5915,9 @@ subject, see the hardware manufacturer's manual.
@ifset V850
* V850-Dependent:: V850 Dependent Features
@end ifset
@ifset XTENSA
* Xtensa-Dependent:: Xtensa Dependent Features
@end ifset
@ifset Z8000
* Z8000-Dependent:: Z8000 Dependent Features
@end ifset
@ -6036,6 +6089,10 @@ family.
@include c-v850.texi
@end ifset
@ifset XTENSA
@include c-xtensa.texi
@end ifset
@ifset GENERIC
@c reverse effect of @down at top of generic Machine-Dep chapter
@raisesections
@ -6330,6 +6387,9 @@ support for openVMS/Alpha.
Timothy Wall, Michael Hayes, and Greg Smart contributed to the various tic*
flavors.
David Heine, Sterling Augustine, Bob Wilson and John Ruttenberg from Tensilica,
Inc. added support for Xtensa processors.
Several engineers at Cygnus Support have also provided many small bug fixes and
configuration enhancements.

740
gas/doc/c-xtensa.texi Normal file
View File

@ -0,0 +1,740 @@
@c Copyright (C) 2002 Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@c
@ifset GENERIC
@page
@node Xtensa-Dependent
@chapter Xtensa Dependent Features
@end ifset
@ifclear GENERIC
@node Machine Dependencies
@chapter Xtensa Dependent Features
@end ifclear
@cindex Xtensa architecture
This chapter covers features of the @sc{gnu} assembler that are specific
to the Xtensa architecture. For details about the Xtensa instruction
set, please consult the @cite{Xtensa Instruction Set Architecture (ISA)
Reference Manual}.
@menu
* Xtensa Options:: Command-line Options.
* Xtensa Syntax:: Assembler Syntax for Xtensa Processors.
* Xtensa Optimizations:: Assembler Optimizations.
* Xtensa Relaxation:: Other Automatic Transformations.
* Xtensa Directives:: Directives for Xtensa Processors.
@end menu
@node Xtensa Options
@section Command Line Options
The Xtensa version of the @sc{gnu} assembler supports these
special options:
@table @code
@item --density | --no-density
@kindex --density
@kindex --no-density
@cindex Xtensa density option
@cindex density option, Xtensa
Enable or disable use of the Xtensa code density option (16-bit
instructions). @xref{Density Instructions, ,Using Density
Instructions}. If the processor is configured with the density option,
this is enabled by default; otherwise, it is always disabled.
@item --relax | --no-relax
@kindex --relax
@kindex --no-relax
Enable or disable relaxation of instructions with immediate operands
that are outside the legal range for the instructions. @xref{Xtensa
Relaxation, ,Xtensa Relaxation}. The default is @samp{--relax} and this
default should almost always be used. If relaxation is disabled with
@samp{--no-relax}, instruction operands that are out of range will cause
errors. Note: In the current implementation, these options also control
whether assembler optimizations are performed, making these options
equivalent to @samp{--generics} and @samp{--no-generics}.
@item --generics | --no-generics
@kindex --generics
@kindex --no-generics
Enable or disable all assembler transformations of Xtensa instructions,
including both relaxation and optimization. The default is
@samp{--generics}; @samp{--no-generics} should only be used in the rare
cases when the instructions must be exactly as specified in the assembly
source.
@c The @samp{--no-generics} option is like @samp{--no-relax}
@c except that it also disables assembler optimizations (@pxref{Xtensa
@c Optimizations}).
As with @samp{--no-relax}, using @samp{--no-generics}
causes out of range instruction operands to be errors.
@item --text-section-literals | --no-text-section-literals
@kindex --text-section-literals
@kindex --no-text-section-literals
Control the treatment of literal pools. The default is
@samp{--no-@-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 @samp{--text-@-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 --target-align | --no-target-align
@kindex --target-align
@kindex --no-target-align
Enable or disable automatic alignment to reduce branch penalties at some
expense in code size. @xref{Xtensa Automatic Alignment, ,Automatic
Instruction Alignment}. This optimization is enabled by default. Note
that the assembler will always align instructions like @code{LOOP} that
have fixed alignment requirements.
@item --longcalls | --no-longcalls
@kindex --longcalls
@kindex --no-longcalls
Enable or disable transformation of call instructions to allow calls
across a greater range of addresses. @xref{Xtensa Call Relaxation,
,Function Call Relaxation}. This option should be used when call
targets can potentially be out of range, but it degrades both code size
and performance. The default is @samp{--no-@-longcalls}.
@end table
@node Xtensa Syntax
@section Assembler Syntax
@cindex syntax, Xtensa assembler
@cindex Xtensa assembler syntax
Block comments are delimited by @samp{/*} and @samp{*/}. End of line
comments may be introduced with either @samp{#} or @samp{//}.
Instructions consist of a leading opcode or macro name followed by
whitespace and an optional comma-separated list of operands:
@smallexample
@var{opcode} [@var{operand},@dots{}]
@end smallexample
Instructions must be separated by a newline or semicolon.
@menu
* Xtensa Opcodes:: Opcode Naming Conventions.
* Xtensa Registers:: Register Naming.
@end menu
@node Xtensa Opcodes
@subsection Opcode Names
@cindex Xtensa opcode names
@cindex opcode names, Xtenxa
See the @cite{Xtensa Instruction Set Architecture (ISA) Reference
Manual} for a complete list of opcodes and descriptions of their
semantics.
@cindex generic opcodes
@cindex specific opcodes
@cindex _ opcode prefix
The Xtensa assembler distinguishes between @dfn{generic} and
@dfn{specific} opcodes. Specific opcodes correspond directly to Xtensa
machine instructions. Prefixing an opcode with an underscore character
(@samp{_}) identifies it as a specific opcode. Opcodes without a
leading underscore are generic, which means the assembler is required to
preserve their semantics but may not translate them directly to the
specific opcodes with the same names. Instead, the assembler may
optimize a generic opcode and select a better instruction to use in its
place (@pxref{Xtensa Optimizations, ,Xtensa Optimizations}), or the
assembler may relax the instruction to handle operands that are out of
range for the corresponding specific opcode (@pxref{Xtensa Relaxation,
,Xtensa Relaxation}).
Only use specific opcodes when it is essential to select
the exact machine instructions produced by the assembler.
Using specific opcodes unnecessarily only makes the code less
efficient, by disabling assembler optimization, and less flexible, by
disabling relaxation.
Note that this special handling of underscore prefixes only applies to
Xtensa opcodes, not to either built-in macros or user-defined macros.
When an underscore prefix is used with a macro (e.g., @code{_NOP}), it
refers to a different macro. The assembler generally provides built-in
macros both with and without the underscore prefix, where the underscore
versions behave as if the underscore carries through to the instructions
in the macros. For example, @code{_NOP} expands to @code{_OR a1,a1,a1}.
The underscore prefix only applies to individual instructions, not to
series of instructions. For example, if a series of instructions have
underscore prefixes, the assembler will not transform the individual
instructions, but it may insert other instructions between them (e.g.,
to align a @code{LOOP} instruction). To prevent the assembler from
modifying a series of instructions as a whole, use the
@code{no-generics} directive. @xref{Generics Directive, ,generics}.
@node Xtensa Registers
@subsection Register Names
@cindex Xtensa register names
@cindex register names, Xtensa
@cindex sp register
An initial @samp{$} character is optional in all register names.
General purpose registers are named @samp{a0}@dots{}@samp{a15}. Additional
registers may be added by processor configuration options. In
particular, the @sc{mac16} option adds a @sc{mr} register bank. Its
registers are named @samp{m0}@dots{}@samp{m3}.
As a special feature, @samp{sp} is also supported as a synonym for
@samp{a1}.
@node Xtensa Optimizations
@section Xtensa Optimizations
@cindex optimizations
The optimizations currently supported by @code{@value{AS}} are
generation of density instructions where appropriate and automatic
branch target alignment.
@menu
* Density Instructions:: Using Density Instructions.
* Xtensa Automatic Alignment:: Automatic Instruction Alignment.
@end menu
@node Density Instructions
@subsection Using Density Instructions
@cindex density instructions
The Xtensa instruction set has a code density option that provides
16-bit versions of some of the most commonly used opcodes. Use of these
opcodes can significantly reduce code size. When possible, the
assembler automatically translates generic instructions from the core
Xtensa instruction set into equivalent instructions from the Xtensa code
density option. This translation can be disabled by using specific
opcodes (@pxref{Xtensa Opcodes, ,Opcode Names}), by using the
@samp{--no-density} command-line option (@pxref{Xtensa Options, ,Command
Line Options}), or by using the @code{no-density} directive
(@pxref{Density Directive, ,density}).
It is a good idea @emph{not} to use the density instuctions directly.
The assembler will automatically select dense instructions where
possible. If you later need to avoid using the code density option, you
can disable it in the assembler without having to modify the code.
@node Xtensa Automatic Alignment
@subsection Automatic Instruction Alignment
@cindex alignment of @code{LOOP} instructions
@cindex alignment of @code{ENTRY} instructions
@cindex alignment of branch targets
@cindex @code{LOOP} instructions, alignment
@cindex @code{ENTRY} instructions, alignment
@cindex branch target alignment
The Xtensa assembler will automatically align certain instructions, both
to optimize performance and to satisfy architectural requirements.
When the @code{--target-@-align} command-line option is enabled
(@pxref{Xtensa Options, ,Command Line Options}), the assembler attempts
to widen density instructions preceding a branch target so that the
target instruction does not cross a 4-byte boundary. Similarly, the
assembler also attempts to align each instruction following a call
instruction. If there are not enough preceding safe density
instructions to align a target, no widening will be performed. This
alignment has the potential to reduce branch penalties at some expense
in code size. The assembler will not attempt to align labels with the
prefixes @code{.Ln} and @code{.LM}, since these labels are used for
debugging information and are not typically branch targets.
The @code{LOOP} family of instructions must be aligned on either a 1 or
2 mod 4 byte boundary. The assembler knows about this restriction and
inserts the minimal number of 2 or 3 byte no-op instructions
to satisfy it. When no-op instructions are added, any label immediately
preceding the original loop will be moved in order to refer to the loop
instruction, not the newly generated no-op instruction.
Similarly, the @code{ENTRY} instruction must be aligned on a 0 mod 4
byte boundary. The assembler satisfies this requirement by inserting
zero bytes when required. In addition, labels immediately preceding the
@code{ENTRY} instruction will be moved to the newly aligned instruction
location.
@node Xtensa Relaxation
@section Xtensa Relaxation
@cindex relaxation
When an instruction operand is outside the range allowed for that
particular instruction field, @code{@value{AS}} can transform the code
to use a functionally-equivalent instruction or sequence of
instructions. This process is known as @dfn{relaxation}. This is
typically done for branch instructions because the distance of the
branch targets is not known until assembly-time. The Xtensa assembler
offers branch relaxation and also extends this concept to function
calls, @code{MOVI} instructions and other instructions with immediate
fields.
@menu
* Xtensa Branch Relaxation:: Relaxation of Branches.
* Xtensa Call Relaxation:: Relaxation of Function Calls.
* Xtensa Immediate Relaxation:: Relaxation of other Immediate Fields.
@end menu
@node Xtensa Branch Relaxation
@subsection Conditional Branch Relaxation
@cindex relaxation of branch instructions
@cindex branch instructions, relaxation
When the target of a branch is too far away from the branch itself,
i.e., when the offset from the branch to the target is too large to fit
in the immediate field of the branch instruction, it may be necessary to
replace the branch with a branch around a jump. For example,
@smallexample
beqz a2, L
@end smallexample
may result in:
@smallexample
bnez.n a2, M
j L
M:
@end smallexample
(The @code{BNEZ.N} instruction would be used in this example only if the
density option is available. Otherwise, @code{BNEZ} would be used.)
@node Xtensa Call Relaxation
@subsection Function Call Relaxation
@cindex relaxation of call instructions
@cindex call instructions, relaxation
Function calls may require relaxation because the Xtensa immediate call
instructions (@code{CALL0}, @code{CALL4}, @code{CALL8} and
@code{CALL12}) provide a PC-relative offset of only 512 Kbytes in either
direction. For larger programs, it may be necessary to use indirect
calls (@code{CALLX0}, @code{CALLX4}, @code{CALLX8} and @code{CALLX12})
where the target address is specified in a register. The Xtensa
assembler can automatically relax immediate call instructions into
indirect call instructions. This relaxation is done by loading the
address of the called function into the callee's return address register
and then using a @code{CALLX} instruction. So, for example:
@smallexample
call8 func
@end smallexample
might be relaxed to:
@smallexample
.literal .L1, func
l32r a8, .L1
callx8 a8
@end smallexample
Because the addresses of targets of function calls are not generally
known until link-time, the assembler must assume the worst and relax all
the calls to functions in other source files, not just those that really
will be out of range. The linker can recognize calls that were
unnecessarily relaxed, but it can only partially remove the overhead
introduced by the assembler.
Call relaxation has a negative effect
on both code size and performance, so this relaxation is disabled by
default. If a program is too large and some of the calls are out of
range, function call relaxation can be enabled using the
@samp{--longcalls} command-line option or the @code{longcalls} directive
(@pxref{Longcalls Directive, ,longcalls}).
@node Xtensa Immediate Relaxation
@subsection Other Immediate Field Relaxation
@cindex immediate fields, relaxation
@cindex relaxation of immediate fields
@cindex @code{MOVI} instructions, relaxation
@cindex relaxation of @code{MOVI} instructions
The @code{MOVI} machine instruction can only materialize values in the
range from -2048 to 2047. Values outside this range are best
materalized with @code{L32R} instructions. Thus:
@smallexample
movi a0, 100000
@end smallexample
is assembled into the following machine code:
@smallexample
.literal .L1, 100000
l32r a0, .L1
@end smallexample
@cindex @code{L8UI} instructions, relaxation
@cindex @code{L16SI} instructions, relaxation
@cindex @code{L16UI} instructions, relaxation
@cindex @code{L32I} instructions, relaxation
@cindex relaxation of @code{L8UI} instructions
@cindex relaxation of @code{L16SI} instructions
@cindex relaxation of @code{L16UI} instructions
@cindex relaxation of @code{L32I} instructions
The @code{L8UI} machine instruction can only be used with immediate
offsets in the range from 0 to 255. The @code{L16SI} and @code{L16UI}
machine instructions can only be used with offsets from 0 to 510. The
@code{L32I} machine instruction can only be used with offsets from 0 to
1020. A load offset outside these ranges can be materalized with
an @code{L32R} instruction if the destination register of the load
is different than the source address register. For example:
@smallexample
l32i a1, a0, 2040
@end smallexample
is translated to:
@smallexample
.literal .L1, 2040
l32r a1, .L1
addi a1, a0, a1
l32i a1, a1, 0
@end smallexample
@noindent
If the load destination and source address register are the same, an
out-of-range offset causes an error.
@cindex @code{ADDI} instructions, relaxation
@cindex relaxation of @code{ADDI} instructions
The Xtensa @code{ADDI} instruction only allows immediate operands in the
range from -128 to 127. There are a number of alternate instruction
sequences for the generic @code{ADDI} operation. First, if the
immediate is 0, the @code{ADDI} will be turned into a @code{MOV.N}
instruction (or the equivalent @code{OR} instruction if the code density
option is not available). If the @code{ADDI} immediate is outside of
the range -128 to 127, but inside the range -32896 to 32639, an
@code{ADDMI} instruction or @code{ADDMI}/@code{ADDI} sequence will be
used. Finally, if the immediate is outside of this range and a free
register is available, an @code{L32R}/@code{ADD} sequence will be used
with a literal allocated from the literal pool.
For example:
@smallexample
addi a5, a6, 0
addi a5, a6, 512
addi a5, a6, 513
addi a5, a6, 50000
@end smallexample
is assembled into the following:
@smallexample
.literal .L1, 50000
mov.n a5, a6
addmi a5, a6, 0x200
addmi a5, a6, 0x200
addi a5, a5, 1
l32r a5, .L1
add a5, a6, a5
@end smallexample
@node Xtensa Directives
@section Directives
@cindex Xtensa directives
@cindex directives, Xtensa
The Xtensa assember supports a region-based directive syntax:
@smallexample
.begin @var{directive} [@var{options}]
@dots{}
.end @var{directive}
@end smallexample
All the Xtensa-specific directives that apply to a region of code use
this syntax.
The directive applies to code between the @code{.begin} and the
@code{.end}. The state of the option after the @code{.end} reverts to
what it was before the @code{.begin}.
A nested @code{.begin}/@code{.end} region can further
change the state of the directive without having to be aware of its
outer state. For example, consider:
@smallexample
.begin no-density
L: add a0, a1, a2
.begin density
M: add a0, a1, a2
.end density
N: add a0, a1, a2
.end no-density
@end smallexample
The generic @code{ADD} opcodes at @code{L} and @code{N} in the outer
@code{no-density} region both result in @code{ADD} machine instructions,
but the assembler selects an @code{ADD.N} instruction for the generic
@code{ADD} at @code{M} in the inner @code{density} region.
The advantage of this style is that it works well inside macros which can
preserve the context of their callers.
@cindex precedence of directives
@cindex directives, precedence
When command-line options and assembler directives are used at the same
time and conflict, the one that overrides a default behavior takes
precedence over one that is the same as the default. For example, if
the code density option is available, the default is to select density
instructions whenever possible. So, if the above is assembled with the
@samp{--no-density} flag, which overrides the default, all the generic
@code{ADD} instructions result in @code{ADD} machine instructions. If
assembled with the @samp{--density} flag, which is already the default,
the @code{no-density} directive takes precedence and only one of
the generic @code{ADD} instructions is optimized to be a @code{ADD.N}
machine instruction. An underscore prefix identifying a specific opcode
always takes precedence over directives and command-line flags.
The following directives are available:
@menu
* Density Directive:: Disable Use of Density Instructions.
* Relax Directive:: Disable Assembler Relaxation.
* Longcalls Directive:: Use Indirect Calls for Greater Range.
* Generics Directive:: Disable All Assembler Transformations.
* Literal Directive:: Intermix Literals with Instructions.
* Literal Position Directive:: Specify Inline Literal Pool Locations.
* Literal Prefix Directive:: Specify Literal Section Name Prefix.
* Freeregs Directive:: List Registers Available for Assembler Use.
* Frame Directive:: Describe a stack frame.
@end menu
@node Density Directive
@subsection density
@cindex @code{density} directive
@cindex @code{no-density} directive
The @code{density} and @code{no-density} directives enable or disable
optimization of generic instructions into density instructions within
the region. @xref{Density Instructions, ,Using Density Instructions}.
@smallexample
.begin [no-]density
.end [no-]density
@end smallexample
This optimization is enabled by default unless the Xtensa configuration
does not support the code density option or the @samp{--no-density}
command-line option was specified.
@node Relax Directive
@subsection relax
@cindex @code{relax} directive
@cindex @code{no-relax} directive
The @code{relax} directive enables or disables relaxation
within the region. @xref{Xtensa Relaxation, ,Xtensa Relaxation}.
Note: In the current implementation, these directives also control
whether assembler optimizations are performed, making them equivalent to
the @code{generics} and @code{no-generics} directives.
@smallexample
.begin [no-]relax
.end [no-]relax
@end smallexample
Relaxation is enabled by default unless the @samp{--no-relax}
command-line option was specified.
@node Longcalls Directive
@subsection longcalls
@cindex @code{longcalls} directive
@cindex @code{no-longcalls} directive
The @code{longcalls} directive enables or disables function call
relaxation. @xref{Xtensa Call Relaxation, ,Function Call Relaxation}.
@smallexample
.begin [no-]longcalls
.end [no-]longcalls
@end smallexample
Call relaxation is disabled by default unless the @samp{--longcalls}
command-line option is specified.
@node Generics Directive
@subsection generics
@cindex @code{generics} directive
@cindex @code{no-generics} directive
This directive enables or disables all assembler transformation,
including relaxation (@pxref{Xtensa Relaxation, ,Xtensa Relaxation}) and
optimization (@pxref{Xtensa Optimizations, ,Xtensa Optimizations}).
@smallexample
.begin [no-]generics
.end [no-]generics
@end smallexample
Disabling generics is roughly equivalent to adding an underscore prefix
to every opcode within the region, so that every opcode is treated as a
specific opcode. @xref{Xtensa Opcodes, ,Opcode Names}. In the current
implementation of @code{@value{AS}}, built-in macros are also disabled
within a @code{no-generics} region.
@node Literal Directive
@subsection literal
@cindex @code{literal} directive
The @code{.literal} directive is used to define literal pool data, i.e.,
read-only 32-bit data accessed via @code{L32R} instructions.
@smallexample
.literal @var{label}, @var{value}[, @var{value}@dots{}]
@end smallexample
This directive is similar to the standard @code{.word} directive, except
that the actual location of the literal data is determined by the
assembler and linker, not by the position of the @code{.literal}
directive. Using this directive gives the assembler freedom to locate
the literal data in the most appropriate place and possibly to combine
identical literals. For example, the code:
@smallexample
entry sp, 40
.literal .L1, sym
l32r a4, .L1
@end smallexample
can be used to load a pointer to the symbol @code{sym} into register
@code{a4}. The value of @code{sym} will not be placed between the
@code{ENTRY} and @code{L32R} instructions; instead, the assembler puts
the data in a literal pool.
By default literal pools are placed in a separate section; however, when
using the @samp{--text-@-section-@-literals} option (@pxref{Xtensa
Options, ,Command Line Options}), the literal pools are placed in the
current section. These text section literal pools are created
automatically before @code{ENTRY} instructions and manually after
@samp{.literal_position} directives (@pxref{Literal Position Directive,
,literal_position}). If there are no preceding @code{ENTRY}
instructions or @code{.literal_position} directives, the assembler will
print a warning and place the literal pool at the beginning of the
current section. In such cases, explicit @code{.literal_position}
directives should be used to place the literal pools.
@node Literal Position Directive
@subsection literal_position
@cindex @code{literal_position} directive
When using @samp{--text-@-section-@-literals} to place literals inline
in the section being assembled, the @code{.literal_position} directive
can be used to mark a potential location for a literal pool.
@smallexample
.literal_position
@end smallexample
The @code{.literal_position} directive is ignored when the
@samp{--text-@-section-@-literals} option is not used.
The assembler will automatically place text section literal pools
before @code{ENTRY} instructions, so the @code{.literal_position}
directive is only needed to specify some other location for a literal
pool. You may need to add an explicit jump instruction to skip over an
inline literal pool.
For example, an interrupt vector does not begin with an @code{ENTRY}
instruction so the assembler will be unable to automatically find a good
place to put a literal pool. Moreover, the code for the interrupt
vector must be at a specific starting address, so the literal pool
cannot come before the start of the code. The literal pool for the
vector must be explicitly positioned in the middle of the vector (before
any uses of the literals, of course). The @code{.literal_position}
directive can be used to do this. In the following code, the literal
for @samp{M} will automatically be aligned correctly and is placed after
the unconditional jump.
@smallexample
.global M
code_start:
j continue
.literal_position
.align 4
continue:
movi a4, M
@end smallexample
@node Literal Prefix Directive
@subsection literal_prefix
@cindex @code{literal_prefix} directive
The @code{literal_prefix} directive allows you to specify different
sections to hold literals from different portions of an assembly file.
With this directive, a single assembly file can be used to generate code
into multiple sections, including literals generated by the assembler.
@smallexample
.begin literal_prefix [@var{name}]
.end literal_prefix
@end smallexample
For the code inside the delimited region, the assembler puts literals in
the section @code{@var{name}.literal}. If this section does not yet
exist, the assembler creates it. The @var{name} parameter is
optional. If @var{name} is not specified, the literal prefix is set to
the ``default'' for the file. This default is usually @code{.literal}
but can be changed with the @samp{--rename-section} command-line
argument.
@node Freeregs Directive
@subsection freeregs
@cindex @code{freeregs} directive
This directive tells the assembler that the given registers are unused
in the region.
@smallexample
.begin freeregs @var{ri}[,@var{ri}@dots{}]
.end freeregs
@end smallexample
This allows the assembler to use these registers for relaxations or
optimizations. (They are actually only for relaxations at present, but
the possibility of optimizations exists in the future.)
Nested @code{freeregs} directives can be used to add additional registers
to the list of those available to the assembler. For example:
@smallexample
.begin freeregs a3, a4
.begin freeregs a5
@end smallexample
has the effect of declaring @code{a3}, @code{a4}, and @code{a5} all free.
@node Frame Directive
@subsection frame
@cindex @code{frame} directive
This directive tells the assembler to emit information to allow the
debugger to locate a function's stack frame. The syntax is:
@smallexample
.frame @var{reg}, @var{size}
@end smallexample
where @var{reg} is the register used to hold the frame pointer (usually
the same as the stack pointer) and @var{size} is the size in bytes of
the stack frame. The @code{.frame} directive is typically placed
immediately after the @code{ENTRY} instruction for a function.
In almost all circumstances, this information just duplicates the
information given in the function's @code{ENTRY} instruction; however,
there are two cases where this is not true:
@enumerate
@item
The size of the stack frame is too big to fit in the immediate field
of the @code{ENTRY} instruction.
@item
The frame pointer is different than the stack pointer, as with functions
that call @code{alloca}.
@end enumerate
@c Local Variables:
@c fill-column: 72
@c End:

View File

@ -1450,6 +1450,10 @@ completed, but before the relocations have been generated.
If you define this macro, GAS will call it after the relocs have been
generated.
@item md_post_relax_hook
If you define this macro, GAS will call it after relaxing and sizing the
segments.
@item LISTING_HEADER
A string to use on the header line of a listing. The default value is simply
@code{"GAS LISTING"}.

View File

@ -1,3 +1,13 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* gas/xtensa/all.exp: New file.
* gas/xtensa/entry_align.s: Likewise.
* gas/xtensa/entry_misalign2.s: Likewise.
* gas/xtensa/entry_misalign.s: Likewise.
* gas/xtensa/j_too_far.s: Likewise.
* gas/xtensa/loop_align.s: Likewise.
* gas/xtensa/loop_misalign.s: Likewise.
2003-03-25 Stan Cox <scox@redhat.com>
Nick Clifton <nickc@redhat.com>

View File

@ -0,0 +1,98 @@
#
# Some generic xtensa tests
#
if [istarget xtensa*-*-*] then {
gas_test_error "j_too_far.s" "" "Check for jump out of range error"
set testname "j_too_far.s: error line number reporting"
gas_start "j_too_far.s" ""
set x1 0
while 1 {
expect {
-re ":4: Error:.*too large" { set x1 1 }
timeout { perror "timeout\n"; break }
eof { break }
}
}
gas_finish
if [all_ones $x1] then { pass $testname } else { fail $testname }
gas_test "entry_misalign.s" "" "" "Xtensa Entry misalignment"
set testname "entry_misalign.s: Force entry misalignment"
objdump_start_no_subdir "a.out" "-d -j .text"
set x1 0
while 1 {
expect {
-re "^.*2:.*entry" { set x1 1 }
timeout { perror "timeout\n"; break }
eof { break }
}
}
objdump_finish
if [all_ones $x1] then { pass $testname } else { fail $testname }
gas_test "entry_misalign2.s" "" "" "Xtensa Entry misalignment(2)"
set testname "entry_misalign2.s: Force entry misalignment(2)"
objdump_start_no_subdir "a.out" "-d -j .text"
set x1 0
while 1 {
expect {
-re "^.*2:.*entry" { set x1 1 }
timeout { perror "timeout\n"; break }
eof { break }
}
}
objdump_finish
if [all_ones $x1] then { pass $testname } else { fail $testname }
gas_test "entry_align.s" "" "" "Xtensa autoalign entry"
set testname "entry_align.s: autoalign entry"
objdump_start_no_subdir "a.out" "-d -j .text"
set x1 0
while 1 {
expect {
-re "^.*4:.*entry" { set x1 1 }
timeout { perror "timeout\n"; break }
eof { break }
}
}
objdump_finish
if [all_ones $x1] then { pass $testname } else { fail $testname }
gas_test "loop_misalign.s" "" "" "Xtensa Loop misalignment"
set testname "loop_misalign.s: Force loop misalignment"
objdump_start_no_subdir "a.out" "-d -j .text"
set x1 0
while 1 {
expect {
-re "^.*0:.*loop" { set x1 1 }
timeout { perror "timeout\n"; break }
eof { break }
}
}
objdump_finish
if [all_ones $x1] then { pass $testname } else { fail $testname }
gas_test "loop_align.s" "" "" "Xtensa autoalign loop"
set testname "loop_align.s: autoalign loop"
objdump_start_no_subdir "a.out" "-d -j .text"
set x1 0
while 1 {
expect {
-re "^.*2:.*loop" { set x1 1 }
timeout { perror "timeout\n"; break }
eof { break }
}
}
objdump_finish
if [all_ones $x1] then { pass $testname } else { fail $testname }
}
if [info exists errorInfo] then {
unset errorInfo
}

View File

@ -0,0 +1,4 @@
_nop.n
l4:
entry a5,16
_mov.n a4,a5

View File

@ -0,0 +1,4 @@
_nop.n
l4:
_entry a5,16
_mov.n a4,a5

View File

@ -0,0 +1,6 @@
.begin no-generics
nop.n
l4:
entry a5,16
mov.n a4,a5
.end no-generics

View File

@ -0,0 +1,8 @@
.text
.align 4
entry a5,16
j too_far
.fill 150000
too_far:
nop
nop

View File

@ -0,0 +1,5 @@
l4:
loop a5,l5
_mov.n a4,a5
l5:
_nop.n

View File

@ -0,0 +1,5 @@
l4:
_loop a5,l5
_mov.n a4,a5
l5:
_nop.n

View File

@ -1586,6 +1586,10 @@ write_object_file ()
/* Relaxation has completed. Freeze all syms. */
finalize_syms = 1;
#ifdef md_post_relax_hook
md_post_relax_hook;
#endif
#ifndef BFD_ASSEMBLER
/* Crawl the symbol chain.

View File

@ -1,3 +1,10 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* dis-asm.h (print_insn_xtensa): Declare.
* xtensa-config.h: New file.
* xtensa-isa-internal.h: Likewise.
* xtensa-isa.h: Likewise.
2003-03-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* ansidecl.h (ATTRIBUTE_NONNULL, ATTRIBUTE_NULL_PRINTF,

View File

@ -237,6 +237,7 @@ extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_vax PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_xstormy16 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_xtensa PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sh64 PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_sh64x_media PARAMS ((bfd_vma, disassemble_info *));
extern int print_insn_frv PARAMS ((bfd_vma, disassemble_info *));

View File

@ -1,3 +1,8 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* elf/common.h (EM_XTENSA_OLD): Define.
* elf/xtensa.h: New file.
2003-04-01 Nick Clifton <nickc@redhat.com>
* arm.h (ARM_NOTE_SECTION): Include .gnu in the string.

View File

@ -261,6 +261,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Vitesse IQ2000. */
#define EM_IQ2000 0xFEBA
/* Old, unofficial value for Xtensa. */
#define EM_XTENSA_OLD 0xabc7
/* See the above comment before you add a new EM_* value here. */
/* Values for e_version. */

87
include/elf/xtensa.h Normal file
View File

@ -0,0 +1,87 @@
/* Xtensa ELF support for BFD.
Copyright 2003 Free Software Foundation, Inc.
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
This file is part of BFD, the Binary File Descriptor library.
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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This file holds definitions specific to the Xtensa ELF ABI. */
#ifndef _ELF_XTENSA_H
#define _ELF_XTENSA_H
#include "elf/reloc-macros.h"
/* Relocations. */
START_RELOC_NUMBERS (elf_xtensa_reloc_type)
RELOC_NUMBER (R_XTENSA_NONE, 0)
RELOC_NUMBER (R_XTENSA_32, 1)
RELOC_NUMBER (R_XTENSA_RTLD, 2)
RELOC_NUMBER (R_XTENSA_GLOB_DAT, 3)
RELOC_NUMBER (R_XTENSA_JMP_SLOT, 4)
RELOC_NUMBER (R_XTENSA_RELATIVE, 5)
RELOC_NUMBER (R_XTENSA_PLT, 6)
RELOC_NUMBER (R_XTENSA_OP0, 8)
RELOC_NUMBER (R_XTENSA_OP1, 9)
RELOC_NUMBER (R_XTENSA_OP2, 10)
RELOC_NUMBER (R_XTENSA_ASM_EXPAND, 11)
RELOC_NUMBER (R_XTENSA_ASM_SIMPLIFY, 12)
RELOC_NUMBER (R_XTENSA_GNU_VTINHERIT, 15)
RELOC_NUMBER (R_XTENSA_GNU_VTENTRY, 16)
END_RELOC_NUMBERS (R_XTENSA_max)
/* Processor-specific flags for the ELF header e_flags field. */
/* Four-bit Xtensa machine type field. */
#define EF_XTENSA_MACH 0x0000000f
/* Various CPU types. */
#define E_XTENSA_MACH 0x00000000
/* Leave bits 0xf0 alone in case we ever have more than 16 cpu types.
Highly unlikely, but what the heck. */
#define EF_XTENSA_XT_INSN 0x00000100
#define EF_XTENSA_XT_LIT 0x00000200
/* Processor-specific dynamic array tags. */
/* Offset of the table that records the GOT location(s). */
#define DT_XTENSA_GOT_LOC_OFF 0x70000000
/* Number of entries in the GOT location table. */
#define DT_XTENSA_GOT_LOC_SZ 0x70000001
/* Definitions for instruction and literal property tables. The
instruction tables for ".gnu.linkonce.t.*" sections are placed in
the following sections:
instruction tables: .gnu.linkonce.x.*
literal tables: .gnu.linkonce.p.*
*/
#define XTENSA_INSN_SEC_NAME ".xt.insn"
#define XTENSA_LIT_SEC_NAME ".xt.lit"
typedef struct property_table_entry_t
{
bfd_vma address;
bfd_vma size;
} property_table_entry;
#endif /* _ELF_XTENSA_H */

70
include/xtensa-config.h Normal file
View File

@ -0,0 +1,70 @@
/* Xtensa configuration settings.
Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
** NOTE: This file was automatically generated by the Xtensa Processor
** Generator. Changes made here will be lost when this file is
** updated or replaced with the settings for a different Xtensa
** processor configuration. DO NOT EDIT!
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
/* The macros defined here match those with the same names in the Xtensa
compile-time HAL (Hardware Abstraction Layer). Please refer to the
Xtensa System Software Reference Manual for documentation of these
macros. */
#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_LOOPS 1
#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_HAVE_WINDOWED 1
#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
#define XCHAL_HAVE_DEBUG 1
#define XCHAL_NUM_IBREAK 2
#define XCHAL_NUM_DBREAK 2
#define XCHAL_DEBUGLEVEL 4
#define XCHAL_EXTRA_SA_SIZE 0
#define XCHAL_EXTRA_SA_ALIGN 1
#endif /* !XTENSA_CONFIG_H */

View File

@ -0,0 +1,114 @@
/* Internal definitions for configurable Xtensa ISA support.
Copyright 2003 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Use the statically-linked version for the GNU tools. */
#define STATIC_LIBISA 1
#define ISA_INTERFACE_VERSION 3
struct config_struct
{
char *param_name;
char *param_value;
};
/* Encode/decode function types for immediate operands. */
typedef uint32 (*xtensa_immed_decode_fn) (uint32);
typedef xtensa_encode_result (*xtensa_immed_encode_fn) (uint32 *);
/* Field accessor function types. */
typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf);
typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32);
/* PC-relative relocation function types. */
typedef uint32 (*xtensa_do_reloc_fn) (uint32, uint32);
typedef uint32 (*xtensa_undo_reloc_fn) (uint32, uint32);
/* Instruction decode function type. */
typedef int (*xtensa_insn_decode_fn) (const xtensa_insnbuf);
/* Instruction encoding template function type (each of these functions
returns a constant template; they exist only to make it easier for the
TIE compiler to generate endian-independent DLLs). */
typedef xtensa_insnbuf (*xtensa_encoding_template_fn) (void);
typedef struct xtensa_operand_internal_struct
{
char *operand_kind; /* e.g., "a", "f", "i", "l".... */
char inout; /* '<', '>', or '='. */
char isPCRelative; /* Is this a PC-relative offset? */
xtensa_get_field_fn get_field; /* Get encoded value of the field. */
xtensa_set_field_fn set_field; /* Set field with an encoded value. */
xtensa_immed_encode_fn encode; /* Encode the operand value. */
xtensa_immed_decode_fn decode; /* Decode the value from the field. */
xtensa_do_reloc_fn do_reloc; /* Perform a PC-relative relocation. */
xtensa_undo_reloc_fn undo_reloc; /* Undo a PC-relative relocation. */
} xtensa_operand_internal;
typedef struct xtensa_iclass_internal_struct
{
int num_operands; /* Size of "operands" array. */
xtensa_operand_internal **operands; /* Array of operand structures. */
} xtensa_iclass_internal;
typedef struct xtensa_opcode_internal_struct
{
const char *name; /* Opcode mnemonic. */
int length; /* Length in bytes of the insn. */
xtensa_encoding_template_fn template; /* Fn returning encoding template. */
xtensa_iclass_internal *iclass; /* Iclass for this opcode. */
} xtensa_opcode_internal;
typedef struct opname_lookup_entry_struct
{
const char *key; /* Opcode mnemonic. */
xtensa_opcode opcode; /* Internal opcode number. */
} opname_lookup_entry;
typedef struct xtensa_isa_internal_struct
{
int is_big_endian; /* Endianness. */
int insn_size; /* Maximum length in bytes. */
int insnbuf_size; /* Number of insnbuf_words. */
int num_opcodes; /* Total number for all modules. */
xtensa_opcode_internal **opcode_table;/* Indexed by internal opcode #. */
int num_modules; /* Number of modules (DLLs) loaded. */
int *module_opcode_base; /* Starting opcode # for each module. */
xtensa_insn_decode_fn *module_decode_fn; /* Decode fn for each module. */
opname_lookup_entry *opname_lookup_table; /* Lookup table for each module. */
struct config_struct *config; /* Table of configuration parameters. */
int has_density; /* Is density option available? */
} xtensa_isa_internal;
typedef struct xtensa_isa_module_struct
{
const int (*get_num_opcodes_fn) (void);
xtensa_opcode_internal **(*get_opcodes_fn) (void);
int (*decode_insn_fn) (const xtensa_insnbuf);
struct config_struct *(*get_config_table_fn) (void);
} xtensa_isa_module;
extern xtensa_isa_module xtensa_isa_modules[];

230
include/xtensa-isa.h Normal file
View File

@ -0,0 +1,230 @@
/* Interface definition for configurable Xtensa ISA support.
Copyright 2003 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef XTENSA_LIBISA_H
#define XTENSA_LIBISA_H
/* Use the statically-linked version for the GNU tools. */
#define STATIC_LIBISA 1
#ifdef __cplusplus
extern "C" {
#endif
#ifndef uint32
#define uint32 unsigned int
#endif
/* This file defines the interface to the Xtensa ISA library. This library
contains most of the ISA-specific information for a particular Xtensa
processor. For example, the set of valid instructions, their opcode
encodings and operand fields are all included here. To support Xtensa's
configurability and user-defined instruction extensions (i.e., TIE), the
library is initialized by loading one or more dynamic libraries; only a
small set of interface code is present in the statically-linked portion
of the library.
This interface basically defines four abstract data types.
. an instruction buffer - for holding the raw instruction bits
. ISA info - information about the ISA as a whole
. opcode info - information about individual instructions
. operand info - information about specific instruction operands
It would be nice to implement these as classes in C++, but the library is
implemented in C to match the expectations of the GNU tools.
Instead, the interface defines a set of functions to access each data
type. With the exception of the instruction buffer, the internal
representations of the data structures are hidden. All accesses must be
made through the functions defined here. */
typedef void* xtensa_isa;
typedef void* xtensa_operand;
/* Opcodes are represented here using sequential integers beginning with 0.
The specific value used for a particular opcode is only fixed for a
particular instantiation of an xtensa_isa structure, so these values
should only be used internally. */
typedef int xtensa_opcode;
/* Define a unique value for undefined opcodes ("static const int" doesn't
seem to work for this because EGCS 1.0.3 on i686-Linux without -O won't
allow it to be used as an initializer). */
#define XTENSA_UNDEFINED -1
typedef int libisa_module_specifier;
extern xtensa_isa xtensa_isa_init (void);
/* Instruction buffers. */
typedef uint32 xtensa_insnbuf_word;
typedef xtensa_insnbuf_word *xtensa_insnbuf;
/* Get the size in words of the xtensa_insnbuf array. */
extern int xtensa_insnbuf_size (xtensa_isa);
/* Allocate (with malloc) an xtensa_insnbuf of the right size. */
extern xtensa_insnbuf xtensa_insnbuf_alloc (xtensa_isa);
/* Release (with free) an xtensa_insnbuf of the right size. */
extern void xtensa_insnbuf_free (xtensa_insnbuf);
/* Inward and outward conversion from memory images (byte streams) to our
internal instruction representation. */
extern void xtensa_insnbuf_to_chars (xtensa_isa, const xtensa_insnbuf,
char *);
extern void xtensa_insnbuf_from_chars (xtensa_isa, xtensa_insnbuf,
const char *);
/* ISA information. */
/* Load the ISA information from a shared library. If successful, this returns
a value which identifies the ISA for use in subsequent calls to the ISA
library; otherwise, it returns NULL. Multiple ISAs can be loaded to support
heterogeneous multiprocessor systems. */
extern xtensa_isa xtensa_load_isa (libisa_module_specifier);
/* Extend an existing set of ISA information by loading an additional shared
library of ISA information. This is primarily intended for loading TIE
extensions. If successful, the return value is non-zero. */
extern int xtensa_extend_isa (xtensa_isa, libisa_module_specifier);
/* The default ISA. This variable is set automatically to the ISA most
recently loaded and is provided as a convenience. An exception is the GNU
opcodes library, where there is a fixed interface that does not allow
passing the ISA as a parameter and the ISA must be taken from this global
variable. (Note: Since this variable is just a convenience, it is not
exported when libisa is built as a DLL, due to the hassle of dealing with
declspecs.) */
extern xtensa_isa xtensa_default_isa;
/* Deallocate an xtensa_isa structure. */
extern void xtensa_isa_free (xtensa_isa);
/* Get the maximum instruction size in bytes. */
extern int xtensa_insn_maxlength (xtensa_isa);
/* Get the total number of opcodes for this processor. */
extern int xtensa_num_opcodes (xtensa_isa);
/* Translate a mnemonic name to an opcode. Returns XTENSA_UNDEFINED if
the name is not a valid opcode mnemonic. */
extern xtensa_opcode xtensa_opcode_lookup (xtensa_isa, const char *);
/* Decode a binary instruction buffer. Returns the opcode or
XTENSA_UNDEFINED if the instruction is illegal. */
extern xtensa_opcode xtensa_decode_insn (xtensa_isa, const xtensa_insnbuf);
/* Opcode information. */
/* Set the opcode field(s) in a binary instruction buffer. The operand
fields are set to zero. */
extern void xtensa_encode_insn (xtensa_isa, xtensa_opcode, xtensa_insnbuf);
/* Get the mnemonic name for an opcode. */
extern const char * xtensa_opcode_name (xtensa_isa, xtensa_opcode);
/* Find the length (in bytes) of an instruction. */
extern int xtensa_insn_length (xtensa_isa, xtensa_opcode);
/* Find the length of an instruction by looking only at the first byte. */
extern int xtensa_insn_length_from_first_byte (xtensa_isa, char);
/* Find the number of operands for an instruction. */
extern int xtensa_num_operands (xtensa_isa, xtensa_opcode);
/* Get the information about operand number "opnd" of a particular opcode. */
extern xtensa_operand xtensa_get_operand (xtensa_isa, xtensa_opcode, int);
/* Operand information. */
/* Find the kind of operand. There are three possibilities:
1) PC-relative immediates (e.g., "l", "L"). These can be identified with
the xtensa_operand_isPCRelative function.
2) non-PC-relative immediates ("i").
3) register-file short names (e.g., "a", "b", "m" and others defined
via TIE). */
extern char * xtensa_operand_kind (xtensa_operand);
/* Check if an operand is an input ('<'), output ('>'), or inout ('=')
operand. Note: The output operand of a conditional assignment
(e.g., movnez) appears here as an inout ('=') even if it is declared
in the TIE code as an output ('>'); this allows the compiler to
properly handle register allocation for conditional assignments. */
extern char xtensa_operand_inout (xtensa_operand);
/* Get and set the raw (encoded) value of the field for the specified
operand. The "set" function does not check if the value fits in the
field; that is done by the "encode" function below. */
extern uint32 xtensa_operand_get_field (xtensa_operand, const xtensa_insnbuf);
extern void xtensa_operand_set_field (xtensa_operand, xtensa_insnbuf, uint32);
/* Encode and decode operands. The raw bits in the operand field
may be encoded in a variety of different ways. These functions hide the
details of that encoding. The encode function has a special return type
(xtensa_encode_result) to indicate success or the reason for failure; the
encoded value is returned through the argument pointer. The decode function
has no possibility of failure and returns the decoded value. */
typedef enum
{
xtensa_encode_result_ok,
xtensa_encode_result_align,
xtensa_encode_result_not_in_table,
xtensa_encode_result_too_low,
xtensa_encode_result_too_high,
xtensa_encode_result_not_ok,
xtensa_encode_result_max = xtensa_encode_result_not_ok
} xtensa_encode_result;
extern xtensa_encode_result xtensa_operand_encode (xtensa_operand, uint32 *);
extern uint32 xtensa_operand_decode (xtensa_operand, uint32);
/* For PC-relative offset operands, the interpretation of the offset may vary
between opcodes, e.g., is it relative to the current PC or that of the next
instruction? The following functions are defined to perform PC-relative
relocations and to undo them (as in the disassembler). The first function
takes the desired address and the PC of the current instruction and returns
the unencoded value to be stored in the offset field. The second function
takes the unencoded offset value and the current PC and returns the address.
Note that these functions do not replace the encode/decode functions; the
operands must be encoded/decoded separately. */
extern int xtensa_operand_isPCRelative (xtensa_operand);
extern uint32 xtensa_operand_do_reloc (xtensa_operand, uint32, uint32);
extern uint32 xtensa_operand_undo_reloc (xtensa_operand, uint32, uint32);
#ifdef __cplusplus
}
#endif
#endif /* XTENSA_LIBISA_H */

View File

@ -1,3 +1,16 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* Makefile.am (ALL_EMULATIONS): Add eelf32xtensa.o.
(eelf32xtensa.c): New target.
* Makefile.in: Regenerate.
* configure.tgt: Handle xtensa-*-*.
* gen-doc.texi: Set XTENSA variable.
* ld.texinfo: Set XTENSA variable. Add new Xtensa node.
* emulparams/elf32xtensa.sh: New file.
* emulparams/xtensa-config.sh: Likewise.
* emultempl/xtensaelf.em: Likewise.
* scripttempl/elfxtensa.sc: Likewise.
2003-04-01 Jakub Jelinek <jakub@redhat.com>
* configure.tgt (powerpc*-*-linux*): Add elf32ppc to ppc64

View File

@ -183,6 +183,7 @@ ALL_EMULATIONS = \
eelf32ppcwindiss.o \
eelf32vax.o \
eelf32xstormy16.o \
eelf32xtensa.o \
eelf_i386.o \
eelf_i386_be.o \
eelf_i386_chaos.o \
@ -589,6 +590,11 @@ eelf32xstormy16.c: $(srcdir)/emulparams/elf32xstormy16.sh \
eelf32vax.c: $(srcdir)/emulparams/elf32vax.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32vax "$(tdir_elf32vax)"
eelf32xtensa.c: $(srcdir)/emulparams/elf32xtensa.sh \
$(srcdir)/emulparams/xtensa-config.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/xtensaelf.em \
$(srcdir)/scripttempl/elfxtensa.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32xtensa "$(tdir_elf32xtensa)"
eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32fr30 "$(tdir_fr30)"

View File

@ -297,6 +297,7 @@ ALL_EMULATIONS = \
eelf32ppcwindiss.o \
eelf32vax.o \
eelf32xstormy16.o \
eelf32xtensa.o \
eelf_i386.o \
eelf_i386_be.o \
eelf_i386_chaos.o \
@ -1315,6 +1316,11 @@ eelf32xstormy16.c: $(srcdir)/emulparams/elf32xstormy16.sh \
eelf32vax.c: $(srcdir)/emulparams/elf32vax.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32vax "$(tdir_elf32vax)"
eelf32xtensa.c: $(srcdir)/emulparams/elf32xtensa.sh \
$(srcdir)/emulparams/xtensa-config.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/xtensaelf.em \
$(srcdir)/scripttempl/elfxtensa.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32xtensa "$(tdir_elf32xtensa)"
eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32fr30 "$(tdir_fr30)"

View File

@ -525,6 +525,7 @@ iq2000-*-elf) targ_emul=elf32iq2000 ; targ_extra_emuls="elf32iq10" ;;
frv-*-*) targ_emul=elf32frv ;;
w65-*-*) targ_emul=w65 ;;
xstormy16-*-*) targ_emul=elf32xstormy16 ;;
xtensa-*-*) targ_emul=elf32xtensa;;
fr30-*-*) targ_emul=elf32fr30 ;;
mcore-*-pe) targ_emul=mcorepe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;

View File

@ -0,0 +1,32 @@
# First set some configuration-specific variables
. ${srcdir}/emulparams/xtensa-config.sh
# See genscripts.sh and ../scripttempl/elfxtensa.sc for the meaning of these.
SCRIPT_NAME=elfxtensa
TEMPLATE_NAME=elf32
EXTRA_EM_FILE=xtensaelf
OUTPUT_FORMAT=undefined
BIG_OUTPUT_FORMAT="elf32-xtensa-be"
LITTLE_OUTPUT_FORMAT="elf32-xtensa-le"
TEXT_START_ADDR=0x400000
NONPAGED_TEXT_START_ADDR=0x400000
ARCH=xtensa
MACHINE=
GENERATE_SHLIB_SCRIPT=yes
GENERATE_COMBRELOC_SCRIPT=yes
NO_SMALL_DATA=yes
OTHER_READONLY_SECTIONS='
.xt_except_table : { KEEP (*(.xt_except_table)) }
.xt.lit : { *(.xt.lit*) *(.gnu.linkonce.p*) }
'
OTHER_READWRITE_SECTIONS='
.xt_except_desc :
{
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
*(.xt_except_desc_end)
}
'
OTHER_SECTIONS='
.xt.insn : { *(.xt.insn) *(.gnu.linkonce.x*) }
'

View File

@ -0,0 +1,8 @@
# Xtensa configuration settings.
## NOTE: This file was automatically generated by the Xtensa Processor
## Generator. Changes made here will be lost when this file is
## updated or replaced with the settings for a different Xtensa
## processor configuration. DO NOT EDIT!
MAXPAGESIZE=0x1000

1586
ld/emultempl/xtensaelf.em Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
@set MSP430
@set TICOFF
@set WIN32
@set XTENSA
@c 3. Properties of this configuration
@clear SingleFormat

View File

@ -45,6 +45,7 @@
@set V850
@set VAX
@set WIN32
@set XTENSA
@end ifset
@c man end
@ -157,6 +158,9 @@ section entitled ``GNU Free Documentation License''.
@ifset WIN32
* Win32:: ld and WIN32 (cygwin/mingw)
@end ifset
@ifset XTENSA
* Xtensa:: ld and Xtensa Processors
@end ifset
@end ifclear
@ifclear SingleFormat
* BFD:: BFD
@ -1227,7 +1231,9 @@ This option is only supported on a few targets.
@ifset I960
@xref{i960,, @command{ld} and the Intel 960 family}.
@end ifset
@ifset XTENSA
@xref{Xtensa,, @command{ld} and Xtensa Processors}.
@end ifset
On some platforms, the @samp{--relax} option performs global
optimizations that become possible when the linker resolves addressing
@ -4446,6 +4452,9 @@ functionality are not listed.
@ifset WIN32
* WIN32:: @command{ld} and WIN32 (cygwin/mingw)
@end ifset
@ifset XTENSA
* Xtensa:: @command{ld} and Xtensa Processors
@end ifset
@end menu
@end ifset
@ -5077,6 +5086,72 @@ which is probably not what you wanted.
@end ifclear
@end ifset
@ifset XTENSA
@ifclear GENERIC
@raisesections
@end ifclear
@node Xtensa
@section @code{ld} and Xtensa Processors
@cindex Xtensa processors
The default @command{ld} behavior for Xtensa processors is to interpret
@code{SECTIONS} commands so that lists of explicitly named sections in a
specification with a wildcard file will be interleaved when necessary to
keep literal pools within the range of PC-relative load offsets. For
example, with the command:
@smallexample
SECTIONS
@{
.text : @{
*(.literal .text)
@}
@}
@end smallexample
@noindent
@command{ld} may interleave some of the @code{.literal}
and @code{.text} sections from different object files to ensure that the
literal pools are within the range of PC-relative load offsets. A valid
interleaving might place the @code{.literal} sections from an initial
group of files followed by the @code{.text} sections of that group of
files. Then, the @code{.literal} sections from the rest of the files
and the @code{.text} sections from the rest of the files would follow.
The non-interleaved order can still be specified as:
@smallexample
SECTIONS
@{
.text : @{
*(.literal) *(.text)
@}
@}
@end smallexample
@cindex @code{--relax} on Xtensa
@cindex relaxing on Xtensa
@kindex --no-relax
The Xtensa version of @command{ld} enables the @option{--relax} option by
default to attempt to reduce space in the output image by combining
literals with identical values. It also provides the
@option{--no-relax} option to disable this optimization. When enabled,
the relaxation algorithm ensures that a literal will only be merged with
another literal when the new merged literal location is within the
offset range of all of its uses.
The relaxation mechanism will also attempt to optimize
assembler-generated ``longcall'' sequences of
@code{L32R}/@code{CALLX@var{n}} when the target is known to fit into a
@code{CALL@var{n}} instruction encoding. The current optimization
converts the sequence into @code{NOP}/@code{CALL@var{n}} and removes the
literal referenced by the @code{L32R} instruction.
@ifclear GENERIC
@lowersections
@end ifclear
@end ifset
@ifclear SingleFormat
@node BFD
@chapter BFD

397
ld/scripttempl/elfxtensa.sc Normal file
View File

@ -0,0 +1,397 @@
#
# Unusual variables checked by this code:
# NOP - four byte opcode for no-op (defaults to 0)
# NO_SMALL_DATA - no .sbss/.sbss2/.sdata/.sdata2 sections if not
# empty.
# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
# INITIAL_READONLY_SECTIONS - at start of text segment
# OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
# (e.g., .PARISC.milli)
# OTHER_TEXT_SECTIONS - these get put in .text when relocating
# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
# (e.g., .PARISC.global)
# OTHER_BSS_SECTIONS - other than .bss .sbss ...
# OTHER_SECTIONS - at the end
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
# executable (e.g., _DYNAMIC_LINK)
# TEXT_START_SYMBOLS - symbols that appear at the start of the
# .text section.
# DATA_START_SYMBOLS - symbols that appear at the start of the
# .data section.
# OTHER_GOT_SYMBOLS - symbols defined just before .got.
# OTHER_GOT_SECTIONS - sections just after .got.
# OTHER_SDATA_SECTIONS - sections just after .sdata.
# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
# .bss section besides __bss_start.
# TEXT_DYNAMIC - .dynamic in text segment, not data segment.
# EMBEDDED - whether this is for an embedded system.
# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set
# start address of shared library.
# INPUT_FILES - INPUT command of files to always include
# WRITABLE_RODATA - if set, the .rodata section should be writable
# INIT_START, INIT_END - statements just before and just after
# combination of .init sections.
# FINI_START, FINI_END - statements just before and just after
# combination of .fini sections.
# STACK_ADDR - start of a .stack section.
# OTHER_END_SYMBOLS - symbols to place right at the end of the script.
#
# When adding sections, do note that the names of some sections are used
# when specifying the start address of the next.
#
# Many sections come in three flavours. There is the 'real' section,
# like ".data". Then there are the per-procedure or per-variable
# sections, generated by -ffunction-sections and -fdata-sections in GCC,
# and useful for --gc-sections, which for a variable "foo" might be
# ".data.foo". Then there are the linkonce sections, for which the linker
# eliminates duplicates, which are named like ".gnu.linkonce.d.foo".
# The exact correspondences are:
#
# Section Linkonce section
# .text .gnu.linkonce.t.foo
# .rodata .gnu.linkonce.r.foo
# .data .gnu.linkonce.d.foo
# .bss .gnu.linkonce.b.foo
# .sdata .gnu.linkonce.s.foo
# .sbss .gnu.linkonce.sb.foo
# .sdata2 .gnu.linkonce.s2.foo
# .sbss2 .gnu.linkonce.sb2.foo
# .debug_info .gnu.linkonce.wi.foo
# .tdata .gnu.linkonce.td.foo
# .tbss .gnu.linkonce.tb.foo
#
# Each of these can also have corresponding .rel.* and .rela.* sections.
test -z "$ENTRY" && ENTRY=_start
test -z "${ELFSIZE}" && ELFSIZE=32
test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8"
test "$LD_FLAG" = "N" && DATA_ADDR=.
test -n "$CREATE_SHLIB" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
test -z "$CREATE_SHLIB" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
DATA_SEGMENT_END=""
if test -n "${COMMONPAGESIZE}"; then
DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})"
DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);"
fi
INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }"
RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }"
INIT_LIT=".init.literal 0 : { *(.init.literal) }"
INIT=".init 0 : { *(.init) }"
FINI_LIT=".fini.literal 0 : { *(.fini.literal) }"
FINI=".fini 0 : { *(.fini) }"
if test -z "${NO_SMALL_DATA}"; then
SBSS=".sbss ${RELOCATING-0} :
{
${RELOCATING+PROVIDE (__sbss_start = .);}
${RELOCATING+PROVIDE (___sbss_start = .);}
*(.dynsbss)
*(.sbss${RELOCATING+ .sbss.* .gnu.linkonce.sb.*})
*(.scommon)
${RELOCATING+PROVIDE (__sbss_end = .);}
${RELOCATING+PROVIDE (___sbss_end = .);}
}"
SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2${RELOCATING+ .sbss2.* .gnu.linkonce.sb2.*}) }"
SDATA="/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata ${RELOCATING-0} :
{
${RELOCATING+${SDATA_START_SYMBOLS}}
*(.sdata${RELOCATING+ .sdata.* .gnu.linkonce.s.*})
}"
SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2${RELOCATING+ .sdata2.* .gnu.linkonce.s2.*}) }"
REL_SDATA=".rel.sdata ${RELOCATING-0} : { *(.rel.sdata${RELOCATING+ .rel.sdata.* .rel.gnu.linkonce.s.*}) }
.rela.sdata ${RELOCATING-0} : { *(.rela.sdata${RELOCATING+ .rela.sdata.* .rela.gnu.linkonce.s.*}) }"
REL_SBSS=".rel.sbss ${RELOCATING-0} : { *(.rel.sbss${RELOCATING+ .rel.sbss.* .rel.gnu.linkonce.sb.*}) }
.rela.sbss ${RELOCATING-0} : { *(.rela.sbss${RELOCATING+ .rela.sbss.* .rela.gnu.linkonce.sb.*}) }"
REL_SDATA2=".rel.sdata2 ${RELOCATING-0} : { *(.rel.sdata2${RELOCATING+ .rel.sdata2.* .rel.gnu.linkonce.s2.*}) }
.rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2${RELOCATING+ .rela.sdata2.* .rela.gnu.linkonce.s2.*}) }"
REL_SBSS2=".rel.sbss2 ${RELOCATING-0} : { *(.rel.sbss2${RELOCATING+ .rel.sbss2.* .rel.gnu.linkonce.sb2.*}) }
.rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2${RELOCATING+ .rela.sbss2.* .rela.gnu.linkonce.sb2.*}) }"
fi
CTOR=".ctors ${CONSTRUCTING-0} :
{
${CONSTRUCTING+${CTOR_START}}
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o $OTHER_EXCLUDE_FILES) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
${CONSTRUCTING+${CTOR_END}}
}"
DTOR=".dtors ${CONSTRUCTING-0} :
{
${CONSTRUCTING+${DTOR_START}}
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o $OTHER_EXCLUDE_FILES) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
${CONSTRUCTING+${DTOR_END}}
}"
STACK=" .stack ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} :
{
${RELOCATING+_stack = .;}
*(.stack)
}"
# if this is for an embedded system, don't add SIZEOF_HEADERS.
if [ -z "$EMBEDDED" ]; then
test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS"
else
test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}"
fi
cat <<EOF
ENTRY(${ENTRY})
${RELOCATING+${LIB_SEARCH_DIRS}}
${RELOCATING+/* Do we need any of these for elf?
__DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
${RELOCATING+${EXECUTABLE_SYMBOLS}}
${RELOCATING+${INPUT_FILES}}
${RELOCATING- /* For some reason, the Solaris linker makes bad executables
if gld -r is used and the intermediate file has sections starting
at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
bug. But for now assigning the zero vmas works. */}
SECTIONS
{
/* Read-only sections, merged into text segment: */
${CREATE_SHLIB-${RELOCATING+. = ${TEXT_BASE_ADDRESS};}}
${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}}
${CREATE_SHLIB-${INTERP}}
${INITIAL_READONLY_SECTIONS}
${TEXT_DYNAMIC+${DYNAMIC}}
.hash ${RELOCATING-0} : { *(.hash) }
.dynsym ${RELOCATING-0} : { *(.dynsym) }
.dynstr ${RELOCATING-0} : { *(.dynstr) }
.gnu.version ${RELOCATING-0} : { *(.gnu.version) }
.gnu.version_d ${RELOCATING-0}: { *(.gnu.version_d) }
.gnu.version_r ${RELOCATING-0}: { *(.gnu.version_r) }
EOF
if [ "x$COMBRELOC" = x ]; then
COMBRELOCCAT=cat
else
COMBRELOCCAT="cat > $COMBRELOC"
fi
eval $COMBRELOCCAT <<EOF
.rel.init ${RELOCATING-0} : { *(.rel.init) }
.rela.init ${RELOCATING-0} : { *(.rela.init) }
.rel.text ${RELOCATING-0} : { *(.rel.text${RELOCATING+ .rel.text.* .rel.gnu.linkonce.t.*}) }
.rela.text ${RELOCATING-0} : { *(.rela.text${RELOCATING+ .rela.text.* .rela.gnu.linkonce.t.*}) }
.rel.fini ${RELOCATING-0} : { *(.rel.fini) }
.rela.fini ${RELOCATING-0} : { *(.rela.fini) }
.rel.rodata ${RELOCATING-0} : { *(.rel.rodata${RELOCATING+ .rel.rodata.* .rel.gnu.linkonce.r.*}) }
.rela.rodata ${RELOCATING-0} : { *(.rela.rodata${RELOCATING+ .rela.rodata.* .rela.gnu.linkonce.r.*}) }
${OTHER_READONLY_RELOC_SECTIONS}
.rel.data ${RELOCATING-0} : { *(.rel.data${RELOCATING+ .rel.data.* .rel.gnu.linkonce.d.*}) }
.rela.data ${RELOCATING-0} : { *(.rela.data${RELOCATING+ .rela.data.* .rela.gnu.linkonce.d.*}) }
.rel.tdata ${RELOCATING-0} : { *(.rel.tdata${RELOCATING+ .rel.tdata.* .rel.gnu.linkonce.td.*}) }
.rela.tdata ${RELOCATING-0} : { *(.rela.tdata${RELOCATING+ .rela.tdata.* .rela.gnu.linkonce.td.*}) }
.rel.tbss ${RELOCATING-0} : { *(.rel.tbss${RELOCATING+ .rel.tbss.* .rel.gnu.linkonce.tb.*}) }
.rela.tbss ${RELOCATING-0} : { *(.rela.tbss${RELOCATING+ .rela.tbss.* .rela.gnu.linkonce.tb.*}) }
.rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
.rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
.rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
.rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
.rel.got ${RELOCATING-0} : { *(.rel.got) }
.rela.got ${RELOCATING-0} : { *(.rela.got) }
${OTHER_GOT_RELOC_SECTIONS}
${REL_SDATA}
${REL_SBSS}
${REL_SDATA2}
${REL_SBSS2}
.rel.bss ${RELOCATING-0} : { *(.rel.bss${RELOCATING+ .rel.bss.* .rel.gnu.linkonce.b.*}) }
.rela.bss ${RELOCATING-0} : { *(.rela.bss${RELOCATING+ .rela.bss.* .rela.gnu.linkonce.b.*}) }
EOF
if [ -n "$COMBRELOC" ]; then
cat <<EOF
.rel.dyn ${RELOCATING-0} :
{
EOF
sed -e '/^[ ]*[{}][ ]*$/d;/:[ ]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/ \1/' $COMBRELOC
cat <<EOF
}
.rela.dyn ${RELOCATING-0} :
{
EOF
sed -e '/^[ ]*[{}][ ]*$/d;/:[ ]*$/d;/\.rel\./d;s/^.*: { *\(.*\)}/ \1/' $COMBRELOC
cat <<EOF
}
EOF
fi
cat <<EOF
.rel.plt ${RELOCATING-0} : { *(.rel.plt) }
.rela.plt ${RELOCATING-0} : { *(.rela.plt) }
${OTHER_PLT_RELOC_SECTIONS}
${RELOCATING-$INIT_LIT}
${RELOCATING-$INIT}
.text ${RELOCATING-0} :
{
*(.got.plt* .plt*)
${RELOCATING+${INIT_START}}
${RELOCATING+KEEP (*(.init.literal))}
${RELOCATING+KEEP (*(.init))}
${RELOCATING+${INIT_END}}
${RELOCATING+${TEXT_START_SYMBOLS}}
*(.literal .text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*})
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
${RELOCATING+${OTHER_TEXT_SECTIONS}}
${RELOCATING+${FINI_START}}
${RELOCATING+KEEP (*(.fini.literal))}
${RELOCATING+KEEP (*(.fini))}
${RELOCATING+${FINI_END}}
} =${NOP-0}
${RELOCATING-$FINI_LIT}
${RELOCATING-$FINI}
${RELOCATING+PROVIDE (__etext = .);}
${RELOCATING+PROVIDE (_etext = .);}
${RELOCATING+PROVIDE (etext = .);}
${WRITABLE_RODATA-${RODATA}}
.rodata1 ${RELOCATING-0} : { *(.rodata1) }
${CREATE_SHLIB-${SDATA2}}
${CREATE_SHLIB-${SBSS2}}
${OTHER_READONLY_SECTIONS}
.eh_frame_hdr : { *(.eh_frame_hdr) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
${RELOCATING+. = ALIGN(${ALIGNMENT});}
${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_start = .);}}
.preinit_array ${RELOCATING-0} : { *(.preinit_array) }
${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_end = .);}}
${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_start = .);}}
.init_array ${RELOCATING-0} : { *(.init_array) }
${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_end = .);}}
${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_start = .);}}
.fini_array ${RELOCATING-0} : { *(.fini_array) }
${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_end = .);}}
.data ${RELOCATING-0} :
{
${RELOCATING+${DATA_START_SYMBOLS}}
*(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
${CONSTRUCTING+SORT(CONSTRUCTORS)}
}
.data1 ${RELOCATING-0} : { *(.data1) }
.tdata ${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) }
.tbss ${RELOCATING-0} : { *(.tbss${RELOCATING+ .tbss.* .gnu.linkonce.tb.*})${RELOCATING+ *(.tcommon)} }
.eh_frame ${RELOCATING-0} : { KEEP (*(.eh_frame)) }
.gcc_except_table ${RELOCATING-0} : { *(.gcc_except_table) }
${WRITABLE_RODATA+${RODATA}}
${OTHER_READWRITE_SECTIONS}
${TEXT_DYNAMIC-${DYNAMIC}}
${RELOCATING+${CTOR}}
${RELOCATING+${DTOR}}
.jcr ${RELOCATING-0} : { KEEP (*(.jcr)) }
${RELOCATING+${OTHER_GOT_SYMBOLS}}
.got ${RELOCATING-0} : { *(.got) }
${OTHER_GOT_SECTIONS}
${CREATE_SHLIB+${SDATA2}}
${CREATE_SHLIB+${SBSS2}}
${SDATA}
${OTHER_SDATA_SECTIONS}
${RELOCATING+_edata = .;}
${RELOCATING+PROVIDE (edata = .);}
${RELOCATING+__bss_start = .;}
${RELOCATING+${OTHER_BSS_SYMBOLS}}
${SBSS}
.bss ${RELOCATING-0} :
{
*(.dynbss)
*(.bss${RELOCATING+ .bss.* .gnu.linkonce.b.*})
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
${RELOCATING+. = ALIGN(${ALIGNMENT});}
}
${OTHER_BSS_SECTIONS}
${RELOCATING+. = ALIGN(${ALIGNMENT});}
${RELOCATING+_end = .;}
${RELOCATING+${OTHER_BSS_END_SYMBOLS}}
${RELOCATING+PROVIDE (end = .);}
${RELOCATING+${DATA_SEGMENT_END}}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
${STACK_ADDR+${STACK}}
${OTHER_SECTIONS}
${RELOCATING+${OTHER_END_SYMBOLS}}
}
EOF

View File

@ -1,3 +1,18 @@
2003-04-01 Bob Wilson <bob.wilson@acm.org>
* ld-elf/merge.d: xfail xtensa-*-*.
* ld-scripts/crossref.exp: Add -mtext-section-literals to CFLAGS
for Xtensa targets.
* ld-srec/srec.exp: Add -no-relax flag for Xtensa targets.
* ld-xtensa/coalesce1.s: New file.
* ld-xtensa/coalesce2.s: Likewise.
* ld-xtensa/coalesce.exp: Likewise.
* ld-xtensa/coalesce.t: Likewise.
* ld-xtensa/lcall1.s: Likewise.
* ld-xtensa/lcall2.s: Likewise.
* ld-xtensa/lcall.exp: Likewise.
* ld-xtensa/lcall.t: Likewise.
2003-03-25 Alexandre Oliva <aoliva@redhat.com>
* ld-mips-elf/mips-elf.exp: Added...

View File

@ -3,7 +3,7 @@
#objdump: -s
#xfail: "arc-*-*" "avr-*-*" "cris-*-*" "dlx-*-*" "fr30-*-*" "frv-*-*"
#xfail: "hppa*-*-*" "h8300-*-*" "i960-*-*" "ip2k-*-*" "m32r-*-*" "mcore-*-*"
#xfail: "mn10*-*-*" "openrisc-*-*" "pj-*-*" "sparc*-*-*"
#xfail: "mn10*-*-*" "openrisc-*-*" "pj-*-*" "sparc*-*-*" "xtensa-*-*"
.*: file format .*elf.*

View File

@ -26,6 +26,13 @@ if { [which $CC] == 0 } {
return
}
# Xtensa targets currently default to putting literal values in a separate
# section and that requires linker script support, so put literals in text.
global CFLAGS
if [istarget xtensa*-*-*] {
set CFLAGS "$CFLAGS -mtext-section-literals"
}
if { ![ld_compile $CC "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \
|| ![ld_compile $CC "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } {
unresolved $test1

View File

@ -288,6 +288,11 @@ proc run_srec_test { test objs } {
if [istarget v850*-*-elf] {
set objs "$objs -L ../gcc -lgcc"
}
# Xtensa ELF targets relax by default; S-Record linker does not
if [istarget xtensa*-*-*] {
set flags "$flags -no-relax"
}
if { ![ld_simple_link $ld tmpdir/sr1 "$flags $objs"] \
|| ![ld_simple_link $ld tmpdir/sr2.sr "$flags --oformat srec $objs"] } {

View File

@ -0,0 +1,93 @@
# Test literal coaslescing for Xtensa targets.
# By David Heine, Tensilica, Inc.
# Copyright 2002, 2003
# Free Software Foundation, Inc.
#
# This file 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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
set testname "COALESCE"
set OBJDUMPFLAGS "-dr"
#
# default_ld_objdump
# run objdump on a file
#
proc default_ld_objdump { objdump object outputfile } {
global OBJDUMPFLAGS
global objdump_output
global host_triplet
if {[which $objdump] == 0} then {
perror "$objdump does not exist"
return 0
}
if ![info exists OBJDUMPFLAGS] { set OBJDUMPFLAGS "" }
verbose -log "$objdump $OBJDUMPFLAGS $object >$outputfile"
catch "exec $objdump $OBJDUMPFLAGS $object >$outputfile" exec_output
set exec_output [prune_warnings $exec_output]
if [string match "" $exec_output] then {
return 1
} else {
verbose -log "$exec_output"
perror "$object: objdump failed"
return 0
}
}
if ![ld_assemble $as $srcdir/$subdir/coalesce1.s tmpdir/coalesce1.o] {
unresolved $testname
return
}
if ![ld_assemble $as $srcdir/$subdir/coalesce2.s tmpdir/coalesce2.o] {
unresolved $testname
return
}
set object "tmpdir/coalesce"
set outputfile "$object.txt"
if ![ld_simple_link $ld $object "-T $srcdir/$subdir/coalesce.t tmpdir/coalesce1.o tmpdir/coalesce2.o"] {
verbose -log "failure in ld"
fail $testname
return
}
if ![default_ld_objdump $objdump $object $outputfile ] {
verbose -log "failure in objdump"
fail $testname
return
}
set file [open $outputfile r]
set found 0
while { [gets $file line] != -1 } {
# verbose "$line" 2
if [regexp "^0000000c <main>:" $line] {
set found 1
}
}
close $file
if $found {
pass $testname
} else {
fail $testname
}

View File

@ -0,0 +1,6 @@
SECTIONS
{
.text 0x00000000 : {
*(.literal .text)
}
}

View File

@ -0,0 +1,15 @@
.global foo
.data
.global g_name
.align 4
g_name:
.word 0xffffffff
.text
.global main
.align 4
main:
entry a5,16
movi a5,20000
movi a6,g_name
call8 foo
ret

View File

@ -0,0 +1,9 @@
.text
.global foo
.global g_name
foo:
entry a5,16
movi a5,20000
movi a6,g_name
movi a7,50000
ret

View File

@ -0,0 +1,107 @@
# Test Xtensa longcall optimization.
# By David Heine, Tensilica, Inc.
# Copyright 2002, 2003
# Free Software Foundation, Inc.
#
# This file 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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
set testname "LCALL"
set OBJDUMPFLAGS "-dr"
#
# default_ld_objdump
# run objdump on a file
#
proc default_ld_objdump { objdump object outputfile } {
global OBJDUMPFLAGS
global objdump_output
global host_triplet
if {[which $objdump] == 0} then {
perror "$objdump does not exist"
return 0
}
if ![info exists OBJDUMPFLAGS] { set OBJDUMPFLAGS "" }
verbose -log "$objdump $OBJDUMPFLAGS $object >$outputfile"
catch "exec $objdump $OBJDUMPFLAGS $object >$outputfile" exec_output
set exec_output [prune_warnings $exec_output]
if [string match "" $exec_output] then {
return 1
} else {
verbose -log "$exec_output"
perror "$object: objdump failed"
return 0
}
}
if ![ld_assemble $as $srcdir/$subdir/lcall1.s tmpdir/lcall1.o] {
unresolved $testname
return
}
if ![ld_assemble $as $srcdir/$subdir/lcall2.s tmpdir/lcall2.o] {
unresolved $testname
return
}
set object "tmpdir/lcall"
set outputfile "$object.txt"
if ![ld_simple_link $ld $object "-T $srcdir/$subdir/lcall.t tmpdir/lcall1.o tmpdir/lcall2.o"] {
verbose -log "failure in ld"
fail $testname
return
}
if ![default_ld_objdump $objdump $object $outputfile ] {
verbose -log "failure in objdump"
fail $testname
return
}
set file [open $outputfile r]
while { [gets $file line] != -1 } {
# verbose "$line" 2
if [regexp "l32r" $line] {
verbose -log "Found an l32r in the linked object"
verbose -log "$line"
fail $testname
}
}
close $file
pass $testname
set testname "LCALL2"
set file [open $outputfile r]
set found 0
while { [gets $file line] != -1 } {
# verbose "$line" 2
if [regexp "^00000004 <label1>:" $line] {
set found 1
}
}
close $file
if $found {
pass $testname
} else {
fail $testname
}

View File

@ -0,0 +1,6 @@
SECTIONS
{
.text 0x00000000 : {
*(.literal .text)
}
}

View File

@ -0,0 +1,12 @@
.global foo
.text
.align 4
label1:
.begin literal
.word 0xffffffff
.end literal
entry a5,16
.begin longcalls
call4 foo
.end longcalls
nop

View File

@ -0,0 +1,5 @@
.global foo
foo:
entry a5,16
nop
ret

View File

@ -160,6 +160,7 @@ CFILES = \
xstormy16-dis.c \
xstormy16-ibld.c \
xstormy16-opc.c \
xtensa-dis.c \
z8k-dis.c \
z8kgen.c
@ -270,6 +271,7 @@ ALL_MACHINES = \
xstormy16-dis.lo \
xstormy16-ibld.lo \
xstormy16-opc.lo \
xtensa-dis.lo \
z8k-dis.lo
OFILES = @BFD_MACHINES@
@ -817,6 +819,9 @@ xstormy16-ibld.lo: xstormy16-ibld.c sysdep.h config.h \
xstormy16-opc.lo: xstormy16-opc.c sysdep.h config.h \
$(INCDIR)/ansidecl.h $(BFD_H) $(INCDIR)/symcat.h xstormy16-desc.h \
$(INCDIR)/opcode/cgen.h xstormy16-opc.h $(INCDIR)/libiberty.h
xtensa-dis.lo: xtensa-dis.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/ansidecl.h sysdep.h config.h $(INCDIR)/dis-asm.h \
$(BFD_H) $(INCDIR)/symcat.h
z8k-dis.lo: z8k-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h z8k-opc.h
z8kgen.lo: z8kgen.c sysdep.h config.h $(INCDIR)/ansidecl.h \

View File

@ -1,4 +1,4 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
@ -271,6 +271,7 @@ CFILES = \
xstormy16-dis.c \
xstormy16-ibld.c \
xstormy16-opc.c \
xtensa-dis.c \
z8k-dis.c \
z8kgen.c
@ -382,6 +383,7 @@ ALL_MACHINES = \
xstormy16-dis.lo \
xstormy16-ibld.lo \
xstormy16-opc.lo \
xtensa-dis.lo \
z8k-dis.lo
@ -465,7 +467,7 @@ acinclude.m4 aclocal.m4 config.in configure configure.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = libopcodes.a.c $(libopcodes_la_SOURCES)
OBJECTS = libopcodes.a.$(OBJEXT) $(libopcodes_la_OBJECTS)
@ -1313,6 +1315,9 @@ xstormy16-ibld.lo: xstormy16-ibld.c sysdep.h config.h \
xstormy16-opc.lo: xstormy16-opc.c sysdep.h config.h \
$(INCDIR)/ansidecl.h $(BFD_H) $(INCDIR)/symcat.h xstormy16-desc.h \
$(INCDIR)/opcode/cgen.h xstormy16-opc.h $(INCDIR)/libiberty.h
xtensa-dis.lo: xtensa-dis.c $(INCDIR)/xtensa-isa.h \
$(INCDIR)/ansidecl.h sysdep.h config.h $(INCDIR)/dis-asm.h \
$(BFD_H) $(INCDIR)/symcat.h
z8k-dis.lo: z8k-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h z8k-opc.h
z8kgen.lo: z8kgen.c sysdep.h config.h $(INCDIR)/ansidecl.h \

387
opcodes/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -241,6 +241,7 @@ if test x${all_targets} = xfalse ; then
bfd_w65_arch) ta="$ta w65-dis.lo" ;;
bfd_we32k_arch) ;;
bfd_xstormy16_arch) ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;;
bfd_xtensa_arch) ta="$ta xtensa-dis.lo" ;;
bfd_z8k_arch) ta="$ta z8k-dis.lo" ;;
bfd_frv_arch) ta="$ta frv-asm.lo frv-desc.lo frv-dis.lo frv-ibld.lo frv-opc.lo" using_cgen=yes ;;

View File

@ -68,6 +68,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define ARCH_vax
#define ARCH_w65
#define ARCH_xstormy16
#define ARCH_xtensa
#define ARCH_z8k
#define ARCH_frv
#define ARCH_iq2000
@ -343,6 +344,11 @@ disassembler (abfd)
disassemble = print_insn_xstormy16;
break;
#endif
#ifdef ARCH_xtensa
case bfd_arch_xtensa:
disassemble = print_insn_xtensa;
break;
#endif
#ifdef ARCH_z8k
case bfd_arch_z8k:
if (bfd_get_mach(abfd) == bfd_mach_z8001)

526
opcodes/xtensa-dis.c Normal file
View File

@ -0,0 +1,526 @@
/* xtensa-dis.c. Disassembly functions for Xtensa.
Copyright 2003 Free Software Foundation, Inc.
Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
This file is part of GDB, GAS, and the GNU binutils.
GDB, GAS, and the GNU binutils are free software; you can redistribute
them and/or modify them 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.
GDB, GAS, and the GNU binutils are distributed in the hope that they
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 file; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "xtensa-isa.h"
#include "ansidecl.h"
#include "sysdep.h"
#include "dis-asm.h"
#include <setjmp.h>
#ifndef MAX
#define MAX(a,b) (a > b ? a : b)
#endif
static char* state_names[256] =
{
"lbeg", /* 0 */
"lend", /* 1 */
"lcount", /* 2 */
"sar", /* 3 */
"br", /* 4 */
"reserved_5", /* 5 */
"reserved_6", /* 6 */
"reserved_7", /* 7 */
"av", /* 8 */
"avh", /* 9 */
"bv", /* 10 */
"sav", /* 11 */
"scompare1", /* 12 */
"reserved_13", /* 13 */
"reserved_14", /* 14 */
"reserved_15", /* 15 */
"acclo", /* 16 */
"acchi", /* 17 */
"reserved_18", /* 18 */
"reserved_19", /* 19 */
"reserved_20", /* 20 */
"reserved_21", /* 21 */
"reserved_22", /* 22 */
"reserved_23", /* 23 */
"reserved_24", /* 24 */
"reserved_25", /* 25 */
"reserved_26", /* 26 */
"reserved_27", /* 27 */
"reserved_28", /* 28 */
"reserved_29", /* 29 */
"reserved_30", /* 30 */
"reserved_31", /* 31 */
"mr0", /* 32 */
"mr1", /* 33 */
"mr2", /* 34 */
"mr3", /* 35 */
"reserved_36", /* 36 */
"reserved_37", /* 37 */
"reserved_38", /* 38 */
"reserved_39", /* 39 */
"reserved_40", /* 40 */
"reserved_41", /* 41 */
"reserved_42", /* 42 */
"reserved_43", /* 43 */
"reserved_44", /* 44 */
"reserved_45", /* 45 */
"reserved_46", /* 46 */
"reserved_47", /* 47 */
"reserved_48", /* 48 */
"reserved_49", /* 49 */
"reserved_50", /* 50 */
"reserved_51", /* 51 */
"reserved_52", /* 52 */
"reserved_53", /* 53 */
"reserved_54", /* 54 */
"reserved_55", /* 55 */
"reserved_56", /* 56 */
"reserved_57", /* 57 */
"reserved_58", /* 58 */
"reserved_59", /* 59 */
"reserved_60", /* 60 */
"reserved_61", /* 61 */
"reserved_62", /* 62 */
"reserved_63", /* 63 */
"reserved_64", /* 64 */
"reserved_65", /* 65 */
"reserved_66", /* 66 */
"reserved_67", /* 67 */
"reserved_68", /* 68 */
"reserved_69", /* 69 */
"reserved_70", /* 70 */
"reserved_71", /* 71 */
"wb", /* 72 */
"ws", /* 73 */
"reserved_74", /* 74 */
"reserved_75", /* 75 */
"reserved_76", /* 76 */
"reserved_77", /* 77 */
"reserved_78", /* 78 */
"reserved_79", /* 79 */
"reserved_80", /* 80 */
"reserved_81", /* 81 */
"reserved_82", /* 82 */
"ptevaddr", /* 83 */
"reserved_84", /* 84 */
"reserved_85", /* 85 */
"reserved_86", /* 86 */
"reserved_87", /* 87 */
"reserved_88", /* 88 */
"reserved_89", /* 89 */
"rasid", /* 90 */
"itlbcfg", /* 91 */
"dtlbcfg", /* 92 */
"reserved_93", /* 93 */
"reserved_94", /* 94 */
"reserved_95", /* 95 */
"ibreakenable", /* 96 */
"reserved_97", /* 97 */
"cacheattr", /* 98 */
"reserved_99", /* 99 */
"reserved_100", /* 100 */
"reserved_101", /* 101 */
"reserved_102", /* 102 */
"reserved_103", /* 103 */
"ddr", /* 104 */
"reserved_105", /* 105 */
"reserved_106", /* 106 */
"reserved_107", /* 107 */
"reserved_108", /* 108 */
"reserved_109", /* 109 */
"reserved_110", /* 110 */
"reserved_111", /* 111 */
"reserved_112", /* 112 */
"reserved_113", /* 113 */
"reserved_114", /* 114 */
"reserved_115", /* 115 */
"reserved_116", /* 116 */
"reserved_117", /* 117 */
"reserved_118", /* 118 */
"reserved_119", /* 119 */
"reserved_120", /* 120 */
"reserved_121", /* 121 */
"reserved_122", /* 122 */
"reserved_123", /* 123 */
"reserved_124", /* 124 */
"reserved_125", /* 125 */
"reserved_126", /* 126 */
"reserved_127", /* 127 */
"ibreaka0", /* 128 */
"ibreaka1", /* 129 */
"ibreaka2", /* 130 */
"ibreaka3", /* 131 */
"ibreaka4", /* 132 */
"ibreaka5", /* 133 */
"ibreaka6", /* 134 */
"ibreaka7", /* 135 */
"ibreaka8", /* 136 */
"ibreaka9", /* 137 */
"ibreaka10", /* 138 */
"ibreaka11", /* 139 */
"ibreaka12", /* 140 */
"ibreaka13", /* 141 */
"ibreaka14", /* 142 */
"ibreaka15", /* 143 */
"dbreaka0", /* 144 */
"dbreaka1", /* 145 */
"dbreaka2", /* 146 */
"dbreaka3", /* 147 */
"dbreaka4", /* 148 */
"dbreaka5", /* 149 */
"dbreaka6", /* 150 */
"dbreaka7", /* 151 */
"dbreaka8", /* 152 */
"dbreaka9", /* 153 */
"dbreaka10", /* 154 */
"dbreaka11", /* 155 */
"dbreaka12", /* 156 */
"dbreaka13", /* 157 */
"dbreaka14", /* 158 */
"dbreaka15", /* 159 */
"dbreakc0", /* 160 */
"dbreakc1", /* 161 */
"dbreakc2", /* 162 */
"dbreakc3", /* 163 */
"dbreakc4", /* 164 */
"dbreakc5", /* 165 */
"dbreakc6", /* 166 */
"dbreakc7", /* 167 */
"dbreakc8", /* 168 */
"dbreakc9", /* 169 */
"dbreakc10", /* 170 */
"dbreakc11", /* 171 */
"dbreakc12", /* 172 */
"dbreakc13", /* 173 */
"dbreakc14", /* 174 */
"dbreakc15", /* 175 */
"reserved_176", /* 176 */
"epc1", /* 177 */
"epc2", /* 178 */
"epc3", /* 179 */
"epc4", /* 180 */
"epc5", /* 181 */
"epc6", /* 182 */
"epc7", /* 183 */
"epc8", /* 184 */
"epc9", /* 185 */
"epc10", /* 186 */
"epc11", /* 187 */
"epc12", /* 188 */
"epc13", /* 189 */
"epc14", /* 190 */
"epc15", /* 191 */
"depc", /* 192 */
"reserved_193", /* 193 */
"eps2", /* 194 */
"eps3", /* 195 */
"eps4", /* 196 */
"eps5", /* 197 */
"eps6", /* 198 */
"eps7", /* 199 */
"eps8", /* 200 */
"eps9", /* 201 */
"eps10", /* 202 */
"eps11", /* 203 */
"eps12", /* 204 */
"eps13", /* 205 */
"eps14", /* 206 */
"eps15", /* 207 */
"reserved_208", /* 208 */
"excsave1", /* 209 */
"excsave2", /* 210 */
"excsave3", /* 211 */
"excsave4", /* 212 */
"excsave5", /* 213 */
"excsave6", /* 214 */
"excsave7", /* 215 */
"excsave8", /* 216 */
"excsave9", /* 217 */
"excsave10", /* 218 */
"excsave11", /* 219 */
"excsave12", /* 220 */
"excsave13", /* 221 */
"excsave14", /* 222 */
"excsave15", /* 223 */
"cpenable", /* 224 */
"reserved_225", /* 225 */
"interrupt", /* 226 */
"interrupt2", /* 227 */
"intenable", /* 228 */
"reserved_229", /* 229 */
"ps", /* 230 */
"reserved_231", /* 231 */
"exccause", /* 232 */
"debugcause", /* 233 */
"ccount", /* 234 */
"prid", /* 235 */
"icount", /* 236 */
"icountlvl", /* 237 */
"excvaddr", /* 238 */
"reserved_239", /* 239 */
"ccompare0", /* 240 */
"ccompare1", /* 241 */
"ccompare2", /* 242 */
"ccompare3", /* 243 */
"misc0", /* 244 */
"misc1", /* 245 */
"misc2", /* 246 */
"misc3", /* 247 */
"reserved_248", /* 248 */
"reserved_249", /* 249 */
"reserved_250", /* 250 */
"reserved_251", /* 251 */
"reserved_252", /* 252 */
"reserved_253", /* 253 */
"reserved_254", /* 254 */
"reserved_255", /* 255 */
};
int show_raw_fields;
static int fetch_data
PARAMS ((struct disassemble_info *info, bfd_vma memaddr, int numBytes));
static void print_xtensa_operand
PARAMS ((bfd_vma, struct disassemble_info *, xtensa_operand,
unsigned operand_val, int print_sr_name));
struct dis_private {
bfd_byte *byte_buf;
jmp_buf bailout;
};
static int
fetch_data (info, memaddr, numBytes)
struct disassemble_info *info;
bfd_vma memaddr;
int numBytes;
{
int length, status = 0;
struct dis_private *priv = (struct dis_private *) info->private_data;
int insn_size = (numBytes != 0 ? numBytes :
xtensa_insn_maxlength (xtensa_default_isa));
/* Read the maximum instruction size, padding with zeros if we go past
the end of the text section. This code will automatically adjust
length when we hit the end of the buffer. */
memset (priv->byte_buf, 0, insn_size);
for (length = insn_size; length > 0; length--)
{
status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
info);
if (status == 0)
return length;
}
(*info->memory_error_func) (status, memaddr, info);
longjmp (priv->bailout, 1);
/*NOTREACHED*/
}
static void
print_xtensa_operand (memaddr, info, opnd, operand_val, print_sr_name)
bfd_vma memaddr;
struct disassemble_info *info;
xtensa_operand opnd;
unsigned operand_val;
int print_sr_name;
{
char *kind = xtensa_operand_kind (opnd);
int signed_operand_val;
if (show_raw_fields)
{
if (operand_val < 0xa)
(*info->fprintf_func) (info->stream, "%u", operand_val);
else
(*info->fprintf_func) (info->stream, "0x%x", operand_val);
return;
}
operand_val = xtensa_operand_decode (opnd, operand_val);
signed_operand_val = (int) operand_val;
if (xtensa_operand_isPCRelative (opnd))
{
operand_val = xtensa_operand_undo_reloc (opnd, operand_val, memaddr);
info->target = operand_val;
(*info->print_address_func) (info->target, info);
}
else if (!strcmp (kind, "i"))
{
if (print_sr_name
&& signed_operand_val >= 0
&& signed_operand_val <= 255)
(*info->fprintf_func) (info->stream, "%s",
state_names[signed_operand_val]);
else if ((signed_operand_val > -256) && (signed_operand_val < 256))
(*info->fprintf_func) (info->stream, "%d", signed_operand_val);
else
(*info->fprintf_func) (info->stream, "0x%x",signed_operand_val);
}
else
(*info->fprintf_func) (info->stream, "%s%u", kind, operand_val);
}
/* Print the Xtensa instruction at address MEMADDR on info->stream.
Returns length of the instruction in bytes. */
int
print_insn_xtensa (memaddr, info)
bfd_vma memaddr;
struct disassemble_info *info;
{
unsigned operand_val;
int bytes_fetched, size, maxsize, i, noperands;
xtensa_isa isa;
xtensa_opcode opc;
char *op_name;
int print_sr_name;
struct dis_private priv;
static bfd_byte *byte_buf = NULL;
static xtensa_insnbuf insn_buffer = NULL;
if (!xtensa_default_isa)
(void) xtensa_isa_init ();
info->target = 0;
maxsize = xtensa_insn_maxlength (xtensa_default_isa);
/* Set bytes_per_line to control the amount of whitespace between the hex
values and the opcode. For Xtensa, we always print one "chunk" and we
vary bytes_per_chunk to determine how many bytes to print. (objdump
would apparently prefer that we set bytes_per_chunk to 1 and vary
bytes_per_line but that makes it hard to fit 64-bit instructions on
an 80-column screen.) The value of bytes_per_line here is not exactly
right, because objdump adds an extra space for each chunk so that the
amount of whitespace depends on the chunk size. Oh well, it's good
enough.... Note that we set the minimum size to 4 to accomodate
literal pools. */
info->bytes_per_line = MAX (maxsize, 4);
/* Allocate buffers the first time through. */
if (!insn_buffer)
insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
if (!byte_buf)
byte_buf = (bfd_byte *) malloc (MAX (maxsize, 4));
priv.byte_buf = byte_buf;
info->private_data = (PTR) &priv;
if (setjmp (priv.bailout) != 0)
/* Error return. */
return -1;
/* Don't set "isa" before the setjmp to keep the compiler from griping. */
isa = xtensa_default_isa;
/* Fetch the maximum size instruction. */
bytes_fetched = fetch_data (info, memaddr, 0);
/* Copy the bytes into the decode buffer. */
memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
sizeof (xtensa_insnbuf_word)));
xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf);
opc = xtensa_decode_insn (isa, insn_buffer);
if (opc == XTENSA_UNDEFINED
|| ((size = xtensa_insn_length (isa, opc)) > bytes_fetched))
{
(*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
return 1;
}
op_name = (char *) xtensa_opcode_name (isa, opc);
(*info->fprintf_func) (info->stream, "%s", op_name);
print_sr_name = (!strcasecmp (op_name, "wsr")
|| !strcasecmp (op_name, "xsr")
|| !strcasecmp (op_name, "rsr"));
/* Print the operands (if any). */
noperands = xtensa_num_operands (isa, opc);
if (noperands > 0)
{
int first = 1;
(*info->fprintf_func) (info->stream, "\t");
for (i = 0; i < noperands; i++)
{
xtensa_operand opnd = xtensa_get_operand (isa, opc, i);
if (first)
first = 0;
else
(*info->fprintf_func) (info->stream, ", ");
operand_val = xtensa_operand_get_field (opnd, insn_buffer);
print_xtensa_operand (memaddr, info, opnd, operand_val,
print_sr_name);
}
}
info->bytes_per_chunk = size;
info->display_endian = info->endian;
return size;
}