Add Xtensa port
This commit is contained in:
parent
ce0c72625a
commit
e0001a05d2
@ -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.
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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
30
bfd/configure
vendored
@ -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
|
||||
|
@ -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
38
bfd/cpu-xtensa.c
Normal 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
5846
bfd/elf32-xtensa.c
Normal file
File diff suppressed because it is too large
Load Diff
10
bfd/libbfd.h
10
bfd/libbfd.h
@ -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
|
||||
|
43
bfd/reloc.c
43
bfd/reloc.c
@ -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
|
||||
|
@ -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
593
bfd/xtensa-isa.c
Normal 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
6090
bfd/xtensa-modules.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
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
200
gas/config/tc-xtensa.h
Normal 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
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
142
gas/config/xtensa-relax.h
Normal 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
370
gas/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -55,6 +55,7 @@ CPU_DOCS = \
|
||||
c-tic54x.texi \
|
||||
c-vax.texi \
|
||||
c-v850.texi \
|
||||
c-xtensa.texi \
|
||||
c-z8k.texi
|
||||
|
||||
gasver.texi: Makefile
|
||||
|
@ -167,6 +167,7 @@ CPU_DOCS = \
|
||||
c-tic54x.texi \
|
||||
c-vax.texi \
|
||||
c-v850.texi \
|
||||
c-xtensa.texi \
|
||||
c-z8k.texi
|
||||
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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
740
gas/doc/c-xtensa.texi
Normal 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:
|
@ -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"}.
|
||||
|
@ -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>
|
||||
|
||||
|
98
gas/testsuite/gas/xtensa/all.exp
Normal file
98
gas/testsuite/gas/xtensa/all.exp
Normal 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
|
||||
}
|
4
gas/testsuite/gas/xtensa/entry_align.s
Normal file
4
gas/testsuite/gas/xtensa/entry_align.s
Normal file
@ -0,0 +1,4 @@
|
||||
_nop.n
|
||||
l4:
|
||||
entry a5,16
|
||||
_mov.n a4,a5
|
4
gas/testsuite/gas/xtensa/entry_misalign.s
Normal file
4
gas/testsuite/gas/xtensa/entry_misalign.s
Normal file
@ -0,0 +1,4 @@
|
||||
_nop.n
|
||||
l4:
|
||||
_entry a5,16
|
||||
_mov.n a4,a5
|
6
gas/testsuite/gas/xtensa/entry_misalign2.s
Normal file
6
gas/testsuite/gas/xtensa/entry_misalign2.s
Normal file
@ -0,0 +1,6 @@
|
||||
.begin no-generics
|
||||
nop.n
|
||||
l4:
|
||||
entry a5,16
|
||||
mov.n a4,a5
|
||||
.end no-generics
|
8
gas/testsuite/gas/xtensa/j_too_far.s
Normal file
8
gas/testsuite/gas/xtensa/j_too_far.s
Normal file
@ -0,0 +1,8 @@
|
||||
.text
|
||||
.align 4
|
||||
entry a5,16
|
||||
j too_far
|
||||
.fill 150000
|
||||
too_far:
|
||||
nop
|
||||
nop
|
5
gas/testsuite/gas/xtensa/loop_align.s
Normal file
5
gas/testsuite/gas/xtensa/loop_align.s
Normal file
@ -0,0 +1,5 @@
|
||||
l4:
|
||||
loop a5,l5
|
||||
_mov.n a4,a5
|
||||
l5:
|
||||
_nop.n
|
5
gas/testsuite/gas/xtensa/loop_misalign.s
Normal file
5
gas/testsuite/gas/xtensa/loop_misalign.s
Normal file
@ -0,0 +1,5 @@
|
||||
l4:
|
||||
_loop a5,l5
|
||||
_mov.n a4,a5
|
||||
l5:
|
||||
_nop.n
|
@ -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.
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 *));
|
||||
|
@ -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.
|
||||
|
@ -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
87
include/elf/xtensa.h
Normal 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
70
include/xtensa-config.h
Normal 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 */
|
114
include/xtensa-isa-internal.h
Normal file
114
include/xtensa-isa-internal.h
Normal 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
230
include/xtensa-isa.h
Normal 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 */
|
13
ld/ChangeLog
13
ld/ChangeLog
@ -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
|
||||
|
@ -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)"
|
||||
|
@ -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)"
|
||||
|
@ -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" ;;
|
||||
|
32
ld/emulparams/elf32xtensa.sh
Normal file
32
ld/emulparams/elf32xtensa.sh
Normal 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*) }
|
||||
'
|
8
ld/emulparams/xtensa-config.sh
Normal file
8
ld/emulparams/xtensa-config.sh
Normal 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
1586
ld/emultempl/xtensaelf.em
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
||||
@set MSP430
|
||||
@set TICOFF
|
||||
@set WIN32
|
||||
@set XTENSA
|
||||
|
||||
@c 3. Properties of this configuration
|
||||
@clear SingleFormat
|
||||
|
@ -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
397
ld/scripttempl/elfxtensa.sc
Normal 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
|
@ -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...
|
||||
|
@ -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.*
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"] } {
|
||||
|
93
ld/testsuite/ld-xtensa/coalesce.exp
Normal file
93
ld/testsuite/ld-xtensa/coalesce.exp
Normal 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
|
||||
}
|
||||
|
6
ld/testsuite/ld-xtensa/coalesce.t
Normal file
6
ld/testsuite/ld-xtensa/coalesce.t
Normal file
@ -0,0 +1,6 @@
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00000000 : {
|
||||
*(.literal .text)
|
||||
}
|
||||
}
|
15
ld/testsuite/ld-xtensa/coalesce1.s
Normal file
15
ld/testsuite/ld-xtensa/coalesce1.s
Normal 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
|
9
ld/testsuite/ld-xtensa/coalesce2.s
Normal file
9
ld/testsuite/ld-xtensa/coalesce2.s
Normal 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
|
107
ld/testsuite/ld-xtensa/lcall.exp
Normal file
107
ld/testsuite/ld-xtensa/lcall.exp
Normal 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
|
||||
}
|
||||
|
6
ld/testsuite/ld-xtensa/lcall.t
Normal file
6
ld/testsuite/ld-xtensa/lcall.t
Normal file
@ -0,0 +1,6 @@
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00000000 : {
|
||||
*(.literal .text)
|
||||
}
|
||||
}
|
12
ld/testsuite/ld-xtensa/lcall1.s
Normal file
12
ld/testsuite/ld-xtensa/lcall1.s
Normal 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
|
5
ld/testsuite/ld-xtensa/lcall2.s
Normal file
5
ld/testsuite/ld-xtensa/lcall2.s
Normal file
@ -0,0 +1,5 @@
|
||||
.global foo
|
||||
foo:
|
||||
entry a5,16
|
||||
nop
|
||||
ret
|
@ -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 \
|
||||
|
@ -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
387
opcodes/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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 ;;
|
||||
|
||||
|
@ -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
526
opcodes/xtensa-dis.c
Normal 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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user