summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/gas/config
diff options
context:
space:
mode:
authorAndrew Hsieh <andrewhsieh@google.com>2014-12-09 17:57:18 +0800
committerAndrew Hsieh <andrewhsieh@google.com>2014-12-09 19:50:14 +0800
commit5e8c1cf25beccac1d22d10dc866912394f42771b (patch)
treeee16b70f804484dc8e434e647e699ab50da2620f /binutils-2.25/gas/config
parent8eebd7953384e6662ca926b003f2cdda8ccd3ee5 (diff)
downloadtoolchain_binutils-5e8c1cf25beccac1d22d10dc866912394f42771b.tar.gz
toolchain_binutils-5e8c1cf25beccac1d22d10dc866912394f42771b.tar.bz2
toolchain_binutils-5e8c1cf25beccac1d22d10dc866912394f42771b.zip
[2.25] sync to a30720e3e633f275250e26f85ccae5dbdddfb6c6
local patches will be re-applied later commit a30720e3e633f275250e26f85ccae5dbdddfb6c6 Author: Alan Modra <amodra@gmail.com> Date: Wed Nov 19 10:30:16 2014 +1030 daily update Change-Id: Ieb2a3f4dd2ecb289ac5305ff08d428b2847494ab
Diffstat (limited to 'binutils-2.25/gas/config')
-rw-r--r--binutils-2.25/gas/config/aout_gnu.h3
-rw-r--r--binutils-2.25/gas/config/atof-ieee.c3
-rw-r--r--binutils-2.25/gas/config/atof-vax.c3
-rw-r--r--[-rwxr-xr-x]binutils-2.25/gas/config/bfin-aux.h3
-rw-r--r--binutils-2.25/gas/config/bfin-defs.h3
-rw-r--r--binutils-2.25/gas/config/bfin-lex-wrapper.c3
-rw-r--r--binutils-2.25/gas/config/bfin-lex.l3
-rw-r--r--binutils-2.25/gas/config/bfin-parse.y4
-rw-r--r--binutils-2.25/gas/config/e-crisaout.c2
-rw-r--r--binutils-2.25/gas/config/e-criself.c2
-rw-r--r--binutils-2.25/gas/config/e-i386aout.c2
-rw-r--r--binutils-2.25/gas/config/e-i386coff.c2
-rw-r--r--binutils-2.25/gas/config/e-i386elf.c2
-rw-r--r--binutils-2.25/gas/config/e-mipself.c2
-rw-r--r--binutils-2.25/gas/config/itbl-mips.h2
-rw-r--r--binutils-2.25/gas/config/m68k-parse.h3
-rw-r--r--binutils-2.25/gas/config/m68k-parse.y3
-rw-r--r--binutils-2.25/gas/config/obj-aout.c5
-rw-r--r--binutils-2.25/gas/config/obj-aout.h3
-rw-r--r--binutils-2.25/gas/config/obj-coff-seh.c10
-rw-r--r--binutils-2.25/gas/config/obj-coff-seh.h7
-rw-r--r--binutils-2.25/gas/config/obj-coff.c6
-rw-r--r--binutils-2.25/gas/config/obj-coff.h9
-rw-r--r--binutils-2.25/gas/config/obj-ecoff.c3
-rw-r--r--binutils-2.25/gas/config/obj-ecoff.h3
-rw-r--r--binutils-2.25/gas/config/obj-elf.c75
-rw-r--r--binutils-2.25/gas/config/obj-elf.h6
-rw-r--r--binutils-2.25/gas/config/obj-evax.c3
-rw-r--r--binutils-2.25/gas/config/obj-evax.h3
-rw-r--r--binutils-2.25/gas/config/obj-fdpicelf.c3
-rw-r--r--binutils-2.25/gas/config/obj-fdpicelf.h3
-rw-r--r--binutils-2.25/gas/config/obj-macho.c20
-rw-r--r--binutils-2.25/gas/config/obj-macho.h2
-rw-r--r--binutils-2.25/gas/config/obj-multi.c2
-rw-r--r--binutils-2.25/gas/config/obj-multi.h3
-rw-r--r--binutils-2.25/gas/config/obj-som.c4
-rw-r--r--binutils-2.25/gas/config/obj-som.h3
-rw-r--r--binutils-2.25/gas/config/rl78-defs.h6
-rw-r--r--binutils-2.25/gas/config/rl78-parse.y20
-rw-r--r--binutils-2.25/gas/config/rx-defs.h2
-rw-r--r--binutils-2.25/gas/config/rx-parse.y18
-rw-r--r--binutils-2.25/gas/config/tc-aarch64.c261
-rw-r--r--binutils-2.25/gas/config/tc-aarch64.h15
-rw-r--r--binutils-2.25/gas/config/tc-alpha.c4
-rw-r--r--binutils-2.25/gas/config/tc-alpha.h7
-rw-r--r--binutils-2.25/gas/config/tc-arc.c9
-rw-r--r--binutils-2.25/gas/config/tc-arc.h13
-rw-r--r--binutils-2.25/gas/config/tc-arm.c1055
-rw-r--r--binutils-2.25/gas/config/tc-arm.h19
-rw-r--r--binutils-2.25/gas/config/tc-avr.c401
-rw-r--r--binutils-2.25/gas/config/tc-avr.h52
-rw-r--r--binutils-2.25/gas/config/tc-bfin.c5
-rw-r--r--binutils-2.25/gas/config/tc-bfin.h3
-rw-r--r--binutils-2.25/gas/config/tc-cr16.c8
-rw-r--r--binutils-2.25/gas/config/tc-cr16.h9
-rw-r--r--binutils-2.25/gas/config/tc-cris.c76
-rw-r--r--binutils-2.25/gas/config/tc-cris.h3
-rw-r--r--binutils-2.25/gas/config/tc-crx.c3
-rw-r--r--binutils-2.25/gas/config/tc-crx.h5
-rw-r--r--binutils-2.25/gas/config/tc-d10v.c4
-rw-r--r--binutils-2.25/gas/config/tc-d10v.h3
-rw-r--r--binutils-2.25/gas/config/tc-d30v.c3
-rw-r--r--binutils-2.25/gas/config/tc-d30v.h3
-rw-r--r--binutils-2.25/gas/config/tc-dlx.c20
-rw-r--r--binutils-2.25/gas/config/tc-dlx.h2
-rw-r--r--[-rwxr-xr-x]binutils-2.25/gas/config/tc-epiphany.c2
-rw-r--r--[-rwxr-xr-x]binutils-2.25/gas/config/tc-epiphany.h2
-rw-r--r--binutils-2.25/gas/config/tc-fr30.c3
-rw-r--r--binutils-2.25/gas/config/tc-fr30.h3
-rw-r--r--binutils-2.25/gas/config/tc-frv.c3
-rw-r--r--binutils-2.25/gas/config/tc-frv.h3
-rw-r--r--binutils-2.25/gas/config/tc-generic.c2
-rw-r--r--binutils-2.25/gas/config/tc-generic.h3
-rw-r--r--binutils-2.25/gas/config/tc-h8300.c2
-rw-r--r--binutils-2.25/gas/config/tc-h8300.h2
-rw-r--r--binutils-2.25/gas/config/tc-hppa.c18
-rw-r--r--binutils-2.25/gas/config/tc-hppa.h10
-rw-r--r--binutils-2.25/gas/config/tc-i370.c3
-rw-r--r--binutils-2.25/gas/config/tc-i370.h3
-rw-r--r--binutils-2.25/gas/config/tc-i386-intel.c13
-rw-r--r--binutils-2.25/gas/config/tc-i386.c281
-rw-r--r--binutils-2.25/gas/config/tc-i386.h11
-rw-r--r--binutils-2.25/gas/config/tc-i860.c3
-rw-r--r--binutils-2.25/gas/config/tc-i860.h3
-rw-r--r--binutils-2.25/gas/config/tc-i960.c5
-rw-r--r--binutils-2.25/gas/config/tc-i960.h4
-rw-r--r--binutils-2.25/gas/config/tc-ia64.c13
-rw-r--r--binutils-2.25/gas/config/tc-ia64.h8
-rw-r--r--binutils-2.25/gas/config/tc-ip2k.c3
-rw-r--r--binutils-2.25/gas/config/tc-ip2k.h2
-rw-r--r--binutils-2.25/gas/config/tc-iq2000.c3
-rw-r--r--binutils-2.25/gas/config/tc-iq2000.h2
-rw-r--r--binutils-2.25/gas/config/tc-lm32.c2
-rw-r--r--binutils-2.25/gas/config/tc-lm32.h2
-rw-r--r--binutils-2.25/gas/config/tc-m32c.c7
-rw-r--r--binutils-2.25/gas/config/tc-m32c.h10
-rw-r--r--binutils-2.25/gas/config/tc-m32r.c3
-rw-r--r--binutils-2.25/gas/config/tc-m32r.h3
-rw-r--r--binutils-2.25/gas/config/tc-m68851.h3
-rw-r--r--binutils-2.25/gas/config/tc-m68hc11.c4
-rw-r--r--binutils-2.25/gas/config/tc-m68hc11.h3
-rw-r--r--binutils-2.25/gas/config/tc-m68k.c11
-rw-r--r--binutils-2.25/gas/config/tc-m68k.h4
-rw-r--r--binutils-2.25/gas/config/tc-mcore.c3
-rw-r--r--binutils-2.25/gas/config/tc-mcore.h3
-rw-r--r--binutils-2.25/gas/config/tc-mep.c3
-rw-r--r--binutils-2.25/gas/config/tc-mep.h2
-rw-r--r--binutils-2.25/gas/config/tc-metag.c2
-rw-r--r--binutils-2.25/gas/config/tc-metag.h2
-rw-r--r--binutils-2.25/gas/config/tc-microblaze.c11
-rw-r--r--binutils-2.25/gas/config/tc-microblaze.h12
-rw-r--r--binutils-2.25/gas/config/tc-mips.c1912
-rw-r--r--binutils-2.25/gas/config/tc-mips.h11
-rw-r--r--binutils-2.25/gas/config/tc-mmix.c16
-rw-r--r--binutils-2.25/gas/config/tc-mmix.h3
-rw-r--r--binutils-2.25/gas/config/tc-mn10200.c2
-rw-r--r--binutils-2.25/gas/config/tc-mn10200.h2
-rw-r--r--binutils-2.25/gas/config/tc-mn10300.c6
-rw-r--r--binutils-2.25/gas/config/tc-mn10300.h10
-rw-r--r--binutils-2.25/gas/config/tc-moxie.c8
-rw-r--r--binutils-2.25/gas/config/tc-moxie.h10
-rw-r--r--binutils-2.25/gas/config/tc-msp430.c974
-rw-r--r--binutils-2.25/gas/config/tc-msp430.h6
-rw-r--r--binutils-2.25/gas/config/tc-mt.c2
-rw-r--r--binutils-2.25/gas/config/tc-mt.h2
-rw-r--r--binutils-2.25/gas/config/tc-nds32.c6600
-rw-r--r--binutils-2.25/gas/config/tc-nds32.h281
-rw-r--r--binutils-2.25/gas/config/tc-nios2.c67
-rw-r--r--binutils-2.25/gas/config/tc-nios2.h8
-rw-r--r--binutils-2.25/gas/config/tc-ns32k.c7
-rw-r--r--binutils-2.25/gas/config/tc-ns32k.h6
-rw-r--r--binutils-2.25/gas/config/tc-openrisc.h61
-rw-r--r--binutils-2.25/gas/config/tc-or1k.c (renamed from binutils-2.25/gas/config/tc-openrisc.c)269
-rw-r--r--binutils-2.25/gas/config/tc-or1k.h79
-rw-r--r--binutils-2.25/gas/config/tc-or32.c967
-rw-r--r--binutils-2.25/gas/config/tc-or32.h56
-rw-r--r--binutils-2.25/gas/config/tc-pdp11.c3
-rw-r--r--binutils-2.25/gas/config/tc-pdp11.h2
-rw-r--r--binutils-2.25/gas/config/tc-pj.c6
-rw-r--r--binutils-2.25/gas/config/tc-pj.h11
-rw-r--r--binutils-2.25/gas/config/tc-ppc.c703
-rw-r--r--binutils-2.25/gas/config/tc-ppc.h14
-rw-r--r--binutils-2.25/gas/config/tc-rl78.c625
-rw-r--r--binutils-2.25/gas/config/tc-rl78.h7
-rw-r--r--binutils-2.25/gas/config/tc-rx.c30
-rw-r--r--binutils-2.25/gas/config/tc-rx.h10
-rw-r--r--binutils-2.25/gas/config/tc-s390.c3
-rw-r--r--binutils-2.25/gas/config/tc-s390.h3
-rw-r--r--binutils-2.25/gas/config/tc-score.c16
-rw-r--r--binutils-2.25/gas/config/tc-score.h2
-rw-r--r--binutils-2.25/gas/config/tc-score7.c20
-rw-r--r--binutils-2.25/gas/config/tc-sh.c11
-rw-r--r--binutils-2.25/gas/config/tc-sh.h10
-rw-r--r--binutils-2.25/gas/config/tc-sh64.c3
-rw-r--r--binutils-2.25/gas/config/tc-sh64.h3
-rw-r--r--binutils-2.25/gas/config/tc-sparc.c203
-rw-r--r--binutils-2.25/gas/config/tc-sparc.h11
-rw-r--r--binutils-2.25/gas/config/tc-spu.c2
-rw-r--r--binutils-2.25/gas/config/tc-spu.h2
-rw-r--r--binutils-2.25/gas/config/tc-tic30.c9
-rw-r--r--binutils-2.25/gas/config/tc-tic30.h2
-rw-r--r--binutils-2.25/gas/config/tc-tic4x.c8
-rw-r--r--binutils-2.25/gas/config/tc-tic4x.h3
-rw-r--r--binutils-2.25/gas/config/tc-tic54x.c14
-rw-r--r--binutils-2.25/gas/config/tc-tic54x.h8
-rw-r--r--binutils-2.25/gas/config/tc-tic6x.c11
-rw-r--r--binutils-2.25/gas/config/tc-tic6x.h11
-rw-r--r--binutils-2.25/gas/config/tc-tilegx.c2
-rw-r--r--binutils-2.25/gas/config/tc-tilegx.h4
-rw-r--r--binutils-2.25/gas/config/tc-tilepro.c2
-rw-r--r--binutils-2.25/gas/config/tc-tilepro.h4
-rw-r--r--binutils-2.25/gas/config/tc-v850.c43
-rw-r--r--binutils-2.25/gas/config/tc-v850.h8
-rw-r--r--binutils-2.25/gas/config/tc-vax.c65
-rw-r--r--binutils-2.25/gas/config/tc-vax.h8
-rw-r--r--binutils-2.25/gas/config/tc-xc16x.c2
-rw-r--r--binutils-2.25/gas/config/tc-xc16x.h4
-rw-r--r--binutils-2.25/gas/config/tc-xgate.c3
-rw-r--r--binutils-2.25/gas/config/tc-xgate.h2
-rw-r--r--binutils-2.25/gas/config/tc-xstormy16.c8
-rw-r--r--binutils-2.25/gas/config/tc-xstormy16.h5
-rw-r--r--binutils-2.25/gas/config/tc-xtensa.c567
-rw-r--r--binutils-2.25/gas/config/tc-xtensa.h8
-rw-r--r--binutils-2.25/gas/config/tc-z80.c12
-rw-r--r--binutils-2.25/gas/config/tc-z80.h4
-rw-r--r--binutils-2.25/gas/config/tc-z8k.c3
-rw-r--r--binutils-2.25/gas/config/tc-z8k.h4
-rw-r--r--binutils-2.25/gas/config/te-386bsd.h3
-rw-r--r--binutils-2.25/gas/config/te-aix5.h2
-rw-r--r--binutils-2.25/gas/config/te-armeabi.h2
-rw-r--r--binutils-2.25/gas/config/te-armfbsdeabi.h22
-rw-r--r--binutils-2.25/gas/config/te-armfbsdvfp.h22
-rw-r--r--binutils-2.25/gas/config/te-armlinuxeabi.h2
-rw-r--r--binutils-2.25/gas/config/te-dragonfly.h2
-rw-r--r--binutils-2.25/gas/config/te-dynix.h2
-rw-r--r--binutils-2.25/gas/config/te-epoc-pe.h2
-rw-r--r--binutils-2.25/gas/config/te-freebsd.h2
-rw-r--r--binutils-2.25/gas/config/te-generic.h2
-rw-r--r--binutils-2.25/gas/config/te-gnu.h2
-rw-r--r--binutils-2.25/gas/config/te-go32.h2
-rw-r--r--binutils-2.25/gas/config/te-hppa.h3
-rw-r--r--binutils-2.25/gas/config/te-hppa64.h2
-rw-r--r--binutils-2.25/gas/config/te-hppalinux64.h2
-rw-r--r--binutils-2.25/gas/config/te-hpux.h2
-rw-r--r--binutils-2.25/gas/config/te-i386aix.h2
-rw-r--r--binutils-2.25/gas/config/te-ia64aix.h2
-rw-r--r--binutils-2.25/gas/config/te-interix.h2
-rw-r--r--binutils-2.25/gas/config/te-irix.h2
-rw-r--r--binutils-2.25/gas/config/te-linux.h2
-rw-r--r--binutils-2.25/gas/config/te-lynx.h2
-rw-r--r--binutils-2.25/gas/config/te-mach.h2
-rw-r--r--binutils-2.25/gas/config/te-macos.h2
-rw-r--r--binutils-2.25/gas/config/te-nacl.h2
-rw-r--r--binutils-2.25/gas/config/te-nbsd.h3
-rw-r--r--binutils-2.25/gas/config/te-nbsd532.h2
-rw-r--r--binutils-2.25/gas/config/te-netware.h2
-rw-r--r--binutils-2.25/gas/config/te-pc532mach.h2
-rw-r--r--binutils-2.25/gas/config/te-pe.h2
-rw-r--r--binutils-2.25/gas/config/te-pep.h2
-rw-r--r--binutils-2.25/gas/config/te-psos.h2
-rw-r--r--binutils-2.25/gas/config/te-riscix.h2
-rw-r--r--binutils-2.25/gas/config/te-solaris.h2
-rw-r--r--binutils-2.25/gas/config/te-sparcaout.h2
-rw-r--r--binutils-2.25/gas/config/te-sun3.h3
-rw-r--r--binutils-2.25/gas/config/te-svr4.h2
-rw-r--r--binutils-2.25/gas/config/te-symbian.h2
-rw-r--r--binutils-2.25/gas/config/te-tmips.h2
-rw-r--r--binutils-2.25/gas/config/te-uclinux.h2
-rw-r--r--binutils-2.25/gas/config/te-vms.c2
-rw-r--r--binutils-2.25/gas/config/te-vms.h2
-rw-r--r--binutils-2.25/gas/config/te-vxworks.h3
-rw-r--r--binutils-2.25/gas/config/te-wince-pe.h2
-rw-r--r--binutils-2.25/gas/config/vax-inst.h3
-rw-r--r--binutils-2.25/gas/config/xtensa-istack.h3
-rw-r--r--binutils-2.25/gas/config/xtensa-relax.c3
-rw-r--r--binutils-2.25/gas/config/xtensa-relax.h2
236 files changed, 12826 insertions, 3956 deletions
diff --git a/binutils-2.25/gas/config/aout_gnu.h b/binutils-2.25/gas/config/aout_gnu.h
index 99186b90..35ab91b0 100644
--- a/binutils-2.25/gas/config/aout_gnu.h
+++ b/binutils-2.25/gas/config/aout_gnu.h
@@ -1,7 +1,6 @@
/* This file is aout_gnu.h
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 2000, 2002,
- 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/atof-ieee.c b/binutils-2.25/gas/config/atof-ieee.c
index 32e57076..d23405c2 100644
--- a/binutils-2.25/gas/config/atof-ieee.c
+++ b/binutils-2.25/gas/config/atof-ieee.c
@@ -1,6 +1,5 @@
/* atof_ieee.c - turn a Flonum into an IEEE floating point number
- Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2005,
- 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/atof-vax.c b/binutils-2.25/gas/config/atof-vax.c
index 6e81ffe3..9075b975 100644
--- a/binutils-2.25/gas/config/atof-vax.c
+++ b/binutils-2.25/gas/config/atof-vax.c
@@ -1,6 +1,5 @@
/* atof_vax.c - turn a Flonum into a VAX floating point number
- Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/bfin-aux.h b/binutils-2.25/gas/config/bfin-aux.h
index e78a4e84..44665b95 100755..100644
--- a/binutils-2.25/gas/config/bfin-aux.h
+++ b/binutils-2.25/gas/config/bfin-aux.h
@@ -1,6 +1,5 @@
/* bfin-aux.h ADI Blackfin Header file for gas
- Copyright 2005, 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/bfin-defs.h b/binutils-2.25/gas/config/bfin-defs.h
index b43fe76b..0f494c89 100644
--- a/binutils-2.25/gas/config/bfin-defs.h
+++ b/binutils-2.25/gas/config/bfin-defs.h
@@ -1,6 +1,5 @@
/* bfin-defs.h ADI Blackfin gas header file
- Copyright 2005, 2006, 2007, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/bfin-lex-wrapper.c b/binutils-2.25/gas/config/bfin-lex-wrapper.c
index e61118cc..d836c303 100644
--- a/binutils-2.25/gas/config/bfin-lex-wrapper.c
+++ b/binutils-2.25/gas/config/bfin-lex-wrapper.c
@@ -1,5 +1,4 @@
-/* Copyright 20012
- Free Software Foundation, Inc.
+/* Copyright (C) 2012-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/bfin-lex.l b/binutils-2.25/gas/config/bfin-lex.l
index 9792323b..c8462c56 100644
--- a/binutils-2.25/gas/config/bfin-lex.l
+++ b/binutils-2.25/gas/config/bfin-lex.l
@@ -1,6 +1,5 @@
/* bfin-lex.l ADI Blackfin lexer
- Copyright 2005, 2006, 2007, 2008, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/bfin-parse.y b/binutils-2.25/gas/config/bfin-parse.y
index 4eaf6f1b..435beea9 100644
--- a/binutils-2.25/gas/config/bfin-parse.y
+++ b/binutils-2.25/gas/config/bfin-parse.y
@@ -1,6 +1,5 @@
/* bfin-parse.y ADI Blackfin parser
- Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -21,7 +20,6 @@
%{
#include "as.h"
-#include <obstack.h>
#include "bfin-aux.h" /* Opcode generating auxiliaries. */
#include "libbfd.h"
diff --git a/binutils-2.25/gas/config/e-crisaout.c b/binutils-2.25/gas/config/e-crisaout.c
index 4adeb0b1..c1fa5448 100644
--- a/binutils-2.25/gas/config/e-crisaout.c
+++ b/binutils-2.25/gas/config/e-crisaout.c
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/e-criself.c b/binutils-2.25/gas/config/e-criself.c
index f4372f00..db869241 100644
--- a/binutils-2.25/gas/config/e-criself.c
+++ b/binutils-2.25/gas/config/e-criself.c
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/e-i386aout.c b/binutils-2.25/gas/config/e-i386aout.c
index 779111a7..7fd7c319 100644
--- a/binutils-2.25/gas/config/e-i386aout.c
+++ b/binutils-2.25/gas/config/e-i386aout.c
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/e-i386coff.c b/binutils-2.25/gas/config/e-i386coff.c
index 6cc42c0a..272a1674 100644
--- a/binutils-2.25/gas/config/e-i386coff.c
+++ b/binutils-2.25/gas/config/e-i386coff.c
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/e-i386elf.c b/binutils-2.25/gas/config/e-i386elf.c
index 8fbd878c..a5b27131 100644
--- a/binutils-2.25/gas/config/e-i386elf.c
+++ b/binutils-2.25/gas/config/e-i386elf.c
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/e-mipself.c b/binutils-2.25/gas/config/e-mipself.c
index 8f37b823..bc7f09ff 100644
--- a/binutils-2.25/gas/config/e-mipself.c
+++ b/binutils-2.25/gas/config/e-mipself.c
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/itbl-mips.h b/binutils-2.25/gas/config/itbl-mips.h
index 90c83d1d..69f1dc47 100644
--- a/binutils-2.25/gas/config/itbl-mips.h
+++ b/binutils-2.25/gas/config/itbl-mips.h
@@ -1,6 +1,6 @@
/* itbl-mips.h
- Copyright 1997, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/m68k-parse.h b/binutils-2.25/gas/config/m68k-parse.h
index 4f91385f..b4c0b5b6 100644
--- a/binutils-2.25/gas/config/m68k-parse.h
+++ b/binutils-2.25/gas/config/m68k-parse.h
@@ -1,6 +1,5 @@
/* m68k-parse.h -- header file for m68k assembler
- Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000,
- 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/m68k-parse.y b/binutils-2.25/gas/config/m68k-parse.y
index 2c58266f..d5c59a18 100644
--- a/binutils-2.25/gas/config/m68k-parse.y
+++ b/binutils-2.25/gas/config/m68k-parse.y
@@ -1,6 +1,5 @@
/* m68k.y -- bison grammar for m68k operand parsing
- Copyright 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-aout.c b/binutils-2.25/gas/config/obj-aout.c
index ce721359..93ea904a 100644
--- a/binutils-2.25/gas/config/obj-aout.c
+++ b/binutils-2.25/gas/config/obj-aout.c
@@ -1,7 +1,5 @@
/* a.out object file format
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2007, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -25,7 +23,6 @@
#include "as.h"
#undef NO_RELOC
#include "aout/aout64.h"
-#include "obstack.h"
void
obj_aout_frob_symbol (symbolS *sym, int *punt ATTRIBUTE_UNUSED)
diff --git a/binutils-2.25/gas/config/obj-aout.h b/binutils-2.25/gas/config/obj-aout.h
index c4184d8e..784dae74 100644
--- a/binutils-2.25/gas/config/obj-aout.h
+++ b/binutils-2.25/gas/config/obj-aout.h
@@ -1,6 +1,5 @@
/* obj-aout.h, a.out object file format for gas, the assembler.
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000,
- 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-coff-seh.c b/binutils-2.25/gas/config/obj-coff-seh.c
index 83e8cb66..ad3fc875 100644
--- a/binutils-2.25/gas/config/obj-coff-seh.c
+++ b/binutils-2.25/gas/config/obj-coff-seh.c
@@ -1,6 +1,5 @@
/* seh pdata/xdata coff object file format
- Copyright 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS.
@@ -170,6 +169,13 @@ seh_validate_seg (const char *directive)
return 0;
}
+/* Switch back to the code section, whatever that may be. */
+static void
+obj_coff_seh_code (int ignored ATTRIBUTE_UNUSED)
+{
+ subseg_set (seh_ctx_cur->code_seg, 0);
+}
+
static void
switch_xdata (int subseg, segT code_seg)
{
diff --git a/binutils-2.25/gas/config/obj-coff-seh.h b/binutils-2.25/gas/config/obj-coff-seh.h
index 71c803f2..cf494851 100644
--- a/binutils-2.25/gas/config/obj-coff-seh.h
+++ b/binutils-2.25/gas/config/obj-coff-seh.h
@@ -1,6 +1,5 @@
/* seh pdata/xdata coff object file format
- Copyright 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS.
@@ -57,6 +56,7 @@
.seh_savereg
.seh_savexmm
.seh_pushframe
+ .seh_code
*/
/* architecture specific pdata/xdata handling. */
@@ -74,6 +74,7 @@
{"seh_32", obj_coff_seh_32, 1}, \
{"seh_no32", obj_coff_seh_32, 0}, \
{"seh_handler", obj_coff_seh_handler, 0}, \
+ {"seh_code", obj_coff_seh_code, 0}, \
{"seh_handlerdata", obj_coff_seh_handlerdata, 0},
/* Type definitions. */
@@ -149,6 +150,7 @@ static void obj_coff_seh_32 (int);
static void obj_coff_seh_proc (int);
static void obj_coff_seh_handler (int);
static void obj_coff_seh_handlerdata (int);
+static void obj_coff_seh_code (int);
#define UNDSEC bfd_und_section_ptr
@@ -202,4 +204,3 @@ static void obj_coff_seh_handlerdata (int);
PEX64_SCOPE_ENTRY_SIZE * (IDX))
#endif
-
diff --git a/binutils-2.25/gas/config/obj-coff.c b/binutils-2.25/gas/config/obj-coff.c
index dbe2f079..9f5a903a 100644
--- a/binutils-2.25/gas/config/obj-coff.c
+++ b/binutils-2.25/gas/config/obj-coff.c
@@ -1,7 +1,5 @@
/* coff object file format
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS.
@@ -24,7 +22,6 @@
#include "as.h"
#include "safe-ctype.h"
-#include "obstack.h"
#include "subsegs.h"
#include "struc-symbol.h"
@@ -390,6 +387,7 @@ coff_obj_symbol_new_hook (symbolS *symbolP)
memset (s, 0, sz);
coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
+ coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
S_SET_DATA_TYPE (symbolP, T_NULL);
S_SET_STORAGE_CLASS (symbolP, 0);
diff --git a/binutils-2.25/gas/config/obj-coff.h b/binutils-2.25/gas/config/obj-coff.h
index ff5548ea..dba6b63f 100644
--- a/binutils-2.25/gas/config/obj-coff.h
+++ b/binutils-2.25/gas/config/obj-coff.h
@@ -1,7 +1,5 @@
/* coff object file format
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS.
@@ -77,11 +75,6 @@
#endif
#endif
-#ifdef TC_OR32
-#include "coff/or32.h"
-#define TARGET_FORMAT "coff-or32-big"
-#endif
-
#ifdef TC_I960
#include "coff/i960.h"
#define TARGET_FORMAT "coff-Intel-little"
diff --git a/binutils-2.25/gas/config/obj-ecoff.c b/binutils-2.25/gas/config/obj-ecoff.c
index a3e5308d..3c1df472 100644
--- a/binutils-2.25/gas/config/obj-ecoff.c
+++ b/binutils-2.25/gas/config/obj-ecoff.c
@@ -1,6 +1,5 @@
/* ECOFF object file format.
- Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
- 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file was put together by Ian Lance Taylor <ian@cygnus.com>.
diff --git a/binutils-2.25/gas/config/obj-ecoff.h b/binutils-2.25/gas/config/obj-ecoff.h
index 1d93dd96..70cafdf4 100644
--- a/binutils-2.25/gas/config/obj-ecoff.h
+++ b/binutils-2.25/gas/config/obj-ecoff.h
@@ -1,6 +1,5 @@
/* ECOFF object file format header file.
- Copyright 1993, 1994, 1995, 1996, 1997, 1999, 2002, 2004, 2005,
- 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
Contributed by Cygnus Support.
Written by Ian Lance Taylor <ian@cygnus.com>.
diff --git a/binutils-2.25/gas/config/obj-elf.c b/binutils-2.25/gas/config/obj-elf.c
index 33772619..e2ef99e2 100644
--- a/binutils-2.25/gas/config/obj-elf.c
+++ b/binutils-2.25/gas/config/obj-elf.c
@@ -1,7 +1,5 @@
/* ELF object file format
- Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -268,7 +266,7 @@ elf_file_symbol (const char *s, int appfile)
|| (symbol_rootP->bsym->flags & BSF_FILE) == 0)
{
symbolS *sym;
- unsigned int name_length;
+ size_t name_length;
sym = symbol_new (s, absolute_section, 0, NULL);
symbol_set_frag (sym, &zero_address_frag);
@@ -1460,6 +1458,62 @@ skip_past_char (char ** str, char c)
}
#define skip_past_comma(str) skip_past_char (str, ',')
+/* A list of attributes that have been explicitly set by the assembly code.
+ VENDOR is the vendor id, BASE is the tag shifted right by the number
+ of bits in MASK, and bit N of MASK is set if tag BASE+N has been set. */
+struct recorded_attribute_info {
+ struct recorded_attribute_info *next;
+ int vendor;
+ unsigned int base;
+ unsigned long mask;
+};
+static struct recorded_attribute_info *recorded_attributes;
+
+/* Record that we have seen an explicit specification of attribute TAG
+ for vendor VENDOR. */
+
+static void
+record_attribute (int vendor, unsigned int tag)
+{
+ unsigned int base;
+ unsigned long mask;
+ struct recorded_attribute_info *rai;
+
+ base = tag / (8 * sizeof (rai->mask));
+ mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+ for (rai = recorded_attributes; rai; rai = rai->next)
+ if (rai->vendor == vendor && rai->base == base)
+ {
+ rai->mask |= mask;
+ return;
+ }
+
+ rai = XNEW (struct recorded_attribute_info);
+ rai->next = recorded_attributes;
+ rai->vendor = vendor;
+ rai->base = base;
+ rai->mask = mask;
+ recorded_attributes = rai;
+}
+
+/* Return true if we have seen an explicit specification of attribute TAG
+ for vendor VENDOR. */
+
+bfd_boolean
+obj_elf_seen_attribute (int vendor, unsigned int tag)
+{
+ unsigned int base;
+ unsigned long mask;
+ struct recorded_attribute_info *rai;
+
+ base = tag / (8 * sizeof (rai->mask));
+ mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+ for (rai = recorded_attributes; rai; rai = rai->next)
+ if (rai->vendor == vendor && rai->base == base)
+ return (rai->mask & mask) != 0;
+ return FALSE;
+}
+
/* Parse an attribute directive for VENDOR.
Returns the attribute number read, or zero on error. */
@@ -1542,6 +1596,7 @@ obj_elf_vendor_attribute (int vendor)
s = demand_copy_C_string (&len);
}
+ record_attribute (vendor, tag);
switch (type & 3)
{
case 3:
@@ -2065,7 +2120,9 @@ elf_frob_symbol (symbolS *symp, int *puntp)
char *p;
p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
- know (p != NULL);
+ if (p == NULL)
+ /* We will have already reported an error about a missing version. */
+ *puntp = TRUE;
/* This symbol was given a new name with the .symver directive.
@@ -2078,14 +2135,15 @@ elf_frob_symbol (symbolS *symp, int *puntp)
symbol. However, it's not clear whether it is the best
approach. */
- if (! S_IS_DEFINED (symp))
+ else if (! S_IS_DEFINED (symp))
{
/* Verify that the name isn't using the @@ syntax--this is
reserved for definitions of the default version to link
against. */
if (p[1] == ELF_VER_CHR)
{
- as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
+ as_bad (_("invalid attempt to declare external version name"
+ " as default in symbol `%s'"),
sy_obj->versioned_name);
*puntp = TRUE;
}
@@ -2348,8 +2406,7 @@ elf_frob_file_before_adjust (void)
p = strchr (symbol_get_obj (symp)->versioned_name,
ELF_VER_CHR);
- know (p != NULL);
- if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
+ if (p != NULL && p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
{
size_t l = strlen (&p[3]) + 1;
memmove (&p[1], &p[3], l);
diff --git a/binutils-2.25/gas/config/obj-elf.h b/binutils-2.25/gas/config/obj-elf.h
index d4fd4d55..3f8f8f49 100644
--- a/binutils-2.25/gas/config/obj-elf.h
+++ b/binutils-2.25/gas/config/obj-elf.h
@@ -1,7 +1,5 @@
/* ELF object file format.
- Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -167,6 +165,8 @@ extern void obj_elf_change_section
(const char *, int, bfd_vma, int, const char *, int, int);
extern struct fix *obj_elf_vtable_inherit (int);
extern struct fix *obj_elf_vtable_entry (int);
+extern bfd_boolean obj_elf_seen_attribute
+ (int, unsigned int);
extern int obj_elf_vendor_attribute (int);
/* BFD wants to write the udata field, which is a no-no for the
diff --git a/binutils-2.25/gas/config/obj-evax.c b/binutils-2.25/gas/config/obj-evax.c
index 2fda63d7..a38269c4 100644
--- a/binutils-2.25/gas/config/obj-evax.c
+++ b/binutils-2.25/gas/config/obj-evax.c
@@ -1,6 +1,5 @@
/* obj-evax.c - EVAX (openVMS/Alpha) object file format.
- Copyright 1996, 1997, 2005, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
Contributed by Klaus Kämpf (kkaempf@progis.de) of
proGIS Software, Aachen, Germany.
Extensively enhanced by Douglas Rupp of AdaCore.
diff --git a/binutils-2.25/gas/config/obj-evax.h b/binutils-2.25/gas/config/obj-evax.h
index b7520b77..c1fc9be1 100644
--- a/binutils-2.25/gas/config/obj-evax.h
+++ b/binutils-2.25/gas/config/obj-evax.h
@@ -1,6 +1,5 @@
/* This file is obj-evax.h
- Copyright 1996, 2000, 2005, 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
Contributed by Klaus Kämpf (kkaempf@progis.de) of
proGIS Software, Aachen, Germany.
diff --git a/binutils-2.25/gas/config/obj-fdpicelf.c b/binutils-2.25/gas/config/obj-fdpicelf.c
index 8a486b09..13d945dc 100644
--- a/binutils-2.25/gas/config/obj-fdpicelf.c
+++ b/binutils-2.25/gas/config/obj-fdpicelf.c
@@ -1,5 +1,4 @@
-/* Copyright 20012
- Free Software Foundation, Inc.
+/* Copyright (C) 2012-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-fdpicelf.h b/binutils-2.25/gas/config/obj-fdpicelf.h
index e91acda2..6da1ef2d 100644
--- a/binutils-2.25/gas/config/obj-fdpicelf.h
+++ b/binutils-2.25/gas/config/obj-fdpicelf.h
@@ -1,5 +1,4 @@
-/* Copyright 20012
- Free Software Foundation, Inc.
+/* Copyright (C) 2012-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-macho.c b/binutils-2.25/gas/config/obj-macho.c
index 21281a0e..fcf17295 100644
--- a/binutils-2.25/gas/config/obj-macho.c
+++ b/binutils-2.25/gas/config/obj-macho.c
@@ -1,5 +1,5 @@
/* Mach-O object file format
- Copyright 2009, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -1013,7 +1013,6 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sym);
bfd_mach_o_section *sec;
int sectype = -1;
- int err = 0;
/* If the symbol is defined, then we can do more rigorous checking on
the validity of the qualifiers. Otherwise, we are stuck with waiting
@@ -1041,7 +1040,8 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
as_bad (_("'%s' previously declared as '%s'."), s->symbol.name,
(s->n_type & BFD_MACH_O_N_PEXT) ? "private extern"
: "global" );
- err = 1;
+ s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
+ return 1;
}
else
{
@@ -1092,7 +1092,8 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
as_bad (_("'%s' can't be a weak_definition (currently only"
" supported in sections of type coalesced)"),
s->symbol.name);
- err = 1;
+ s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
+ return 1;
}
else
s->n_desc |= BFD_MACH_O_N_WEAK_DEF;
@@ -1111,7 +1112,7 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
/* We've seen some kind of qualifier - check validity if or when the entity
is defined. */
s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
- return err;
+ return 0;
}
/* Respond to symbol qualifiers.
@@ -1409,8 +1410,12 @@ void obj_mach_o_frob_label (struct symbol *sp)
{
if ((s->n_desc & BFD_MACH_O_N_WEAK_DEF)
&& sectype != BFD_MACH_O_S_COALESCED)
- as_bad (_("'%s' can't be a weak_definition (currently only supported"
- " in sections of type coalesced)"), s->symbol.name);
+ {
+ as_bad (_("'%s' can't be a weak_definition (currently only supported"
+ " in sections of type coalesced)"), s->symbol.name);
+ /* Don't cascade errors. */
+ s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
+ }
/* Have we changed from an undefined to defined ref? */
s->n_desc &= ~(REFE | LAZY);
@@ -1480,7 +1485,6 @@ obj_mach_o_frob_symbol (struct symbol *sp)
{
/* Anything here that should be added that is non-standard. */
s->n_desc &= ~BFD_MACH_O_REFERENCE_MASK;
- s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
}
else if (s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED)
{
diff --git a/binutils-2.25/gas/config/obj-macho.h b/binutils-2.25/gas/config/obj-macho.h
index 92cb8ef8..632fb8de 100644
--- a/binutils-2.25/gas/config/obj-macho.h
+++ b/binutils-2.25/gas/config/obj-macho.h
@@ -1,5 +1,5 @@
/* Mach-O object file format for gas, the assembler.
- Copyright 2009, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-multi.c b/binutils-2.25/gas/config/obj-multi.c
index 0741137a..8c78d628 100644
--- a/binutils-2.25/gas/config/obj-multi.c
+++ b/binutils-2.25/gas/config/obj-multi.c
@@ -1,4 +1,4 @@
-/* Copyright 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-multi.h b/binutils-2.25/gas/config/obj-multi.h
index 353162ea..e656e2ca 100644
--- a/binutils-2.25/gas/config/obj-multi.h
+++ b/binutils-2.25/gas/config/obj-multi.h
@@ -1,6 +1,5 @@
/* Multiple object format emulation.
- Copyright 1995, 1996, 1997, 1999, 2000, 2002, 2004, 2005, 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/obj-som.c b/binutils-2.25/gas/config/obj-som.c
index 9598e10e..55a9b6a9 100644
--- a/binutils-2.25/gas/config/obj-som.c
+++ b/binutils-2.25/gas/config/obj-som.c
@@ -1,6 +1,5 @@
/* SOM object file format.
- Copyright 1993, 1994, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -25,7 +24,6 @@
#include "as.h"
#include "subsegs.h"
#include "aout/stab_gnu.h"
-#include "obstack.h"
static int version_seen = 0;
static int copyright_seen = 0;
diff --git a/binutils-2.25/gas/config/obj-som.h b/binutils-2.25/gas/config/obj-som.h
index 9fac3c25..bb2aead8 100644
--- a/binutils-2.25/gas/config/obj-som.h
+++ b/binutils-2.25/gas/config/obj-som.h
@@ -1,6 +1,5 @@
/* SOM object file format.
- Copyright 1993, 1994, 1995, 1998, 2000, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/rl78-defs.h b/binutils-2.25/gas/config/rl78-defs.h
index ebe19a97..0af8874e 100644
--- a/binutils-2.25/gas/config/rl78-defs.h
+++ b/binutils-2.25/gas/config/rl78-defs.h
@@ -1,6 +1,5 @@
/* rl78-defs.h Renesas RL78 internal definitions
- Copyright 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -26,6 +25,9 @@
#define RL78REL_DATA 0
#define RL78REL_PCREL 1
+#define RL78_RELAX_NONE 0
+#define RL78_RELAX_BRANCH 1
+
extern int rl78_error (const char *);
extern void rl78_lex_init (char *, char *);
extern void rl78_prefix (int);
diff --git a/binutils-2.25/gas/config/rl78-parse.y b/binutils-2.25/gas/config/rl78-parse.y
index 1f01920c..e358a27b 100644
--- a/binutils-2.25/gas/config/rl78-parse.y
+++ b/binutils-2.25/gas/config/rl78-parse.y
@@ -1,5 +1,5 @@
/* rl78-parse.y Renesas RL78 parser
- Copyright 2011-2013 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -290,22 +290,22 @@ statement :
/* ---------------------------------------------------------------------- */
| BC '$' EXPR
- { B1 (0xdc); PC1 ($3); }
+ { B1 (0xdc); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| BNC '$' EXPR
- { B1 (0xde); PC1 ($3); }
+ { B1 (0xde); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| BZ '$' EXPR
- { B1 (0xdd); PC1 ($3); }
+ { B1 (0xdd); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| BNZ '$' EXPR
- { B1 (0xdf); PC1 ($3); }
+ { B1 (0xdf); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| BH '$' EXPR
- { B2 (0x61, 0xc3); PC1 ($3); }
+ { B2 (0x61, 0xc3); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| BNH '$' EXPR
- { B2 (0x61, 0xd3); PC1 ($3); }
+ { B2 (0x61, 0xd3); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); }
/* ---------------------------------------------------------------------- */
@@ -1153,12 +1153,12 @@ addsubw : ADDW { $$ = 0x00; }
;
andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
- | OR1 { $$ = 0x06; rl78_bit_insn = 1;}
+ | OR1 { $$ = 0x06; rl78_bit_insn = 1; }
| XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
;
-bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1;}
- | BF { $$ = 0x04; rl78_bit_insn = 1; }
+bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1; rl78_relax (RL78_RELAX_BRANCH, 0); }
+ | BF { $$ = 0x04; rl78_bit_insn = 1; rl78_relax (RL78_RELAX_BRANCH, 0); }
| BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
;
diff --git a/binutils-2.25/gas/config/rx-defs.h b/binutils-2.25/gas/config/rx-defs.h
index 78ab4dff..93c4fa9c 100644
--- a/binutils-2.25/gas/config/rx-defs.h
+++ b/binutils-2.25/gas/config/rx-defs.h
@@ -1,5 +1,5 @@
/* rx-defs.h Renesas RX internal definitions
- Copyright 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/rx-parse.y b/binutils-2.25/gas/config/rx-parse.y
index 3933e6b9..d93b4f66 100644
--- a/binutils-2.25/gas/config/rx-parse.y
+++ b/binutils-2.25/gas/config/rx-parse.y
@@ -1,5 +1,5 @@
/* rx-parse.y Renesas RX parser
- Copyright 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -636,13 +636,13 @@ statement :
| BNOT REG ',' REG
{ id24 (1, 0x6f, 0x00); F ($4, 16, 4); F ($2, 20, 4); }
- | BSET REG ',' disp '[' REG ']' DOT_B
+ | BSET REG ',' disp '[' REG ']' opt_b
{ id24 (1, 0x60, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
- | BCLR REG ',' disp '[' REG ']' DOT_B
+ | BCLR REG ',' disp '[' REG ']' opt_b
{ id24 (1, 0x64, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
- | BTST REG ',' disp '[' REG ']' DOT_B
+ | BTST REG ',' disp '[' REG ']' opt_b
{ id24 (1, 0x68, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
- | BNOT REG ',' disp '[' REG ']' DOT_B
+ | BNOT REG ',' disp '[' REG ']' opt_b
{ id24 (1, 0x6c, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); }
/* ---------------------------------------------------------------------- */
@@ -664,13 +664,13 @@ statement :
/* ---------------------------------------------------------------------- */
- | BMCND '#' EXPR ',' disp '[' REG ']' DOT_B
+ | BMCND '#' EXPR ',' disp '[' REG ']' opt_b
{ id24 (1, 0xe0, 0x00); F ($1, 20, 4); FE ($3, 11, 3);
F ($7, 16, 4); DSP ($5, 14, BSIZE); }
/* ---------------------------------------------------------------------- */
- | BNOT '#' EXPR ',' disp '[' REG ']' DOT_B
+ | BNOT '#' EXPR ',' disp '[' REG ']' opt_b
{ id24 (1, 0xe0, 0x0f); FE ($3, 11, 3); F ($7, 16, 4);
DSP ($5, 14, BSIZE); }
@@ -930,6 +930,10 @@ opt_l : {}
| DOT_L {}
;
+opt_b : {}
+ | DOT_B {}
+ ;
+
%%
/* ====================================================================== */
diff --git a/binutils-2.25/gas/config/tc-aarch64.c b/binutils-2.25/gas/config/tc-aarch64.c
index 14ffdadc..0e587646 100644
--- a/binutils-2.25/gas/config/tc-aarch64.c
+++ b/binutils-2.25/gas/config/tc-aarch64.c
@@ -1,7 +1,6 @@
/* tc-aarch64.c -- Assemble for the AArch64 ISA
- Copyright 2009, 2010, 2011, 2012, 2013
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of GAS.
@@ -43,6 +42,8 @@
#define streq(a, b) (strcmp (a, b) == 0)
+#define END_OF_INSN '\0'
+
static aarch64_feature_set cpu_variant;
/* Variables that we set while parsing command-line options. Once all
@@ -436,9 +437,16 @@ static symbolS *last_label_seen;
and per-sub-section basis. */
#define MAX_LITERAL_POOL_SIZE 1024
+typedef struct literal_expression
+{
+ expressionS exp;
+ /* If exp.op == O_big then this bignum holds a copy of the global bignum value. */
+ LITTLENUM_TYPE * bignum;
+} literal_expression;
+
typedef struct literal_pool
{
- expressionS literals[MAX_LITERAL_POOL_SIZE];
+ literal_expression literals[MAX_LITERAL_POOL_SIZE];
unsigned int next_free_entry;
unsigned int id;
symbolS *symbol;
@@ -1617,17 +1625,19 @@ add_to_lit_pool (expressionS *exp, int size)
/* Check if this literal value is already in the pool. */
for (entry = 0; entry < pool->next_free_entry; entry++)
{
- if ((pool->literals[entry].X_op == exp->X_op)
+ expressionS * litexp = & pool->literals[entry].exp;
+
+ if ((litexp->X_op == exp->X_op)
&& (exp->X_op == O_constant)
- && (pool->literals[entry].X_add_number == exp->X_add_number)
- && (pool->literals[entry].X_unsigned == exp->X_unsigned))
+ && (litexp->X_add_number == exp->X_add_number)
+ && (litexp->X_unsigned == exp->X_unsigned))
break;
- if ((pool->literals[entry].X_op == exp->X_op)
+ if ((litexp->X_op == exp->X_op)
&& (exp->X_op == O_symbol)
- && (pool->literals[entry].X_add_number == exp->X_add_number)
- && (pool->literals[entry].X_add_symbol == exp->X_add_symbol)
- && (pool->literals[entry].X_op_symbol == exp->X_op_symbol))
+ && (litexp->X_add_number == exp->X_add_number)
+ && (litexp->X_add_symbol == exp->X_add_symbol)
+ && (litexp->X_op_symbol == exp->X_op_symbol))
break;
}
@@ -1640,8 +1650,18 @@ add_to_lit_pool (expressionS *exp, int size)
return FALSE;
}
- pool->literals[entry] = *exp;
+ pool->literals[entry].exp = *exp;
pool->next_free_entry += 1;
+ if (exp->X_op == O_big)
+ {
+ /* PR 16688: Bignums are held in a single global array. We must
+ copy and preserve that value now, before it is overwritten. */
+ pool->literals[entry].bignum = xmalloc (CHARS_PER_LITTLENUM * exp->X_add_number);
+ memcpy (pool->literals[entry].bignum, generic_bignum,
+ CHARS_PER_LITTLENUM * exp->X_add_number);
+ }
+ else
+ pool->literals[entry].bignum = NULL;
}
exp->X_op = O_symbol;
@@ -1661,7 +1681,7 @@ symbol_locate (symbolS * symbolP,
valueT valu, /* Symbol value. */
fragS * frag) /* Associated fragment. */
{
- unsigned int name_length;
+ size_t name_length;
char *preserved_copy_of_name;
name_length = strlen (name) + 1; /* +1 for \0. */
@@ -1735,8 +1755,26 @@ s_ltorg (int ignored ATTRIBUTE_UNUSED)
symbol_table_insert (pool->symbol);
for (entry = 0; entry < pool->next_free_entry; entry++)
- /* First output the expression in the instruction to the pool. */
- emit_expr (&(pool->literals[entry]), size); /* .word|.xword */
+ {
+ expressionS * exp = & pool->literals[entry].exp;
+
+ if (exp->X_op == O_big)
+ {
+ /* PR 16688: Restore the global bignum value. */
+ gas_assert (pool->literals[entry].bignum != NULL);
+ memcpy (generic_bignum, pool->literals[entry].bignum,
+ CHARS_PER_LITTLENUM * exp->X_add_number);
+ }
+
+ /* First output the expression in the instruction to the pool. */
+ emit_expr (exp, size); /* .word|.xword */
+
+ if (exp->X_op == O_big)
+ {
+ free (pool->literals[entry].bignum);
+ pool->literals[entry].bignum = NULL;
+ }
+ }
/* Mark the pool as empty. */
pool->next_free_entry = 0;
@@ -2816,7 +2854,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
if (**str == '\0')
return TRUE;
- /* Otherwise, we have a shifted reloc modifier, so rewind to
+ /* Otherwise, we have a shifted reloc modifier, so rewind to
recover the variable name and continue parsing for the shifter. */
*str = p;
return parse_shifter_operand_imm (str, operand, mode);
@@ -3270,14 +3308,14 @@ parse_barrier (char **str)
Returns the encoding for the option, or PARSE_FAIL.
If IMPLE_DEFINED_P is non-zero, the function will also try to parse the
- implementation defined system register name S3_<op1>_<Cn>_<Cm>_<op2>. */
+ implementation defined system register name S<op0>_<op1>_<Cn>_<Cm>_<op2>. */
static int
parse_sys_reg (char **str, struct hash_control *sys_regs, int imple_defined_p)
{
char *p, *q;
char buf[32];
- const struct aarch64_name_value_pair *o;
+ const aarch64_sys_reg *o;
int value;
p = buf;
@@ -3295,25 +3333,24 @@ parse_sys_reg (char **str, struct hash_control *sys_regs, int imple_defined_p)
return PARSE_FAIL;
else
{
- /* Parse S3_<op1>_<Cn>_<Cm>_<op2>, the implementation defined
- registers. */
+ /* Parse S<op0>_<op1>_<Cn>_<Cm>_<op2>. */
unsigned int op0, op1, cn, cm, op2;
- if (sscanf (buf, "s%u_%u_c%u_c%u_%u", &op0, &op1, &cn, &cm, &op2) != 5)
+
+ if (sscanf (buf, "s%u_%u_c%u_c%u_%u", &op0, &op1, &cn, &cm, &op2)
+ != 5)
return PARSE_FAIL;
- /* The architecture specifies the encoding space for implementation
- defined registers as:
- op0 op1 CRn CRm op2
- 11 xxx 1x11 xxxx xxx
- For convenience GAS accepts a wider encoding space, as follows:
- op0 op1 CRn CRm op2
- 11 xxx xxxx xxxx xxx */
- if (op0 != 3 || op1 > 7 || cn > 15 || cm > 15 || op2 > 7)
+ if (op0 > 3 || op1 > 7 || cn > 15 || cm > 15 || op2 > 7)
return PARSE_FAIL;
value = (op0 << 14) | (op1 << 11) | (cn << 7) | (cm << 3) | op2;
}
}
else
- value = o->value;
+ {
+ if (aarch64_sys_reg_deprecated_p (o))
+ as_warn (_("system register name '%s' is deprecated and may be "
+"removed in a future release"), buf);
+ value = o->value;
+ }
*str = q;
return value;
@@ -3512,9 +3549,9 @@ fix_new_aarch64 (fragS * frag,
/* Diagnostics on operands errors. */
-/* By default, output one-line error message only.
- Enable the verbose error message by -merror-verbose. */
-static int verbose_error_p = 0;
+/* By default, output verbose error message.
+ Disable the verbose error message by -mno-verbose-error. */
+static int verbose_error_p = 1;
#ifdef DEBUG_AARCH64
/* N.B. this is only for the purpose of debugging. */
@@ -4602,6 +4639,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
case AARCH64_OPND_Rs:
case AARCH64_OPND_Ra:
case AARCH64_OPND_Rt_SYS:
+ case AARCH64_OPND_PAIRREG:
po_int_reg_or_fail (1, 0);
break;
@@ -4810,7 +4848,8 @@ parse_operands (char *str, const aarch64_opcode *opcode)
case AARCH64_OPND_IMM_MOV:
{
char *saved = str;
- if (reg_name_p (str, REG_TYPE_R_Z_SP))
+ if (reg_name_p (str, REG_TYPE_R_Z_SP) ||
+ reg_name_p (str, REG_TYPE_VN))
goto failure;
str = saved;
po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
@@ -4968,6 +5007,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
break;
case AARCH64_OPND_COND:
+ case AARCH64_OPND_COND1:
info->cond = hash_find_n (aarch64_cond_hsh, str, 2);
str += 2;
if (info->cond == NULL)
@@ -4975,6 +5015,13 @@ parse_operands (char *str, const aarch64_opcode *opcode)
set_syntax_error (_("invalid condition"));
goto failure;
}
+ else if (operands[i] == AARCH64_OPND_COND1
+ && (info->cond->value & 0xe) == 0xe)
+ {
+ /* Not allow AL or NV. */
+ set_default_error ();
+ goto failure;
+ }
break;
case AARCH64_OPND_ADDR_ADRP:
@@ -5252,6 +5299,37 @@ failure:
if (! backtrack_pos)
goto parse_operands_return;
+ {
+ /* We reach here because this operand is marked as optional, and
+ either no operand was supplied or the operand was supplied but it
+ was syntactically incorrect. In the latter case we report an
+ error. In the former case we perform a few more checks before
+ dropping through to the code to insert the default operand. */
+
+ char *tmp = backtrack_pos;
+ char endchar = END_OF_INSN;
+
+ if (i != (aarch64_num_of_operands (opcode) - 1))
+ endchar = ',';
+ skip_past_char (&tmp, ',');
+
+ if (*tmp != endchar)
+ /* The user has supplied an operand in the wrong format. */
+ goto parse_operands_return;
+
+ /* Make sure there is not a comma before the optional operand.
+ For example the fifth operand of 'sys' is optional:
+
+ sys #0,c0,c0,#0, <--- wrong
+ sys #0,c0,c0,#0 <--- correct. */
+ if (comma_skipped_p && i && endchar == END_OF_INSN)
+ {
+ set_fatal_syntax_error
+ (_("unexpected comma before the omitted optional operand"));
+ goto parse_operands_return;
+ }
+ }
+
/* Reaching here means we are dealing with an optional operand that is
omitted from the assembly line. */
gas_assert (optional_operand_p (opcode, i));
@@ -5262,15 +5340,6 @@ failure:
str = backtrack_pos;
backtrack_pos = 0;
- /* If this is the last operand that is optional and omitted, but without
- the presence of a comma. */
- if (i && comma_skipped_p && i == aarch64_num_of_operands (opcode) - 1)
- {
- set_fatal_syntax_error
- (_("unexpected comma before the omitted optional operand"));
- goto parse_operands_return;
- }
-
/* Clear any error record after the omitted optional operand has been
successfully handled. */
clear_error ();
@@ -5517,14 +5586,6 @@ md_assemble (char *str)
dump_opcode_operands (opcode);
#endif /* DEBUG_AARCH64 */
- /* Check that this instruction is supported for this CPU. */
- if (!opcode->avariant
- || !AARCH64_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
- {
- as_bad (_("selected processor does not support `%s'"), str);
- return;
- }
-
mapping_state (MAP_INSN);
inst_base = &inst.base;
@@ -5549,6 +5610,14 @@ md_assemble (char *str)
&& programmer_friendly_fixup (&inst)
&& do_encode (inst_base->opcode, &inst.base, &inst_base->value))
{
+ /* Check that this instruction is supported for this CPU. */
+ if (!opcode->avariant
+ || !AARCH64_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
+ {
+ as_bad (_("selected processor does not support `%s'"), str);
+ return;
+ }
+
if (inst.reloc.type == BFD_RELOC_UNUSED
|| !inst.reloc.need_libopcodes_p)
output_inst (NULL);
@@ -5754,7 +5823,24 @@ md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
}
/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
- of an rs_align_code fragment. */
+ of an rs_align_code fragment.
+
+ Here we fill the frag with the appropriate info for padding the
+ output stream. The resulting frag will consist of a fixed (fr_fix)
+ and of a repeating (fr_var) part.
+
+ The fixed content is always emitted before the repeating content and
+ these two parts are used as follows in constructing the output:
+ - the fixed part will be used to align to a valid instruction word
+ boundary, in case that we start at a misaligned address; as no
+ executable instruction can live at the misaligned location, we
+ simply fill with zeros;
+ - the variable part will be used to cover the remaining padding and
+ we fill using the AArch64 NOP instruction.
+
+ Note that the size of a RS_ALIGN_CODE fragment is always 7 to provide
+ enough storage space for up to 3 bytes for padding the back to a valid
+ instruction alignment and exactly 4 bytes to store the NOP pattern. */
void
aarch64_handle_align (fragS * fragP)
@@ -5765,69 +5851,33 @@ aarch64_handle_align (fragS * fragP)
int bytes, fix, noop_size;
char *p;
- const char *noop;
if (fragP->fr_type != rs_align_code)
return;
bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
p = fragP->fr_literal + fragP->fr_fix;
- fix = 0;
-
- if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
- bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
#ifdef OBJ_ELF
gas_assert (fragP->tc_frag_data.recorded);
#endif
- noop = aarch64_noop;
noop_size = sizeof (aarch64_noop);
- fragP->fr_var = noop_size;
- if (bytes & (noop_size - 1))
+ fix = bytes & (noop_size - 1);
+ if (fix)
{
- fix = bytes & (noop_size - 1);
#ifdef OBJ_ELF
insert_data_mapping_symbol (MAP_INSN, fragP->fr_fix, fragP, fix);
#endif
memset (p, 0, fix);
p += fix;
- bytes -= fix;
+ fragP->fr_fix += fix;
}
- while (bytes >= noop_size)
- {
- memcpy (p, noop, noop_size);
- p += noop_size;
- bytes -= noop_size;
- fix += noop_size;
- }
-
- fragP->fr_fix += fix;
-}
-
-/* Called from md_do_align. Used to create an alignment
- frag in a code section. */
-
-void
-aarch64_frag_align_code (int n, int max)
-{
- char *p;
-
- /* We assume that there will never be a requirement
- to support alignments greater than x bytes. */
- if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
- as_fatal (_
- ("alignments greater than %d bytes not supported in .text sections"),
- MAX_MEM_FOR_RS_ALIGN_CODE + 1);
-
- p = frag_var (rs_align_code,
- MAX_MEM_FOR_RS_ALIGN_CODE,
- 1,
- (relax_substateT) max,
- (symbolS *) NULL, (offsetT) n, (char *) NULL);
- *p = 0;
+ if (noop_size)
+ memcpy (p, aarch64_noop, noop_size);
+ fragP->fr_var = noop_size;
}
/* Perform target specific initialisation of a frag.
@@ -5892,12 +5942,15 @@ tc_aarch64_regname_to_dw2regnum (char *regname)
case REG_TYPE_SP_64:
case REG_TYPE_R_32:
case REG_TYPE_R_64:
+ return reg->number;
+
case REG_TYPE_FP_B:
case REG_TYPE_FP_H:
case REG_TYPE_FP_S:
case REG_TYPE_FP_D:
case REG_TYPE_FP_Q:
- return reg->number;
+ return reg->number + 64;
+
default:
break;
}
@@ -6591,6 +6644,10 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_TLSDESC_CALL:
break;
+ case BFD_RELOC_UNUSED:
+ /* An error will already have been reported. */
+ break;
+
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
_("unexpected %s fixup"),
@@ -7105,6 +7162,8 @@ static struct aarch64_option_table aarch64_opts[] = {
#endif /* DEBUG_AARCH64 */
{"mverbose-error", N_("output verbose error messages"), &verbose_error_p, 1,
NULL},
+ {"mno-verbose-error", N_("do not output verbose error messages"),
+ &verbose_error_p, 0, NULL},
{NULL, NULL, NULL, 0, NULL}
};
@@ -7121,8 +7180,17 @@ struct aarch64_cpu_option_table
recognized by GCC. */
static const struct aarch64_cpu_option_table aarch64_cpus[] = {
{"all", AARCH64_ANY, NULL},
- {"cortex-a53", AARCH64_ARCH_V8, "Cortex-A53"},
- {"cortex-a57", AARCH64_ARCH_V8, "Cortex-A57"},
+ {"cortex-a53", AARCH64_FEATURE(AARCH64_ARCH_V8,
+ AARCH64_FEATURE_CRC), "Cortex-A53"},
+ {"cortex-a57", AARCH64_FEATURE(AARCH64_ARCH_V8,
+ AARCH64_FEATURE_CRC), "Cortex-A57"},
+ /* The 'xgene-1' name is an older name for 'xgene1', which was used
+ in earlier releases and is superseded by 'xgene1' in all
+ tools. */
+ {"xgene-1", AARCH64_ARCH_V8, "APM X-Gene 1"},
+ {"xgene1", AARCH64_ARCH_V8, "APM X-Gene 1"},
+ {"xgene2", AARCH64_FEATURE(AARCH64_ARCH_V8,
+ AARCH64_FEATURE_CRC), "APM X-Gene 2"},
{"generic", AARCH64_ARCH_V8, NULL},
/* These two are example CPUs supported in GCC, once we have real
@@ -7158,6 +7226,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
{"crc", AARCH64_FEATURE (AARCH64_FEATURE_CRC, 0)},
{"crypto", AARCH64_FEATURE (AARCH64_FEATURE_CRYPTO, 0)},
{"fp", AARCH64_FEATURE (AARCH64_FEATURE_FP, 0)},
+ {"lse", AARCH64_FEATURE (AARCH64_FEATURE_LSE, 0)},
{"simd", AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)},
{NULL, AARCH64_ARCH_NONE}
};
diff --git a/binutils-2.25/gas/config/tc-aarch64.h b/binutils-2.25/gas/config/tc-aarch64.h
index 74a81d65..1fad6ce5 100644
--- a/binutils-2.25/gas/config/tc-aarch64.h
+++ b/binutils-2.25/gas/config/tc-aarch64.h
@@ -1,5 +1,5 @@
/* tc-aarch64.h -- Header file for tc-aarch64.c.
- Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of GAS.
@@ -114,10 +114,11 @@ void aarch64_copy_symbol_attributes (symbolS *, symbolS *);
|| (FIX)->fx_r_type == BFD_RELOC_32 \
|| TC_FORCE_RELOCATION (FIX))
-#define TC_CONS_FIX_NEW cons_fix_new_aarch64
+#define TC_CONS_FIX_NEW(f,w,s,e,r) cons_fix_new_aarch64 ((f), (w), (s), (e))
-/* Max code alignment is 32 bytes */
-#define MAX_MEM_FOR_RS_ALIGN_CODE 31
+/* Max space for a rs_align_code fragment is 3 unaligned bytes
+ (fr_fix) plus 4 bytes to contain the repeating NOP (fr_var). */
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
/* For frags in code sections we need to record whether they contain
code or data. */
@@ -141,17 +142,17 @@ struct aarch64_frag_type
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg)) \
{ \
- aarch64_frag_align_code (N, MAX); \
+ frag_align_code (N, MAX); \
goto LABEL; \
}
-#define DWARF2_LINE_MIN_INSN_LENGTH 2
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
/* The lr register is r30. */
#define DWARF2_DEFAULT_RETURN_COLUMN 30
/* Registers are generally saved at negative offsets to the CFA. */
-#define DWARF2_CIE_DATA_ALIGNMENT (-4)
+#define DWARF2_CIE_DATA_ALIGNMENT (-8)
extern int aarch64_dwarf2_addr_size (void);
#define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()
diff --git a/binutils-2.25/gas/config/tc-alpha.c b/binutils-2.25/gas/config/tc-alpha.c
index d020896d..ea6aa190 100644
--- a/binutils-2.25/gas/config/tc-alpha.c
+++ b/binutils-2.25/gas/config/tc-alpha.c
@@ -1,7 +1,5 @@
/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
- Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
Contributed by Carnegie Mellon University, 1993.
Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
Modified by Ken Raeburn for gas-2.x and ECOFF support.
diff --git a/binutils-2.25/gas/config/tc-alpha.h b/binutils-2.25/gas/config/tc-alpha.h
index 284c1e41..98f81f59 100644
--- a/binutils-2.25/gas/config/tc-alpha.h
+++ b/binutils-2.25/gas/config/tc-alpha.h
@@ -1,7 +1,5 @@
/* This file is tc-alpha.h
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- 2005, 2006, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Written by Ken Raeburn <raeburn@cygnus.com>.
This file is part of GAS, the GNU Assembler.
@@ -73,7 +71,8 @@ extern valueT alpha_gp_value;
#define tc_canonicalize_symbol_name evax_shorten_name
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) \
+#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP,RELOC) \
+ (void) RELOC, \
fix_new_exp (FRAG, OFF, (int)LEN, EXP, 0, \
LEN == 2 ? BFD_RELOC_16 \
: LEN == 4 ? BFD_RELOC_32 \
diff --git a/binutils-2.25/gas/config/tc-arc.c b/binutils-2.25/gas/config/tc-arc.c
index 8d2da96b..5499d88e 100644
--- a/binutils-2.25/gas/config/tc-arc.c
+++ b/binutils-2.25/gas/config/tc-arc.c
@@ -1,6 +1,5 @@
/* tc-arc.c -- Assembler for the ARC
- Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2009, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of GAS, the GNU Assembler.
@@ -1161,7 +1160,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
Values for the status register are specified with %st(label).
`label' will be right shifted by 2. */
-void
+bfd_reloc_code_real_type
arc_parse_cons_expression (expressionS *exp,
unsigned int nbytes ATTRIBUTE_UNUSED)
{
@@ -1180,6 +1179,7 @@ arc_parse_cons_expression (expressionS *exp,
arc_code_symbol (exp);
input_line_pointer = p;
}
+ return BFD_RELOC_NONE;
}
/* Record a fixup for a cons expression. */
@@ -1188,7 +1188,8 @@ void
arc_cons_fix_new (fragS *frag,
int where,
int nbytes,
- expressionS *exp)
+ expressionS *exp,
+ bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
{
if (nbytes == 4)
{
diff --git a/binutils-2.25/gas/config/tc-arc.h b/binutils-2.25/gas/config/tc-arc.h
index 26c0d5f6..a2789e68 100644
--- a/binutils-2.25/gas/config/tc-arc.h
+++ b/binutils-2.25/gas/config/tc-arc.h
@@ -1,6 +1,5 @@
/* tc-arc.h - Macros and type defines for the ARC.
- Copyright 1994, 1995, 1997, 2000, 2001, 2002, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of GAS, the GNU Assembler.
@@ -55,13 +54,15 @@ extern const char * arc_target_format;
/* The ARC needs to parse reloc specifiers in .word. */
-extern void arc_parse_cons_expression (struct expressionS *, unsigned);
+extern bfd_reloc_code_real_type arc_parse_cons_expression (struct expressionS *,
+ unsigned);
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
arc_parse_cons_expression (EXP, NBYTES)
-extern void arc_cons_fix_new (struct frag *, int, int, struct expressionS *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
- arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
+extern void arc_cons_fix_new (struct frag *, int, int, struct expressionS *,
+ bfd_reloc_code_real_type);
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \
+ arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC)
#define DWARF2_LINE_MIN_INSN_LENGTH 4
diff --git a/binutils-2.25/gas/config/tc-arm.c b/binutils-2.25/gas/config/tc-arm.c
index d170f43d..5077f87e 100644
--- a/binutils-2.25/gas/config/tc-arm.c
+++ b/binutils-2.25/gas/config/tc-arm.c
@@ -1,5 +1,5 @@
/* tc-arm.c -- Assemble for the ARM
- Copyright 1994-2013 Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
Modified by David Taylor (dtaylor@armltd.co.uk)
Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
@@ -137,6 +137,8 @@ static int fix_v4bx = FALSE;
/* Warn on using deprecated features. */
static int warn_on_deprecated = TRUE;
+/* Understand CodeComposer Studio assembly syntax. */
+bfd_boolean codecomposer_syntax = FALSE;
/* Variables that we set while parsing command-line options. Once all
options have been read we re-process these values to set the real
@@ -247,6 +249,8 @@ static arm_feature_set selected_cpu = ARM_ARCH_NONE;
/* Must be long enough to hold any of the names in arm_cpus. */
static char selected_cpu_name[16];
+extern FLONUM_TYPE generic_floating_point_number;
+
/* Return if no cpu was selected on command-line. */
static bfd_boolean
no_cpu_selected (void)
@@ -628,6 +632,7 @@ struct asm_opcode
#define LITERAL_MASK 0xf000f000
#define OPCODE_MASK 0xfe1fffff
#define V4_STR_BIT 0x00000020
+#define VLDR_VMOV_SAME 0x0040f000
#define T2_SUBS_PC_LR 0xf3de8f00
@@ -790,11 +795,21 @@ typedef struct literal_pool
struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
#endif
struct literal_pool * next;
+ unsigned int alignment;
} literal_pool;
/* Pointer to a linked list of literal pools. */
literal_pool * list_of_pools = NULL;
+typedef enum asmfunc_states
+{
+ OUTSIDE_ASMFUNC,
+ WAITING_ASMFUNC_NAME,
+ WAITING_ENDASMFUNC
+} asmfunc_states;
+
+static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
+
#ifdef OBJ_ELF
# define now_it seg_info (now_seg)->tc_segment_info_data.current_it
#else
@@ -853,7 +868,7 @@ static void it_fsm_post_encode (void);
/* This array holds the chars that always start a comment. If the
pre-processor is disabled, these aren't very useful. */
-const char comment_chars[] = "@";
+char arm_comment_chars[] = "@";
/* This array holds the chars that only start a comment at the beginning of
a line. If the line seems to have the form '# 123 filename'
@@ -864,7 +879,7 @@ const char comment_chars[] = "@";
/* Also note that comments like this one will always work. */
const char line_comment_chars[] = "#";
-const char line_separator_chars[] = ";";
+char arm_line_separator_chars[] = ";";
/* Chars that can be used to separate mant
from exp in floating point numbers. */
@@ -3012,6 +3027,104 @@ s_even (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
+/* Directives: CodeComposer Studio. */
+
+/* .ref (for CodeComposer Studio syntax only). */
+static void
+s_ccs_ref (int unused ATTRIBUTE_UNUSED)
+{
+ if (codecomposer_syntax)
+ ignore_rest_of_line ();
+ else
+ as_bad (_(".ref pseudo-op only available with -mccs flag."));
+}
+
+/* If name is not NULL, then it is used for marking the beginning of a
+ function, wherease if it is NULL then it means the function end. */
+static void
+asmfunc_debug (const char * name)
+{
+ static const char * last_name = NULL;
+
+ if (name != NULL)
+ {
+ gas_assert (last_name == NULL);
+ last_name = name;
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_func (name, name);
+ }
+ else
+ {
+ gas_assert (last_name != NULL);
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_endfunc (last_name, last_name);
+
+ last_name = NULL;
+ }
+}
+
+static void
+s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
+{
+ if (codecomposer_syntax)
+ {
+ switch (asmfunc_state)
+ {
+ case OUTSIDE_ASMFUNC:
+ asmfunc_state = WAITING_ASMFUNC_NAME;
+ break;
+
+ case WAITING_ASMFUNC_NAME:
+ as_bad (_(".asmfunc repeated."));
+ break;
+
+ case WAITING_ENDASMFUNC:
+ as_bad (_(".asmfunc without function."));
+ break;
+ }
+ demand_empty_rest_of_line ();
+ }
+ else
+ as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
+}
+
+static void
+s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
+{
+ if (codecomposer_syntax)
+ {
+ switch (asmfunc_state)
+ {
+ case OUTSIDE_ASMFUNC:
+ as_bad (_(".endasmfunc without a .asmfunc."));
+ break;
+
+ case WAITING_ASMFUNC_NAME:
+ as_bad (_(".endasmfunc without function."));
+ break;
+
+ case WAITING_ENDASMFUNC:
+ asmfunc_state = OUTSIDE_ASMFUNC;
+ asmfunc_debug (NULL);
+ break;
+ }
+ demand_empty_rest_of_line ();
+ }
+ else
+ as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
+}
+
+static void
+s_ccs_def (int name)
+{
+ if (codecomposer_syntax)
+ s_globl (name);
+ else
+ as_bad (_(".def pseudo-op only available with -mccs flag."));
+}
+
/* Directives: Literal pools. */
static literal_pool *
@@ -3050,6 +3163,7 @@ find_or_make_literal_pool (void)
pool->sub_section = now_subseg;
pool->next = list_of_pools;
pool->symbol = NULL;
+ pool->alignment = 2;
/* Add it to the list. */
list_of_pools = pool;
@@ -3071,33 +3185,74 @@ find_or_make_literal_pool (void)
structure to the relevant literal pool. */
static int
-add_to_lit_pool (void)
+add_to_lit_pool (unsigned int nbytes)
{
+#define PADDING_SLOT 0x1
+#define LIT_ENTRY_SIZE_MASK 0xFF
literal_pool * pool;
- unsigned int entry;
+ unsigned int entry, pool_size = 0;
+ bfd_boolean padding_slot_p = FALSE;
+ unsigned imm1 = 0;
+ unsigned imm2 = 0;
+
+ if (nbytes == 8)
+ {
+ imm1 = inst.operands[1].imm;
+ imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
+ : inst.reloc.exp.X_unsigned ? 0
+ : ((bfd_int64_t) inst.operands[1].imm) >> 32);
+ if (target_big_endian)
+ {
+ imm1 = imm2;
+ imm2 = inst.operands[1].imm;
+ }
+ }
pool = find_or_make_literal_pool ();
/* Check if this literal value is already in the pool. */
for (entry = 0; entry < pool->next_free_entry; entry ++)
{
- if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
- && (inst.reloc.exp.X_op == O_constant)
- && (pool->literals[entry].X_add_number
- == inst.reloc.exp.X_add_number)
- && (pool->literals[entry].X_unsigned
- == inst.reloc.exp.X_unsigned))
+ if (nbytes == 4)
+ {
+ if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
+ && (inst.reloc.exp.X_op == O_constant)
+ && (pool->literals[entry].X_add_number
+ == inst.reloc.exp.X_add_number)
+ && (pool->literals[entry].X_md == nbytes)
+ && (pool->literals[entry].X_unsigned
+ == inst.reloc.exp.X_unsigned))
+ break;
+
+ if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
+ && (inst.reloc.exp.X_op == O_symbol)
+ && (pool->literals[entry].X_add_number
+ == inst.reloc.exp.X_add_number)
+ && (pool->literals[entry].X_add_symbol
+ == inst.reloc.exp.X_add_symbol)
+ && (pool->literals[entry].X_op_symbol
+ == inst.reloc.exp.X_op_symbol)
+ && (pool->literals[entry].X_md == nbytes))
+ break;
+ }
+ else if ((nbytes == 8)
+ && !(pool_size & 0x7)
+ && ((entry + 1) != pool->next_free_entry)
+ && (pool->literals[entry].X_op == O_constant)
+ && (pool->literals[entry].X_add_number == (offsetT) imm1)
+ && (pool->literals[entry].X_unsigned
+ == inst.reloc.exp.X_unsigned)
+ && (pool->literals[entry + 1].X_op == O_constant)
+ && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
+ && (pool->literals[entry + 1].X_unsigned
+ == inst.reloc.exp.X_unsigned))
break;
- if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
- && (inst.reloc.exp.X_op == O_symbol)
- && (pool->literals[entry].X_add_number
- == inst.reloc.exp.X_add_number)
- && (pool->literals[entry].X_add_symbol
- == inst.reloc.exp.X_add_symbol)
- && (pool->literals[entry].X_op_symbol
- == inst.reloc.exp.X_op_symbol))
+ padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
+ if (padding_slot_p && (nbytes == 4))
break;
+
+ pool_size += 4;
}
/* Do we need to create a new entry? */
@@ -3109,7 +3264,64 @@ add_to_lit_pool (void)
return FAIL;
}
- pool->literals[entry] = inst.reloc.exp;
+ if (nbytes == 8)
+ {
+ /* For 8-byte entries, we align to an 8-byte boundary,
+ and split it into two 4-byte entries, because on 32-bit
+ host, 8-byte constants are treated as big num, thus
+ saved in "generic_bignum" which will be overwritten
+ by later assignments.
+
+ We also need to make sure there is enough space for
+ the split.
+
+ We also check to make sure the literal operand is a
+ constant number. */
+ if (!(inst.reloc.exp.X_op == O_constant
+ || inst.reloc.exp.X_op == O_big))
+ {
+ inst.error = _("invalid type for literal pool");
+ return FAIL;
+ }
+ else if (pool_size & 0x7)
+ {
+ if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
+ {
+ inst.error = _("literal pool overflow");
+ return FAIL;
+ }
+
+ pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry].X_add_number = 0;
+ pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
+ pool->next_free_entry += 1;
+ pool_size += 4;
+ }
+ else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
+ {
+ inst.error = _("literal pool overflow");
+ return FAIL;
+ }
+
+ pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry].X_op = O_constant;
+ pool->literals[entry].X_add_number = imm1;
+ pool->literals[entry].X_unsigned = inst.reloc.exp.X_unsigned;
+ pool->literals[entry++].X_md = 4;
+ pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry].X_op = O_constant;
+ pool->literals[entry].X_add_number = imm2;
+ pool->literals[entry].X_unsigned = inst.reloc.exp.X_unsigned;
+ pool->literals[entry].X_md = 4;
+ pool->alignment = 3;
+ pool->next_free_entry += 1;
+ }
+ else
+ {
+ pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry].X_md = 4;
+ }
+
#ifdef OBJ_ELF
/* PR ld/12974: Record the location of the first source line to reference
this entry in the literal pool. If it turns out during linking that the
@@ -3120,14 +3332,45 @@ add_to_lit_pool (void)
#endif
pool->next_free_entry += 1;
}
+ else if (padding_slot_p)
+ {
+ pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry].X_md = nbytes;
+ }
inst.reloc.exp.X_op = O_symbol;
- inst.reloc.exp.X_add_number = ((int) entry) * 4;
+ inst.reloc.exp.X_add_number = pool_size;
inst.reloc.exp.X_add_symbol = pool->symbol;
return SUCCESS;
}
+bfd_boolean
+tc_start_label_without_colon (char unused1 ATTRIBUTE_UNUSED, const char * rest)
+{
+ bfd_boolean ret = TRUE;
+
+ if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
+ {
+ const char *label = rest;
+
+ while (!is_end_of_line[(int) label[-1]])
+ --label;
+
+ if (*label == '.')
+ {
+ as_bad (_("Invalid label '%s'"), label);
+ ret = FALSE;
+ }
+
+ asmfunc_debug (label);
+
+ asmfunc_state = WAITING_ENDASMFUNC;
+ }
+
+ return ret;
+}
+
/* Can't use symbol_new here, so have to create a symbol and then at
a later date assign it a value. Thats what these functions do. */
@@ -3138,7 +3381,7 @@ symbol_locate (symbolS * symbolP,
valueT valu, /* Symbol value. */
fragS * frag) /* Associated fragment. */
{
- unsigned int name_length;
+ size_t name_length;
char * preserved_copy_of_name;
name_length = strlen (name) + 1; /* +1 for \0. */
@@ -3179,7 +3422,6 @@ symbol_locate (symbolS * symbolP,
#endif /* DEBUG_SYMS */
}
-
static void
s_ltorg (int ignored ATTRIBUTE_UNUSED)
{
@@ -3193,15 +3435,17 @@ s_ltorg (int ignored ATTRIBUTE_UNUSED)
|| pool->next_free_entry == 0)
return;
- mapping_state (MAP_DATA);
-
/* Align pool as you have word accesses.
Only make a frag if we have to. */
if (!need_pass_2)
- frag_align (2, 0, 0);
+ frag_align (pool->alignment, 0, 0);
record_alignment (now_seg, 2);
+#ifdef OBJ_ELF
+ seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
+ make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
+#endif
sprintf (sym_name, "$$lit_\002%x", pool->id);
symbol_locate (pool->symbol, sym_name, now_seg,
@@ -3221,7 +3465,8 @@ s_ltorg (int ignored ATTRIBUTE_UNUSED)
dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
#endif
/* First output the expression in the instruction to the pool. */
- emit_expr (&(pool->literals[entry]), 4); /* .word */
+ emit_expr (&(pool->literals[entry]),
+ pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
}
/* Mark the pool as empty. */
@@ -3316,7 +3561,8 @@ s_arm_elf_cons (int nbytes)
memcpy (base, save_buf, p - base);
offset = nbytes - size;
- p = frag_more ((int) nbytes);
+ p = frag_more (nbytes);
+ memset (p, 0, nbytes);
fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
size, &exp, 0, (enum bfd_reloc_code_real) reloc);
}
@@ -4134,15 +4380,24 @@ s_arm_unwind_save (int arch_v6)
s_arm_unwind_save_fpa (reg->number);
return;
- case REG_TYPE_RN: s_arm_unwind_save_core (); return;
+ case REG_TYPE_RN:
+ s_arm_unwind_save_core ();
+ return;
+
case REG_TYPE_VFD:
if (arch_v6)
s_arm_unwind_save_vfp_armv6 ();
else
s_arm_unwind_save_vfp ();
return;
- case REG_TYPE_MMXWR: s_arm_unwind_save_mmxwr (); return;
- case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return;
+
+ case REG_TYPE_MMXWR:
+ s_arm_unwind_save_mmxwr ();
+ return;
+
+ case REG_TYPE_MMXWCG:
+ s_arm_unwind_save_mmxwcg ();
+ return;
default:
as_bad (_(".unwind_save does not support this kind of register"));
@@ -4477,6 +4732,13 @@ const pseudo_typeS md_pseudo_table[] =
#ifdef TE_PE
{"secrel32", pe_directive_secrel, 0},
#endif
+
+ /* These are for compatibility with CodeComposer Studio. */
+ {"ref", s_ccs_ref, 0},
+ {"def", s_ccs_def, 0},
+ {"asmfunc", s_ccs_asmfunc, 0},
+ {"endasmfunc", s_ccs_endasmfunc, 0},
+
{ 0, 0, 0 }
};
@@ -4515,28 +4777,31 @@ parse_immediate (char **str, int *val, int min, int max,
instructions. Puts the result directly in inst.operands[i]. */
static int
-parse_big_immediate (char **str, int i)
+parse_big_immediate (char **str, int i, expressionS *in_exp,
+ bfd_boolean allow_symbol_p)
{
expressionS exp;
+ expressionS *exp_p = in_exp ? in_exp : &exp;
char *ptr = *str;
- my_get_expression (&exp, &ptr, GE_OPT_PREFIX_BIG);
+ my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
- if (exp.X_op == O_constant)
+ if (exp_p->X_op == O_constant)
{
- inst.operands[i].imm = exp.X_add_number & 0xffffffff;
+ inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
/* If we're on a 64-bit host, then a 64-bit number can be returned using
O_constant. We have to be careful not to break compilation for
32-bit X_add_number, though. */
- if ((exp.X_add_number & ~(offsetT)(0xffffffffU)) != 0)
+ if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
{
- /* X >> 32 is illegal if sizeof (exp.X_add_number) == 4. */
- inst.operands[i].reg = ((exp.X_add_number >> 16) >> 16) & 0xffffffff;
+ /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
+ inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
+ & 0xffffffff);
inst.operands[i].regisimm = 1;
}
}
- else if (exp.X_op == O_big
- && LITTLENUM_NUMBER_OF_BITS * exp.X_add_number > 32)
+ else if (exp_p->X_op == O_big
+ && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
{
unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
@@ -4549,7 +4814,7 @@ parse_big_immediate (char **str, int i)
PR 11972: Bignums can now be sign-extended to the
size of a .octa so check that the out of range bits
are all zero or all one. */
- if (LITTLENUM_NUMBER_OF_BITS * exp.X_add_number > 64)
+ if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
{
LITTLENUM_TYPE m = -1;
@@ -4557,7 +4822,7 @@ parse_big_immediate (char **str, int i)
&& generic_bignum[parts * 2] != m)
return FAIL;
- for (j = parts * 2 + 1; j < (unsigned) exp.X_add_number; j++)
+ for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
if (generic_bignum[j] != generic_bignum[j-1])
return FAIL;
}
@@ -4572,7 +4837,7 @@ parse_big_immediate (char **str, int i)
<< (LITTLENUM_NUMBER_OF_BITS * j);
inst.operands[i].regisimm = 1;
}
- else
+ else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
return FAIL;
*str = ptr;
@@ -4681,6 +4946,31 @@ is_quarter_float (unsigned imm)
return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
}
+
+/* Detect the presence of a floating point or integer zero constant,
+ i.e. #0.0 or #0. */
+
+static bfd_boolean
+parse_ifimm_zero (char **in)
+{
+ int error_code;
+
+ if (!is_immediate_prefix (**in))
+ return FALSE;
+
+ ++*in;
+ error_code = atof_generic (in, ".", EXP_CHARS,
+ &generic_floating_point_number);
+
+ if (!error_code
+ && generic_floating_point_number.sign == '+'
+ && (generic_floating_point_number.low
+ > generic_floating_point_number.leader))
+ return TRUE;
+
+ return FALSE;
+}
+
/* Parse an 8-bit "quarter-precision" floating point number of the form:
0baBbbbbbc defgh000 00000000 00000000.
The zero and minus-zero cases need special handling, since they can't be
@@ -5165,10 +5455,12 @@ parse_address_main (char **str, int i, int group_relocations,
inst.operands[i].reg = REG_PC;
inst.operands[i].isreg = 1;
inst.operands[i].preind = 1;
- }
- /* Otherwise a load-constant pseudo op, no special treatment needed here. */
- if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+ if (my_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX_BIG))
+ return PARSE_OPERAND_FAIL;
+ }
+ else if (parse_big_immediate (&p, i, &inst.reloc.exp,
+ /*allow_symbol_p=*/TRUE))
return PARSE_OPERAND_FAIL;
*str = p;
@@ -5998,7 +6290,8 @@ parse_neon_mov (char **str, int *which_operand)
Case 10: VMOV.F32 <Sd>, #<imm>
Case 11: VMOV.F64 <Dd>, #<imm> */
inst.operands[i].immisfloat = 1;
- else if (parse_big_immediate (&ptr, i) == SUCCESS)
+ else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/FALSE)
+ == SUCCESS)
/* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
;
@@ -6151,6 +6444,7 @@ enum operand_parse_code
OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
+ OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
OP_RR_RNSC, /* ARM reg or Neon scalar. */
OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
@@ -6434,6 +6728,22 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
break;
+ case OP_RSVD_FI0:
+ {
+ po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
+ break;
+ try_ifimm0:
+ if (parse_ifimm_zero (&str))
+ inst.operands[i].imm = 0;
+ else
+ {
+ inst.error
+ = _("only floating point zero is allowed as immediate value");
+ goto failure;
+ }
+ }
+ break;
+
case OP_RR_RNSC:
{
po_scalar_or_goto (8, try_rr);
@@ -6483,7 +6793,8 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
try_immbig:
/* There's a possibility of getting a 64-bit immediate here, so
we need special handling. */
- if (parse_big_immediate (&str, i) == FAIL)
+ if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
+ == FAIL)
{
inst.error = _("immediate value is out of range");
goto failure;
@@ -7224,71 +7535,204 @@ encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
}
}
-/* inst.operands[i] was set up by parse_address. Encode it into an
- ARM-format instruction. Reject all forms which cannot be encoded
- into a coprocessor load/store instruction. If wb_ok is false,
- reject use of writeback; if unind_ok is false, reject use of
- unindexed addressing. If reloc_override is not 0, use it instead
- of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
- (in which case it is preserved). */
+/* Write immediate bits [7:0] to the following locations:
+
+ |28/24|23 19|18 16|15 4|3 0|
+ | a |x x x x x|b c d|x x x x x x x x x x x x|e f g h|
+
+ This function is used by VMOV/VMVN/VORR/VBIC. */
+
+static void
+neon_write_immbits (unsigned immbits)
+{
+ inst.instruction |= immbits & 0xf;
+ inst.instruction |= ((immbits >> 4) & 0x7) << 16;
+ inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
+}
+
+/* Invert low-order SIZE bits of XHI:XLO. */
+
+static void
+neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
+{
+ unsigned immlo = xlo ? *xlo : 0;
+ unsigned immhi = xhi ? *xhi : 0;
+
+ switch (size)
+ {
+ case 8:
+ immlo = (~immlo) & 0xff;
+ break;
+
+ case 16:
+ immlo = (~immlo) & 0xffff;
+ break;
+
+ case 64:
+ immhi = (~immhi) & 0xffffffff;
+ /* fall through. */
+
+ case 32:
+ immlo = (~immlo) & 0xffffffff;
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (xlo)
+ *xlo = immlo;
+
+ if (xhi)
+ *xhi = immhi;
+}
+
+/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
+ A, B, C, D. */
static int
-encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
+neon_bits_same_in_bytes (unsigned imm)
{
- inst.instruction |= inst.operands[i].reg << 16;
+ return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
+ && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
+ && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
+ && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
+}
- gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
+/* For immediate of above form, return 0bABCD. */
- if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
+static unsigned
+neon_squash_bits (unsigned imm)
+{
+ return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
+ | ((imm & 0x01000000) >> 21);
+}
+
+/* Compress quarter-float representation to 0b...000 abcdefgh. */
+
+static unsigned
+neon_qfloat_bits (unsigned imm)
+{
+ return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
+}
+
+/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
+ the instruction. *OP is passed as the initial value of the op field, and
+ may be set to a different value depending on the constant (i.e.
+ "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
+ MVN). If the immediate looks like a repeated pattern then also
+ try smaller element sizes. */
+
+static int
+neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
+ unsigned *immbits, int *op, int size,
+ enum neon_el_type type)
+{
+ /* Only permit float immediates (including 0.0/-0.0) if the operand type is
+ float. */
+ if (type == NT_float && !float_p)
+ return FAIL;
+
+ if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
{
- gas_assert (!inst.operands[i].writeback);
- if (!unind_ok)
+ if (size != 32 || *op == 1)
+ return FAIL;
+ *immbits = neon_qfloat_bits (immlo);
+ return 0xf;
+ }
+
+ if (size == 64)
+ {
+ if (neon_bits_same_in_bytes (immhi)
+ && neon_bits_same_in_bytes (immlo))
{
- inst.error = _("instruction does not support unindexed addressing");
- return FAIL;
+ if (*op == 1)
+ return FAIL;
+ *immbits = (neon_squash_bits (immhi) << 4)
+ | neon_squash_bits (immlo);
+ *op = 1;
+ return 0xe;
}
- inst.instruction |= inst.operands[i].imm;
- inst.instruction |= INDEX_UP;
- return SUCCESS;
- }
- if (inst.operands[i].preind)
- inst.instruction |= PRE_INDEX;
+ if (immhi != immlo)
+ return FAIL;
+ }
- if (inst.operands[i].writeback)
+ if (size >= 32)
{
- if (inst.operands[i].reg == REG_PC)
+ if (immlo == (immlo & 0x000000ff))
{
- inst.error = _("pc may not be used with write-back");
- return FAIL;
+ *immbits = immlo;
+ return 0x0;
}
- if (!wb_ok)
+ else if (immlo == (immlo & 0x0000ff00))
{
- inst.error = _("instruction does not support writeback");
- return FAIL;
+ *immbits = immlo >> 8;
+ return 0x2;
}
- inst.instruction |= WRITE_BACK;
+ else if (immlo == (immlo & 0x00ff0000))
+ {
+ *immbits = immlo >> 16;
+ return 0x4;
+ }
+ else if (immlo == (immlo & 0xff000000))
+ {
+ *immbits = immlo >> 24;
+ return 0x6;
+ }
+ else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
+ {
+ *immbits = (immlo >> 8) & 0xff;
+ return 0xc;
+ }
+ else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
+ {
+ *immbits = (immlo >> 16) & 0xff;
+ return 0xd;
+ }
+
+ if ((immlo & 0xffff) != (immlo >> 16))
+ return FAIL;
+ immlo &= 0xffff;
}
- if (reloc_override)
- inst.reloc.type = (bfd_reloc_code_real_type) reloc_override;
- else if ((inst.reloc.type < BFD_RELOC_ARM_ALU_PC_G0_NC
- || inst.reloc.type > BFD_RELOC_ARM_LDC_SB_G2)
- && inst.reloc.type != BFD_RELOC_ARM_LDR_PC_G0)
+ if (size >= 16)
{
- if (thumb_mode)
- inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
- else
- inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+ if (immlo == (immlo & 0x000000ff))
+ {
+ *immbits = immlo;
+ return 0x8;
+ }
+ else if (immlo == (immlo & 0x0000ff00))
+ {
+ *immbits = immlo >> 8;
+ return 0xa;
+ }
+
+ if ((immlo & 0xff) != (immlo >> 8))
+ return FAIL;
+ immlo &= 0xff;
}
- /* Prefer + for zero encoded value. */
- if (!inst.operands[i].negative)
- inst.instruction |= INDEX_UP;
+ if (immlo == (immlo & 0x000000ff))
+ {
+ /* Don't allow MVN with 8-bit immediate. */
+ if (*op == 1)
+ return FAIL;
+ *immbits = immlo;
+ return 0xe;
+ }
- return SUCCESS;
+ return FAIL;
}
+enum lit_type
+{
+ CONST_THUMB,
+ CONST_ARM,
+ CONST_VEC
+};
+
/* inst.reloc.exp describes an "=expr" load pseudo-operation.
Determine whether it can be performed with a move instruction; if
it can, convert inst.instruction to that move instruction and
@@ -7299,9 +7743,12 @@ encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
inst.operands[i] describes the destination register. */
static bfd_boolean
-move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
+move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
{
unsigned long tbit;
+ bfd_boolean thumb_p = (t == CONST_THUMB);
+ bfd_boolean arm_p = (t == CONST_ARM);
+ bfd_boolean vec64_p = (t == CONST_VEC) && !inst.operands[i].issingle;
if (thumb_p)
tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
@@ -7313,14 +7760,18 @@ move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
inst.error = _("invalid pseudo operation");
return TRUE;
}
- if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol)
+ if (inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_symbol
+ && inst.reloc.exp.X_op != O_big)
{
inst.error = _("constant expression expected");
return TRUE;
}
- if (inst.reloc.exp.X_op == O_constant)
+ if ((inst.reloc.exp.X_op == O_constant
+ || inst.reloc.exp.X_op == O_big)
+ && !inst.operands[i].issingle)
{
- if (thumb_p)
+ if (thumb_p && inst.reloc.exp.X_op == O_constant)
{
if (!unified_syntax && (inst.reloc.exp.X_add_number & ~0xFF) == 0)
{
@@ -7330,7 +7781,7 @@ move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
return TRUE;
}
}
- else
+ else if (arm_p && inst.reloc.exp.X_op == O_constant)
{
int value = encode_arm_immediate (inst.reloc.exp.X_add_number);
if (value != FAIL)
@@ -7352,13 +7803,48 @@ move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
return TRUE;
}
}
- }
+ else if (vec64_p)
+ {
+ int op = 0;
+ unsigned immbits = 0;
+ unsigned immlo = inst.operands[1].imm;
+ unsigned immhi = inst.operands[1].regisimm
+ ? inst.operands[1].reg
+ : inst.reloc.exp.X_unsigned
+ ? 0
+ : ((bfd_int64_t)((int) immlo)) >> 32;
+ int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
+ &op, 64, NT_invtype);
- if (add_to_lit_pool () == FAIL)
- {
- inst.error = _("literal pool insertion failed");
- return TRUE;
+ if (cmode == FAIL)
+ {
+ neon_invert_size (&immlo, &immhi, 64);
+ op = !op;
+ cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
+ &op, 64, NT_invtype);
+ }
+ if (cmode != FAIL)
+ {
+ inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
+ | (1 << 23)
+ | (cmode << 8)
+ | (op << 5)
+ | (1 << 4);
+ /* Fill other bits in vmov encoding for both thumb and arm. */
+ if (thumb_mode)
+ inst.instruction |= (0x7 << 29) | (0xF << 24);
+ else
+ inst.instruction |= (0xF << 28) | (0x1 << 25);
+ neon_write_immbits (immbits);
+ return TRUE;
+ }
+ }
}
+
+ if (add_to_lit_pool ((!inst.operands[i].isvec
+ || inst.operands[i].issingle) ? 4 : 8) == FAIL)
+ return TRUE;
+
inst.operands[1].reg = REG_PC;
inst.operands[1].isreg = 1;
inst.operands[1].preind = 1;
@@ -7371,6 +7857,78 @@ move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
return FALSE;
}
+/* inst.operands[i] was set up by parse_address. Encode it into an
+ ARM-format instruction. Reject all forms which cannot be encoded
+ into a coprocessor load/store instruction. If wb_ok is false,
+ reject use of writeback; if unind_ok is false, reject use of
+ unindexed addressing. If reloc_override is not 0, use it instead
+ of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
+ (in which case it is preserved). */
+
+static int
+encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
+{
+ if (!inst.operands[i].isreg)
+ {
+ gas_assert (inst.operands[0].isvec);
+ if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
+ return SUCCESS;
+ }
+
+ inst.instruction |= inst.operands[i].reg << 16;
+
+ gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
+
+ if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
+ {
+ gas_assert (!inst.operands[i].writeback);
+ if (!unind_ok)
+ {
+ inst.error = _("instruction does not support unindexed addressing");
+ return FAIL;
+ }
+ inst.instruction |= inst.operands[i].imm;
+ inst.instruction |= INDEX_UP;
+ return SUCCESS;
+ }
+
+ if (inst.operands[i].preind)
+ inst.instruction |= PRE_INDEX;
+
+ if (inst.operands[i].writeback)
+ {
+ if (inst.operands[i].reg == REG_PC)
+ {
+ inst.error = _("pc may not be used with write-back");
+ return FAIL;
+ }
+ if (!wb_ok)
+ {
+ inst.error = _("instruction does not support writeback");
+ return FAIL;
+ }
+ inst.instruction |= WRITE_BACK;
+ }
+
+ if (reloc_override)
+ inst.reloc.type = (bfd_reloc_code_real_type) reloc_override;
+ else if ((inst.reloc.type < BFD_RELOC_ARM_ALU_PC_G0_NC
+ || inst.reloc.type > BFD_RELOC_ARM_LDC_SB_G2)
+ && inst.reloc.type != BFD_RELOC_ARM_LDR_PC_G0)
+ {
+ if (thumb_mode)
+ inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
+ else
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+ }
+
+ /* Prefer + for zero encoded value. */
+ if (!inst.operands[i].negative)
+ inst.instruction |= INDEX_UP;
+
+ return SUCCESS;
+}
+
/* Functions for instruction encoding, sorted by sub-architecture.
First some generics; their names are taken from the conventional
bit positions for register arguments in ARM format instructions. */
@@ -8101,7 +8659,7 @@ do_ldst (void)
{
inst.instruction |= inst.operands[0].reg << 12;
if (!inst.operands[1].isreg)
- if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/FALSE))
+ if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
return;
encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
check_ldr_r15_aligned ();
@@ -8134,7 +8692,7 @@ do_ldstv4 (void)
constraint (inst.operands[0].reg == REG_PC, BAD_PC);
inst.instruction |= inst.operands[0].reg << 12;
if (!inst.operands[1].isreg)
- if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/TRUE))
+ if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
return;
encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
}
@@ -10678,7 +11236,7 @@ do_t_ldst (void)
{
if (opcode <= 0xffff)
inst.instruction = THUMB_OP32 (opcode);
- if (move_or_literal_pool (0, /*thumb_p=*/TRUE, /*mode_3=*/FALSE))
+ if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
return;
}
if (inst.operands[1].isreg
@@ -10784,7 +11342,7 @@ do_t_ldst (void)
inst.instruction = THUMB_OP16 (inst.instruction);
if (!inst.operands[1].isreg)
- if (move_or_literal_pool (0, /*thumb_p=*/TRUE, /*mode_3=*/FALSE))
+ if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
return;
constraint (!inst.operands[1].preind
@@ -11130,16 +11688,9 @@ do_t_mov_cmp (void)
results. Don't allow this. */
if (low_regs)
{
-/* Silence this error for now because clang generates "MOV" two low regs in
- unified syntax for thumb1, and expects CPSR are not affected. This check
- doesn't exist in binutils-2.21 with gcc 4.6. The thumb1 code generated by
- clang will continue to have problem running on v5t but not on v6 and beyond.
-*/
-#if 0
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
"MOV Rd, Rs with two low registers is not "
"permitted on this architecture");
-#endif
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
arm_ext_v6);
}
@@ -13672,197 +14223,6 @@ neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
return FAIL;
}
-/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
- A, B, C, D. */
-
-static int
-neon_bits_same_in_bytes (unsigned imm)
-{
- return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
- && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
- && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
- && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
-}
-
-/* For immediate of above form, return 0bABCD. */
-
-static unsigned
-neon_squash_bits (unsigned imm)
-{
- return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
- | ((imm & 0x01000000) >> 21);
-}
-
-/* Compress quarter-float representation to 0b...000 abcdefgh. */
-
-static unsigned
-neon_qfloat_bits (unsigned imm)
-{
- return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
-}
-
-/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
- the instruction. *OP is passed as the initial value of the op field, and
- may be set to a different value depending on the constant (i.e.
- "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
- MVN). If the immediate looks like a repeated pattern then also
- try smaller element sizes. */
-
-static int
-neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
- unsigned *immbits, int *op, int size,
- enum neon_el_type type)
-{
- /* Only permit float immediates (including 0.0/-0.0) if the operand type is
- float. */
- if (type == NT_float && !float_p)
- return FAIL;
-
- if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
- {
- if (size != 32 || *op == 1)
- return FAIL;
- *immbits = neon_qfloat_bits (immlo);
- return 0xf;
- }
-
- if (size == 64)
- {
- if (neon_bits_same_in_bytes (immhi)
- && neon_bits_same_in_bytes (immlo))
- {
- if (*op == 1)
- return FAIL;
- *immbits = (neon_squash_bits (immhi) << 4)
- | neon_squash_bits (immlo);
- *op = 1;
- return 0xe;
- }
-
- if (immhi != immlo)
- return FAIL;
- }
-
- if (size >= 32)
- {
- if (immlo == (immlo & 0x000000ff))
- {
- *immbits = immlo;
- return 0x0;
- }
- else if (immlo == (immlo & 0x0000ff00))
- {
- *immbits = immlo >> 8;
- return 0x2;
- }
- else if (immlo == (immlo & 0x00ff0000))
- {
- *immbits = immlo >> 16;
- return 0x4;
- }
- else if (immlo == (immlo & 0xff000000))
- {
- *immbits = immlo >> 24;
- return 0x6;
- }
- else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
- {
- *immbits = (immlo >> 8) & 0xff;
- return 0xc;
- }
- else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
- {
- *immbits = (immlo >> 16) & 0xff;
- return 0xd;
- }
-
- if ((immlo & 0xffff) != (immlo >> 16))
- return FAIL;
- immlo &= 0xffff;
- }
-
- if (size >= 16)
- {
- if (immlo == (immlo & 0x000000ff))
- {
- *immbits = immlo;
- return 0x8;
- }
- else if (immlo == (immlo & 0x0000ff00))
- {
- *immbits = immlo >> 8;
- return 0xa;
- }
-
- if ((immlo & 0xff) != (immlo >> 8))
- return FAIL;
- immlo &= 0xff;
- }
-
- if (immlo == (immlo & 0x000000ff))
- {
- /* Don't allow MVN with 8-bit immediate. */
- if (*op == 1)
- return FAIL;
- *immbits = immlo;
- return 0xe;
- }
-
- return FAIL;
-}
-
-/* Write immediate bits [7:0] to the following locations:
-
- |28/24|23 19|18 16|15 4|3 0|
- | a |x x x x x|b c d|x x x x x x x x x x x x|e f g h|
-
- This function is used by VMOV/VMVN/VORR/VBIC. */
-
-static void
-neon_write_immbits (unsigned immbits)
-{
- inst.instruction |= immbits & 0xf;
- inst.instruction |= ((immbits >> 4) & 0x7) << 16;
- inst.instruction |= ((immbits >> 7) & 0x1) << 24;
-}
-
-/* Invert low-order SIZE bits of XHI:XLO. */
-
-static void
-neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
-{
- unsigned immlo = xlo ? *xlo : 0;
- unsigned immhi = xhi ? *xhi : 0;
-
- switch (size)
- {
- case 8:
- immlo = (~immlo) & 0xff;
- break;
-
- case 16:
- immlo = (~immlo) & 0xffff;
- break;
-
- case 64:
- immhi = (~immhi) & 0xffffffff;
- /* fall through. */
-
- case 32:
- immlo = (~immlo) & 0xffffffff;
- break;
-
- default:
- abort ();
- }
-
- if (xlo)
- *xlo = immlo;
-
- if (xhi)
- *xhi = immhi;
-}
-
static void
do_neon_logic (void)
{
@@ -14678,7 +15038,7 @@ do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
{
case neon_cvt_flavour_s32_f64:
sz = 1;
- op = 0;
+ op = 1;
break;
case neon_cvt_flavour_s32_f32:
sz = 0;
@@ -17119,6 +17479,9 @@ static const struct depr_insn_mask depr_it_insns[] = {
{ 0x4800, 0xf800, N_("Literal loads") },
{ 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
{ 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
+ /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
+ field in asm_opcode. 'tvalue' is used at the stage this check happen. */
+ { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
{ 0, 0, NULL }
};
@@ -19224,8 +19587,8 @@ static const struct asm_opcode insns[] =
nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
- nCE(vcmp, _vcmp, 2, (RVSD, RVSD_I0), vfp_nsyn_cmp),
- nCE(vcmpe, _vcmpe, 2, (RVSD, RVSD_I0), vfp_nsyn_cmp),
+ nCE(vcmp, _vcmp, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
+ nCE(vcmpe, _vcmpe, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
@@ -20485,7 +20848,8 @@ arm_handle_align (fragS * fragP)
if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
{
- if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
+ if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
+ ? selected_cpu : arm_arch_none, arm_ext_v6t2))
{
narrow_noop = thumb_noop[1][target_big_endian];
noop = wide_thumb_noop[target_big_endian];
@@ -20499,7 +20863,9 @@ arm_handle_align (fragS * fragP)
}
else
{
- noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k) != 0]
+ noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
+ ? selected_cpu : arm_arch_none,
+ arm_ext_v6k) != 0]
[target_big_endian];
noop_size = 4;
#ifdef OBJ_ELF
@@ -20848,7 +21214,7 @@ start_unwind_section (const segT text_seg, int idx)
/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
personality routine data. Returns zero, or the index table value for
- and inline entry. */
+ an inline entry. */
static valueT
create_unwind_entry (int have_data)
@@ -20919,7 +21285,12 @@ create_unwind_entry (int have_data)
}
else
{
- gas_assert (unwind.personality_index == -1);
+ /* PR 16765: Missing or misplaced unwind directives can trigger this. */
+ if (unwind.personality_index != -1)
+ {
+ as_bad (_("attempt to recreate an unwind entry"));
+ return 1;
+ }
/* An extra byte is required for the opcode count. */
size = unwind.opcode_count + 1;
@@ -21026,11 +21397,19 @@ int
tc_arm_regname_to_dw2regnum (char *regname)
{
int reg = arm_reg_parse (&regname, REG_TYPE_RN);
+ if (reg != FAIL)
+ return reg;
- if (reg == FAIL)
- return -1;
+ /* PR 16694: Allow VFP registers as well. */
+ reg = arm_reg_parse (&regname, REG_TYPE_VFS);
+ if (reg != FAIL)
+ return 64 + reg;
- return reg;
+ reg = arm_reg_parse (&regname, REG_TYPE_VFD);
+ if (reg != FAIL)
+ return reg + 256;
+
+ return -1;
}
#ifdef TE_PE
@@ -22225,7 +22604,7 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_8:
if (fixP->fx_done || !seg->use_rela_p)
- md_number_to_chars (buf, value, 1);
+ *buf = value;
break;
case BFD_RELOC_16:
@@ -22238,9 +22617,6 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_ARM_THM_TLS_CALL:
case BFD_RELOC_ARM_TLS_DESCSEQ:
case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
- S_SET_THREAD_LOCAL (fixP->fx_addsy);
- break;
-
case BFD_RELOC_ARM_TLS_GOTDESC:
case BFD_RELOC_ARM_TLS_GD32:
case BFD_RELOC_ARM_TLS_LE32:
@@ -22248,12 +22624,10 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_ARM_TLS_LDM32:
case BFD_RELOC_ARM_TLS_LDO32:
S_SET_THREAD_LOCAL (fixP->fx_addsy);
- /* fall through */
+ break;
case BFD_RELOC_ARM_GOT32:
case BFD_RELOC_ARM_GOTOFF:
- if (fixP->fx_done || !seg->use_rela_p)
- md_number_to_chars (buf, 0, 4);
break;
case BFD_RELOC_ARM_GOT_PREL:
@@ -23002,9 +23376,9 @@ void
cons_fix_new_arm (fragS * frag,
int where,
int size,
- expressionS * exp)
+ expressionS * exp,
+ bfd_reloc_code_real_type reloc)
{
- bfd_reloc_code_real_type type;
int pcrel = 0;
/* Pick a reloc.
@@ -23012,17 +23386,17 @@ cons_fix_new_arm (fragS * frag,
switch (size)
{
case 1:
- type = BFD_RELOC_8;
+ reloc = BFD_RELOC_8;
break;
case 2:
- type = BFD_RELOC_16;
+ reloc = BFD_RELOC_16;
break;
case 4:
default:
- type = BFD_RELOC_32;
+ reloc = BFD_RELOC_32;
break;
case 8:
- type = BFD_RELOC_64;
+ reloc = BFD_RELOC_64;
break;
}
@@ -23030,11 +23404,11 @@ cons_fix_new_arm (fragS * frag,
if (exp->X_op == O_secrel)
{
exp->X_op = O_symbol;
- type = BFD_RELOC_32_SECREL;
+ reloc = BFD_RELOC_32_SECREL;
}
#endif
- fix_new_exp (frag, where, (int) size, exp, pcrel, type);
+ fix_new_exp (frag, where, size, exp, pcrel, reloc);
}
#if defined (OBJ_COFF)
@@ -24004,8 +24378,7 @@ static const struct arm_cpu_option_table arm_cpus[] =
ARM_CPU_OPT ("arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL),
ARM_CPU_OPT ("cortex-a5", ARM_ARCH_V7A_MP_SEC,
FPU_NONE, "Cortex-A5"),
- ARM_CPU_OPT ("cortex-a7", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
- FPU_ARCH_NEON_VFP_V4,
+ ARM_CPU_OPT ("cortex-a7", ARM_ARCH_V7VE, FPU_ARCH_NEON_VFP_V4,
"Cortex-A7"),
ARM_CPU_OPT ("cortex-a8", ARM_ARCH_V7A_SEC,
ARM_FEATURE (0, FPU_VFP_V3
@@ -24015,12 +24388,12 @@ static const struct arm_cpu_option_table arm_cpus[] =
ARM_FEATURE (0, FPU_VFP_V3
| FPU_NEON_EXT_V1),
"Cortex-A9"),
- ARM_CPU_OPT ("cortex-a12", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
- FPU_ARCH_NEON_VFP_V4,
+ ARM_CPU_OPT ("cortex-a12", ARM_ARCH_V7VE, FPU_ARCH_NEON_VFP_V4,
"Cortex-A12"),
- ARM_CPU_OPT ("cortex-a15", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
- FPU_ARCH_NEON_VFP_V4,
+ ARM_CPU_OPT ("cortex-a15", ARM_ARCH_V7VE, FPU_ARCH_NEON_VFP_V4,
"Cortex-A15"),
+ ARM_CPU_OPT ("cortex-a17", ARM_ARCH_V7VE, FPU_ARCH_NEON_VFP_V4,
+ "Cortex-A17"),
ARM_CPU_OPT ("cortex-a53", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Cortex-A53"),
ARM_CPU_OPT ("cortex-a57", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
@@ -24100,6 +24473,7 @@ static const struct arm_arch_option_table arm_archs[] =
/* The official spelling of the ARMv7 profile variants is the dashed form.
Accept the non-dashed form for compatibility with old toolchains. */
ARM_ARCH_OPT ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP),
+ ARM_ARCH_OPT ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP),
@@ -24515,6 +24889,15 @@ arm_parse_it_mode (char * str)
return ret;
}
+static bfd_boolean
+arm_ccs_mode (char * unused ATTRIBUTE_UNUSED)
+{
+ codecomposer_syntax = TRUE;
+ arm_comment_chars[0] = ';';
+ arm_line_separator_chars[0] = 0;
+ return TRUE;
+}
+
struct arm_long_option_table arm_long_opts[] =
{
{"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
@@ -24531,6 +24914,8 @@ struct arm_long_option_table arm_long_opts[] =
#endif
{"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
arm_parse_it_mode, NULL},
+ {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
+ arm_ccs_mode, NULL},
{NULL, NULL, 0, NULL}
};
@@ -24679,7 +25064,7 @@ static const cpu_arch_ver_table cpu_arch_ver[] =
{11, ARM_ARCH_V6M},
{12, ARM_ARCH_V6SM},
{8, ARM_ARCH_V6T2},
- {10, ARM_ARCH_V7A_IDIV_MP_SEC_VIRT},
+ {10, ARM_ARCH_V7VE},
{10, ARM_ARCH_V7R},
{10, ARM_ARCH_V7M},
{14, ARM_ARCH_V8A},
@@ -24729,6 +25114,8 @@ aeabi_set_public_attributes (void)
if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
+ selected_cpu = flags;
+
/* Allow the user to override the reported architecture. */
if (object_arch)
{
diff --git a/binutils-2.25/gas/config/tc-arm.h b/binutils-2.25/gas/config/tc-arm.h
index 3a0fab03..a7a0cd0d 100644
--- a/binutils-2.25/gas/config/tc-arm.h
+++ b/binutils-2.25/gas/config/tc-arm.h
@@ -1,6 +1,5 @@
/* This file is tc-arm.h
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
Modified by David Taylor (dtaylor@armltd.co.uk)
@@ -82,6 +81,10 @@ struct fix;
/* We support double slash line-comments for compatibility with the ARM AArch64 Assembler. */
#define DOUBLESLASH_LINE_COMMENTS
+/* We conditionally support labels without a colon. */
+#define LABELS_WITHOUT_COLONS codecomposer_syntax
+extern bfd_boolean codecomposer_syntax;
+
#define tc_symbol_chars arm_symbol_chars
extern const char arm_symbol_chars[];
@@ -101,6 +104,9 @@ extern int arm_optimize_expr (expressionS *, operatorT, expressionS *);
#define md_start_line_hook() arm_start_line_hook ()
+#define TC_START_LABEL_WITHOUT_COLON(c, l) tc_start_label_without_colon (c, l)
+extern bfd_boolean tc_start_label_without_colon (char, const char *);
+
#define tc_frob_label(S) arm_frob_label (S)
/* We also need to mark assembler created symbols: */
@@ -342,7 +348,8 @@ extern int arm_data_in_code (void);
extern char * arm_canonicalize_symbol_name (char *);
extern void arm_adjust_symtab (void);
extern void armelf_frob_symbol (symbolS *, int *);
-extern void cons_fix_new_arm (fragS *, int, int, expressionS *);
+extern void cons_fix_new_arm (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
extern void arm_init_frag (struct frag *, int);
extern void arm_handle_align (struct frag *);
extern bfd_boolean arm_fix_adjustable (struct fix *);
@@ -364,3 +371,9 @@ void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
extern int arm_convert_symbolic_attribute (const char *);
extern int arm_apply_sym_value (struct fix *);
#endif
+
+#define tc_comment_chars arm_comment_chars
+extern char arm_comment_chars[];
+
+#define tc_line_separator_chars arm_line_separator_chars
+extern char arm_line_separator_chars[];
diff --git a/binutils-2.25/gas/config/tc-avr.c b/binutils-2.25/gas/config/tc-avr.c
index 332aa2dc..dfe66c68 100644
--- a/binutils-2.25/gas/config/tc-avr.c
+++ b/binutils-2.25/gas/config/tc-avr.c
@@ -1,6 +1,6 @@
/* tc-avr.c -- Assembler code for the ATMEL AVR
- Copyright 1999-2013 Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of GAS, the GNU Assembler.
@@ -89,6 +89,7 @@ static struct mcu_type_s mcu_types[] =
{"avrxmega5", AVR_ISA_XMEGA, bfd_mach_avrxmega5},
{"avrxmega6", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
{"avrxmega7", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
+ {"avrtiny", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
{"at90s1200", AVR_ISA_1200, bfd_mach_avr1},
{"attiny11", AVR_ISA_AVR1, bfd_mach_avr1},
{"attiny12", AVR_ISA_AVR1, bfd_mach_avr1},
@@ -106,6 +107,7 @@ static struct mcu_type_s mcu_types[] =
{"at90s8515", AVR_ISA_AVR2, bfd_mach_avr2},
{"at90c8534", AVR_ISA_AVR2, bfd_mach_avr2},
{"at90s8535", AVR_ISA_AVR2, bfd_mach_avr2},
+ {"ata5272", AVR_ISA_AVR25, bfd_mach_avr25},
{"attiny13", AVR_ISA_AVR25, bfd_mach_avr25},
{"attiny13a", AVR_ISA_AVR25, bfd_mach_avr25},
{"attiny2313", AVR_ISA_AVR25, bfd_mach_avr25},
@@ -130,6 +132,7 @@ static struct mcu_type_s mcu_types[] =
{"attiny43u", AVR_ISA_AVR25, bfd_mach_avr25},
{"attiny48", AVR_ISA_AVR25, bfd_mach_avr25},
{"attiny88", AVR_ISA_AVR25, bfd_mach_avr25},
+ {"attiny828", AVR_ISA_AVR25, bfd_mach_avr25},
{"at86rf401", AVR_ISA_RF401, bfd_mach_avr25},
{"at43usb355", AVR_ISA_AVR3, bfd_mach_avr3},
{"at76c711", AVR_ISA_AVR3, bfd_mach_avr3},
@@ -138,13 +141,19 @@ static struct mcu_type_s mcu_types[] =
{"attiny167", AVR_ISA_AVR35, bfd_mach_avr35},
{"at90usb82", AVR_ISA_AVR35, bfd_mach_avr35},
{"at90usb162", AVR_ISA_AVR35, bfd_mach_avr35},
+ {"ata5505", AVR_ISA_AVR35, bfd_mach_avr35},
{"atmega8u2", AVR_ISA_AVR35, bfd_mach_avr35},
{"atmega16u2", AVR_ISA_AVR35, bfd_mach_avr35},
{"atmega32u2", AVR_ISA_AVR35, bfd_mach_avr35},
+ {"attiny1634", AVR_ISA_AVR35, bfd_mach_avr35},
{"atmega8", AVR_ISA_M8, bfd_mach_avr4},
{"ata6289", AVR_ISA_AVR4, bfd_mach_avr4},
+ {"atmega8a", AVR_ISA_M8, bfd_mach_avr4},
+ {"ata6285", AVR_ISA_AVR4, bfd_mach_avr4},
+ {"ata6286", AVR_ISA_AVR4, bfd_mach_avr4},
{"atmega48", AVR_ISA_AVR4, bfd_mach_avr4},
{"atmega48a", AVR_ISA_AVR4, bfd_mach_avr4},
+ {"atmega48pa", AVR_ISA_AVR4, bfd_mach_avr4},
{"atmega48p", AVR_ISA_AVR4, bfd_mach_avr4},
{"atmega88", AVR_ISA_AVR4, bfd_mach_avr4},
{"atmega88a", AVR_ISA_AVR4, bfd_mach_avr4},
@@ -159,6 +168,9 @@ static struct mcu_type_s mcu_types[] =
{"at90pwm3", AVR_ISA_AVR4, bfd_mach_avr4},
{"at90pwm3b", AVR_ISA_AVR4, bfd_mach_avr4},
{"at90pwm81", AVR_ISA_AVR4, bfd_mach_avr4},
+ {"at90pwm161", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"ata5790", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"ata5795", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega16", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega16a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega161", AVR_ISA_M161, bfd_mach_avr5},
@@ -166,17 +178,21 @@ static struct mcu_type_s mcu_types[] =
{"atmega163", AVR_ISA_M161, bfd_mach_avr5},
{"atmega164a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega164p", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega164pa",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega165", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega165a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega165p", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega165pa",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega168", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega168a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega168p", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega168pa",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega169", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega169a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega169p", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega169pa",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega32", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega32a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega323", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega324a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega324p", AVR_ISA_AVR5, bfd_mach_avr5},
@@ -200,7 +216,10 @@ static struct mcu_type_s mcu_types[] =
{"atmega3290p",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega3290pa",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega406", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega64rfr2", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega644rfr2",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega64", AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega64a", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega640", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega644", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega644a", AVR_ISA_AVR5, bfd_mach_avr5},
@@ -221,7 +240,7 @@ static struct mcu_type_s mcu_types[] =
{"atmega64rfr2",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega644rfr2",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5},
- {"atmega16hva2",AVR_ISA_AVR5, bfd_mach_avr5},
+ {"atmega16hva2",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega16hvbrevb",AVR_ISA_AVR5,bfd_mach_avr5},
{"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5},
@@ -246,8 +265,10 @@ static struct mcu_type_s mcu_types[] =
{"at94k", AVR_ISA_94K, bfd_mach_avr5},
{"m3000", AVR_ISA_AVR5, bfd_mach_avr5},
{"atmega128", AVR_ISA_AVR51, bfd_mach_avr51},
+ {"atmega128a", AVR_ISA_AVR51, bfd_mach_avr51},
{"atmega1280", AVR_ISA_AVR51, bfd_mach_avr51},
{"atmega1281", AVR_ISA_AVR51, bfd_mach_avr51},
+ {"atmega1284", AVR_ISA_AVR51, bfd_mach_avr51},
{"atmega1284p",AVR_ISA_AVR51, bfd_mach_avr51},
{"atmega128rfa1",AVR_ISA_AVR51, bfd_mach_avr51},
{"atmega128rfr2",AVR_ISA_AVR51, bfd_mach_avr51},
@@ -260,31 +281,62 @@ static struct mcu_type_s mcu_types[] =
{"atmega256rfr2", AVR_ISA_AVR6, bfd_mach_avr6},
{"atmega2564rfr2", AVR_ISA_AVR6, bfd_mach_avr6},
{"atxmega16a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
+ {"atxmega16a4u",AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
+ {"atxmega16c4", AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
{"atxmega16d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
- {"atxmega16x1", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
{"atxmega32a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
+ {"atxmega32a4u",AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
+ {"atxmega32c4", AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
{"atxmega32d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
+ {"atxmega32e5", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
+ {"atxmega16e5", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
+ {"atxmega8e5", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
{"atxmega32x1", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
{"atxmega64a3", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
+ {"atxmega64a3u",AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
+ {"atxmega64a4u",AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
+ {"atxmega64b1", AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
+ {"atxmega64b3", AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
+ {"atxmega64c3", AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
{"atxmega64d3", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
+ {"atxmega64d4", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
{"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5},
{"atxmega64a1u",AVR_ISA_XMEGAU, bfd_mach_avrxmega5},
{"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+ {"atxmega128a3u",AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
{"atxmega128b1", AVR_ISA_XMEGAU, bfd_mach_avrxmega6},
+ {"atxmega128b3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
+ {"atxmega128c3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
{"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+ {"atxmega128d4", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
{"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+ {"atxmega192a3u",AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
+ {"atxmega192c3", AVR_ISA_XMEGAU, bfd_mach_avrxmega6},
{"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
{"atxmega256a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+ {"atxmega256a3u",AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
{"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6},
{"atxmega256a3bu",AVR_ISA_XMEGAU, bfd_mach_avrxmega6},
+ {"atxmega256c3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
{"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+ {"atxmega384c3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
+ {"atxmega384d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
{"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
{"atxmega128a1u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
+ {"atxmega128a4u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
+ {"attiny4", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+ {"attiny5", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+ {"attiny9", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+ {"attiny10", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+ {"attiny20", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+ {"attiny40", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
{NULL, 0, 0}
};
+
/* Current MCU type. */
static struct mcu_type_s default_mcu = {"avr2", AVR_ISA_AVR2, bfd_mach_avr2};
+static struct mcu_type_s specified_mcu;
static struct mcu_type_s * avr_mcu = & default_mcu;
/* AVR target-specific switches. */
@@ -293,9 +345,11 @@ struct avr_opt_s
int all_opcodes; /* -mall-opcodes: accept all known AVR opcodes. */
int no_skip_bug; /* -mno-skip-bug: no warnings for skipping 2-word insns. */
int no_wrap; /* -mno-wrap: reject rjmp/rcall with 8K wrap-around. */
+ int link_relax; /* -mlink-relax: generate relocations for linker
+ relaxation. */
};
-static struct avr_opt_s avr_opt = { 0, 0, 0 };
+static struct avr_opt_s avr_opt = { 0, 0, 0, 0 };
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";
@@ -355,7 +409,9 @@ enum options
{
OPTION_ALL_OPCODES = OPTION_MD_BASE + 1,
OPTION_NO_SKIP_BUG,
- OPTION_NO_WRAP
+ OPTION_NO_WRAP,
+ OPTION_ISA_RMW,
+ OPTION_LINK_RELAX
};
struct option md_longopts[] =
@@ -364,6 +420,8 @@ struct option md_longopts[] =
{ "mall-opcodes", no_argument, NULL, OPTION_ALL_OPCODES },
{ "mno-skip-bug", no_argument, NULL, OPTION_NO_SKIP_BUG },
{ "mno-wrap", no_argument, NULL, OPTION_NO_WRAP },
+ { "mrmw", no_argument, NULL, OPTION_ISA_RMW },
+ { "mlink-relax", no_argument, NULL, OPTION_LINK_RELAX },
{ NULL, no_argument, NULL, 0 }
};
@@ -462,13 +520,16 @@ md_show_usage (FILE *stream)
" avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n"
" avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n"
" avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n"
- " or immediate microcontroller name.\n"));
+ " avrtiny - AVR Tiny core with 16 gp registers\n"));
fprintf (stream,
_(" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n"
" -mno-skip-bug disable warnings for skipping two-word instructions\n"
" (default for avr4, avr5)\n"
" -mno-wrap reject rjmp/rcall instructions with 8K wrap-around\n"
- " (default for avr3, avr5)\n"));
+ " (default for avr3, avr5)\n"
+ " -mrmw accept Read-Modify-Write instructions\n"
+ " -mlink-relax generate relocations for linker relaxation\n"
+ ));
show_mcu_list (stream);
}
@@ -515,7 +576,12 @@ md_parse_option (int c, char *arg)
type - this for allows passing -mmcu=... via gcc ASM_SPEC as well
as .arch ... in the asm output at the same time. */
if (avr_mcu == &default_mcu || avr_mcu->mach == mcu_types[i].mach)
- avr_mcu = &mcu_types[i];
+ {
+ specified_mcu.name = mcu_types[i].name;
+ specified_mcu.isa |= mcu_types[i].isa;
+ specified_mcu.mach = mcu_types[i].mach;
+ avr_mcu = &specified_mcu;
+ }
else
as_fatal (_("redefinition of mcu type `%s' to `%s'"),
avr_mcu->name, mcu_types[i].name);
@@ -530,6 +596,12 @@ md_parse_option (int c, char *arg)
case OPTION_NO_WRAP:
avr_opt.no_wrap = 1;
return 1;
+ case OPTION_ISA_RMW:
+ specified_mcu.isa |= AVR_ISA_RMW;
+ return 1;
+ case OPTION_LINK_RELAX:
+ avr_opt.link_relax = 1;
+ return 1;
}
return 0;
@@ -580,6 +652,7 @@ md_begin (void)
}
bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
+ linkrelax = avr_opt.link_relax;
}
/* Resolve STR as a constant expression and return the result.
@@ -788,30 +861,55 @@ avr_operand (struct avr_opcodes_s *opcode,
case 'r':
case 'a':
case 'v':
- if (*str == 'r' || *str == 'R')
- {
- char r_name[20];
+ {
+ char * old_str = str;
+ char *lower;
+ char r_name[20];
- str = extract_word (str, r_name, sizeof (r_name));
- op_mask = 0xff;
- if (ISDIGIT (r_name[1]))
- {
- if (r_name[2] == '\0')
- op_mask = r_name[1] - '0';
- else if (r_name[1] != '0'
- && ISDIGIT (r_name[2])
- && r_name[3] == '\0')
- op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
- }
- }
- else
- {
- op_mask = avr_get_constant (str, 31);
- str = input_line_pointer;
- }
+ str = extract_word (str, r_name, sizeof (r_name));
+ for (lower = r_name; *lower; ++lower)
+ {
+ if (*lower >= 'A' && *lower <= 'Z')
+ *lower += 'a' - 'A';
+ }
+
+ if (r_name[0] == 'r' && ISDIGIT (r_name[1]) && r_name[2] == 0)
+ /* Single-digit register number, ie r0-r9. */
+ op_mask = r_name[1] - '0';
+ else if (r_name[0] == 'r' && ISDIGIT (r_name[1])
+ && ISDIGIT (r_name[2]) && r_name[3] == 0)
+ /* Double-digit register number, ie r10 - r32. */
+ op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
+ else if (r_name[0] >= 'x' && r_name[0] <= 'z'
+ && (r_name[1] == 'l' || r_name[1] == 'h') && r_name[2] == 0)
+ /* Registers r26-r31 referred to by name, ie xl, xh, yl, yh, zl, zh. */
+ op_mask = (r_name[0] - 'x') * 2 + (r_name[1] == 'h') + 26;
+ else if ((*op == 'v' || *op == 'w')
+ && r_name[0] >= 'x' && r_name[0] <= 'z' && r_name[1] == 0)
+ /* For the movw and addiw instructions, refer to registers x, y and z by name. */
+ op_mask = (r_name[0] - 'x') * 2 + 26;
+ else
+ {
+ /* Numeric or symbolic constant register number. */
+ op_mask = avr_get_constant (old_str, 31);
+ str = input_line_pointer;
+ }
+ }
+
+ if (avr_mcu->mach == bfd_mach_avrtiny)
+ {
+ if (op_mask < 16 || op_mask > 31)
+ {
+ as_bad (_("register name or number from 16 to 31 required"));
+ break;
+ }
+ }
+ else if (op_mask > 31)
+ {
+ as_bad (_("register name or number from 0 to 31 required"));
+ break;
+ }
- if (op_mask <= 31)
- {
switch (*op)
{
case 'a':
@@ -839,9 +937,6 @@ avr_operand (struct avr_opcodes_s *opcode,
break;
}
break;
- }
- as_bad (_("register name or number from 0 to 31 required"));
- break;
case 'e':
{
@@ -948,6 +1043,12 @@ avr_operand (struct avr_opcodes_s *opcode,
&op_expr, FALSE, BFD_RELOC_16);
break;
+ case 'j':
+ str = parse_exp (str, &op_expr);
+ fix_new_exp (frag_now, where, opcode->insn_size * 2,
+ &op_expr, FALSE, BFD_RELOC_AVR_LDS_STS_16);
+ break;
+
case 'M':
{
bfd_reloc_code_real_type r_type;
@@ -992,23 +1093,15 @@ avr_operand (struct avr_opcodes_s *opcode,
break;
case 'P':
- {
- unsigned int x;
-
- x = avr_get_constant (str, 63);
- str = input_line_pointer;
- op_mask |= (x & 0xf) | ((x & 0x30) << 5);
- }
+ str = parse_exp (str, &op_expr);
+ fix_new_exp (frag_now, where, opcode->insn_size * 2,
+ &op_expr, FALSE, BFD_RELOC_AVR_PORT6);
break;
case 'p':
- {
- unsigned int x;
-
- x = avr_get_constant (str, 31);
- str = input_line_pointer;
- op_mask |= x << 3;
- }
+ str = parse_exp (str, &op_expr);
+ fix_new_exp (frag_now, where, opcode->insn_size * 2,
+ &op_expr, FALSE, BFD_RELOC_AVR_PORT5);
break;
case 'E':
@@ -1143,6 +1236,53 @@ md_pcrel_from_section (fixS *fixp, segT sec)
return fixp->fx_frag->fr_address + fixp->fx_where;
}
+static bfd_boolean
+relaxable_section (asection *sec)
+{
+ return (sec->flags & SEC_DEBUGGING) == 0;
+}
+
+/* Does whatever the xtensa port does. */
+int
+avr_validate_fix_sub (fixS *fix)
+{
+ segT add_symbol_segment, sub_symbol_segment;
+
+ /* The difference of two symbols should be resolved by the assembler when
+ linkrelax is not set. If the linker may relax the section containing
+ the symbols, then an Xtensa DIFF relocation must be generated so that
+ the linker knows to adjust the difference value. */
+ if (!linkrelax || fix->fx_addsy == NULL)
+ return 0;
+
+ /* Make sure both symbols are in the same segment, and that segment is
+ "normal" and relaxable. If the segment is not "normal", then the
+ fix is not valid. If the segment is not "relaxable", then the fix
+ should have been handled earlier. */
+ add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
+ if (! SEG_NORMAL (add_symbol_segment) ||
+ ! relaxable_section (add_symbol_segment))
+ return 0;
+
+ sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
+ return (sub_symbol_segment == add_symbol_segment);
+}
+
+/* TC_FORCE_RELOCATION hook */
+
+/* If linkrelax is turned on, and the symbol to relocate
+ against is in a relaxable segment, don't compute the value -
+ generate a relocation instead. */
+int
+avr_force_relocation (fixS *fix)
+{
+ if (linkrelax && fix->fx_addsy
+ && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
+ return 1;
+
+ return generic_force_reloc (fix);
+}
+
/* GAS will call this for each fixup. It should store the correct
value in the object file. */
@@ -1166,11 +1306,47 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
fixP->fx_done = 1;
}
}
-
+ else if (linkrelax && fixP->fx_subsy)
+ {
+ /* For a subtraction relocation expression, generate one
+ of the DIFF relocs, with the value being the difference.
+ Note that a sym1 - sym2 expression is adjusted into a
+ section_start_sym + sym4_offset_from_section_start - sym1
+ expression. fixP->fx_addsy holds the section start symbol,
+ fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
+ holds sym1. Calculate the current difference and write value,
+ but leave fx_offset as is - during relaxation,
+ fx_offset - value gives sym1's value. */
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_AVR_DIFF8;
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_AVR_DIFF16;
+ break;
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_AVR_DIFF32;
+ break;
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+ break;
+ }
+
+ value = S_GET_VALUE (fixP->fx_addsy) +
+ fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
+
+ fixP->fx_subsy = NULL;
+ }
/* We don't actually support subtracting a symbol. */
if (fixP->fx_subsy != (symbolS *) NULL)
as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+ /* For the DIFF relocs, write the value into the object file while still
+ keeping fx_done FALSE, as both the difference (recorded in the object file)
+ and the sym offset (part of fixP) are needed at link relax time. */
+ where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
switch (fixP->fx_r_type)
{
default:
@@ -1180,6 +1356,16 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
case BFD_RELOC_AVR_13_PCREL:
case BFD_RELOC_32:
case BFD_RELOC_16:
+ break;
+ case BFD_RELOC_AVR_DIFF8:
+ *where = value;
+ break;
+ case BFD_RELOC_AVR_DIFF16:
+ bfd_putl16 ((bfd_vma) value, where);
+ break;
+ case BFD_RELOC_AVR_DIFF32:
+ bfd_putl32 ((bfd_vma) value, where);
+ break;
case BFD_RELOC_AVR_CALL:
break;
}
@@ -1256,11 +1442,21 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
break;
+ case BFD_RELOC_AVR_LDS_STS_16:
+ if ((value < 0x40) || (value > 0xBF))
+ as_warn_where (fixP->fx_file, fixP->fx_line,
+ _("operand out of range: 0x%lx"),
+ (unsigned long)value);
+ insn |= ((value & 0xF) | ((value & 0x30) << 5) | ((value & 0x40) << 2));
+ bfd_putl16 ((bfd_vma) insn, where);
+ break;
+
case BFD_RELOC_AVR_6:
if ((value > 63) || (value < 0))
as_bad_where (fixP->fx_file, fixP->fx_line,
_("operand out of range: %ld"), value);
- bfd_putl16 ((bfd_vma) insn | ((value & 7) | ((value & (3 << 3)) << 7) | ((value & (1 << 5)) << 8)), where);
+ bfd_putl16 ((bfd_vma) insn | ((value & 7) | ((value & (3 << 3)) << 7)
+ | ((value & (1 << 5)) << 8)), where);
break;
case BFD_RELOC_AVR_6_ADIW:
@@ -1357,6 +1553,20 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
as_fatal (_("line %d: unknown relocation type: 0x%x"),
fixP->fx_line, fixP->fx_r_type);
break;
+
+ case BFD_RELOC_AVR_PORT6:
+ if (value > 63)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("operand out of range: %ld"), value);
+ bfd_putl16 ((bfd_vma) insn | ((value & 0x30) << 5) | (value & 0x0f), where);
+ break;
+
+ case BFD_RELOC_AVR_PORT5:
+ if (value > 31)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("operand out of range: %ld"), value);
+ bfd_putl16 ((bfd_vma) insn | ((value & 0x1f) << 3), where);
+ break;
}
}
else
@@ -1435,6 +1645,28 @@ md_assemble (char *str)
opcode = (struct avr_opcodes_s *) hash_find (avr_hash, op);
+ if (opcode && !avr_opt.all_opcodes)
+ {
+ /* Check if the instruction's ISA bit is ON in the ISA bits of the part
+ specified by the user. If not look for other instructions
+ specifications with same mnemonic who's ISA bits matches.
+
+ This requires include/opcode/avr.h to have the instructions with
+ same mnenomic to be specified in sequence. */
+
+ while ((opcode->isa & avr_mcu->isa) != opcode->isa)
+ {
+ opcode++;
+
+ if (opcode->name && strcmp(op, opcode->name))
+ {
+ as_bad (_("illegal opcode %s for mcu %s"),
+ opcode->name, avr_mcu->name);
+ return;
+ }
+ }
+ }
+
if (opcode == NULL)
{
as_bad (_("unknown opcode `%s'"), op);
@@ -1447,9 +1679,6 @@ md_assemble (char *str)
if (*str && *opcode->constraints == '?')
++opcode;
- if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)
- as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);
-
dwarf2_emit_insn (0);
/* We used to set input_line_pointer to the result of get_operands,
@@ -1464,22 +1693,7 @@ md_assemble (char *str)
}
}
-typedef struct
-{
- /* Name of the expression modifier allowed with .byte, .word, etc. */
- const char *name;
-
- /* Only allowed with n bytes of data. */
- int nbytes;
-
- /* Associated RELOC. */
- bfd_reloc_code_real_type reloc;
-
- /* Part of the error message. */
- const char *error;
-} exp_mod_data_t;
-
-static const exp_mod_data_t exp_mod_data[] =
+const exp_mod_data_t exp_mod_data[] =
{
/* Default, must be first. */
{ "", 0, BFD_RELOC_16, "" },
@@ -1500,21 +1714,16 @@ static const exp_mod_data_t exp_mod_data[] =
{ NULL, 0, 0, NULL }
};
-/* Data to pass between `avr_parse_cons_expression' and `avr_cons_fix_new'. */
-static const exp_mod_data_t *pexp_mod_data = &exp_mod_data[0];
-
/* Parse special CONS expression: pm (expression) or alternatively
gs (expression). These are used for addressing program memory. Moreover,
define lo8 (expression), hi8 (expression) and hlo8 (expression). */
-void
+const exp_mod_data_t *
avr_parse_cons_expression (expressionS *exp, int nbytes)
{
const exp_mod_data_t *pexp = &exp_mod_data[0];
char *tmp;
- pexp_mod_data = pexp;
-
tmp = input_line_pointer = skip_space (input_line_pointer);
/* The first entry of exp_mod_data[] contains an entry if no
@@ -1532,18 +1741,18 @@ avr_parse_cons_expression (expressionS *exp, int nbytes)
if (*input_line_pointer == '(')
{
input_line_pointer = skip_space (input_line_pointer + 1);
- pexp_mod_data = pexp;
expression (exp);
if (*input_line_pointer == ')')
- ++input_line_pointer;
+ {
+ ++input_line_pointer;
+ return pexp;
+ }
else
{
as_bad (_("`)' required"));
- pexp_mod_data = &exp_mod_data[0];
+ return &exp_mod_data[0];
}
-
- return;
}
input_line_pointer = tmp;
@@ -1553,13 +1762,15 @@ avr_parse_cons_expression (expressionS *exp, int nbytes)
}
expression (exp);
+ return &exp_mod_data[0];
}
void
avr_cons_fix_new (fragS *frag,
int where,
int nbytes,
- expressionS *exp)
+ expressionS *exp,
+ const exp_mod_data_t *pexp_mod_data)
{
int bad = 0;
@@ -1589,17 +1800,15 @@ avr_cons_fix_new (fragS *frag,
if (bad)
as_bad (_("illegal %srelocation size: %d"), pexp_mod_data->error, nbytes);
-
- pexp_mod_data = &exp_mod_data[0];
}
static bfd_boolean
mcu_has_3_byte_pc (void)
{
- int mach = avr_mcu->mach;
+ int mach = avr_mcu->mach;
- return mach == bfd_mach_avr6
- || mach == bfd_mach_avrxmega6
+ return mach == bfd_mach_avr6
+ || mach == bfd_mach_avrxmega6
|| mach == bfd_mach_avrxmega7;
}
@@ -1617,3 +1826,25 @@ tc_cfi_frame_initial_instructions (void)
do not line up the same way as for targers that use pre-decrement. */
cfi_add_CFA_offset (DWARF2_DEFAULT_RETURN_COLUMN, 1-return_size);
}
+
+bfd_boolean
+avr_allow_local_subtract (expressionS * left,
+ expressionS * right,
+ segT section)
+{
+ /* If we are not in relaxation mode, subtraction is OK. */
+ if (!linkrelax)
+ return TRUE;
+
+ /* If the symbols are not in a code section then they are OK. */
+ if ((section->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ if (left->X_add_symbol == right->X_add_symbol)
+ return TRUE;
+
+ /* We have to assume that there may be instructions between the
+ two symbols and that relaxation may increase the distance between
+ them. */
+ return FALSE;
+}
diff --git a/binutils-2.25/gas/config/tc-avr.h b/binutils-2.25/gas/config/tc-avr.h
index ee36e65b..fb596add 100644
--- a/binutils-2.25/gas/config/tc-avr.h
+++ b/binutils-2.25/gas/config/tc-avr.h
@@ -1,6 +1,5 @@
/* This file is tc-avr.h
- Copyright 1999, 2000, 2001, 2002, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
@@ -51,16 +50,36 @@
will point to the start of the expression. */
#define md_operand(x)
+typedef struct
+{
+ /* Name of the expression modifier allowed with .byte, .word, etc. */
+ const char *name;
+
+ /* Only allowed with n bytes of data. */
+ int nbytes;
+
+ /* Associated RELOC. */
+ bfd_reloc_code_real_type reloc;
+
+ /* Part of the error message. */
+ const char *error;
+} exp_mod_data_t;
+
+extern const exp_mod_data_t exp_mod_data[];
+#define TC_PARSE_CONS_RETURN_TYPE const exp_mod_data_t *
+#define TC_PARSE_CONS_RETURN_NONE exp_mod_data
+
/* You may define this macro to parse an expression used in a data
allocation pseudo-op such as `.word'. You can use this to
recognize relocation directives that may appear in such directives. */
#define TC_PARSE_CONS_EXPRESSION(EXPR,N) avr_parse_cons_expression (EXPR, N)
-extern void avr_parse_cons_expression (expressionS *, int);
+extern const exp_mod_data_t *avr_parse_cons_expression (expressionS *, int);
/* You may define this macro to generate a fixup for a data
allocation pseudo-op. */
-#define TC_CONS_FIX_NEW(FRAG,WHERE,N,EXP) avr_cons_fix_new (FRAG, WHERE, N, EXP)
-extern void avr_cons_fix_new (fragS *,int, int, expressionS *);
+#define TC_CONS_FIX_NEW avr_cons_fix_new
+extern void avr_cons_fix_new (fragS *,int, int, expressionS *,
+ const exp_mod_data_t *);
/* This should just call either `number_to_chars_bigendian' or
`number_to_chars_littleendian', whichever is appropriate. On
@@ -93,6 +112,18 @@ extern void avr_cons_fix_new (fragS *,int, int, expressionS *);
visible symbols can be overridden. */
#define EXTERN_FORCE_RELOC 0
+/* If defined, this macro allows control over whether fixups for a
+ given section will be processed when the linkrelax variable is
+ set. Define it to zero and handle things in md_apply_fix instead.*/
+#define TC_LINKRELAX_FIXUP(SEG) 0
+
+/* If this macro returns non-zero, it guarantees that a relocation will be emitted
+ even when the value can be resolved locally. Do that if linkrelax is turned on */
+#define TC_FORCE_RELOCATION(fix) avr_force_relocation (fix)
+#define TC_FORCE_RELOCATION_SUB_SAME(fix, seg) \
+ (! SEG_NORMAL (seg) || avr_force_relocation (fix))
+extern int avr_force_relocation (struct fix *);
+
/* Values passed to md_apply_fix don't include the symbol value. */
#define MD_APPLY_SYM_VALUE(FIX) 0
@@ -150,6 +181,12 @@ extern long md_pcrel_from_section (struct fix *, segT);
goto SKIP; \
}
+/* This macro is evaluated for any fixup with a fx_subsy that
+ fixup_segment cannot reduce to a number. If the macro returns
+ false an error will be reported. */
+#define TC_VALIDATE_FIX_SUB(fix, seg) avr_validate_fix_sub (fix)
+extern int avr_validate_fix_sub (struct fix *);
+
/* This target is buggy, and sets fix size too large. */
#define TC_FX_SIZE_SLACK(FIX) 2
@@ -171,3 +208,8 @@ extern long md_pcrel_from_section (struct fix *, segT);
/* Define a hook to setup initial CFI state. */
extern void tc_cfi_frame_initial_instructions (void);
#define tc_cfi_frame_initial_instructions tc_cfi_frame_initial_instructions
+
+/* The difference between same-section symbols may be affected by linker
+ relaxation, so do not resolve such expressions in the assembler. */
+#define md_allow_local_subtract(l,r,s) avr_allow_local_subtract (l, r, s)
+extern bfd_boolean avr_allow_local_subtract (expressionS *, expressionS *, segT);
diff --git a/binutils-2.25/gas/config/tc-bfin.c b/binutils-2.25/gas/config/tc-bfin.c
index 99e9b1ee..447a477d 100644
--- a/binutils-2.25/gas/config/tc-bfin.c
+++ b/binutils-2.25/gas/config/tc-bfin.c
@@ -1,6 +1,5 @@
/* tc-bfin.c -- Assembler for the ADI Blackfin.
- Copyright 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -949,7 +948,7 @@ int ninsns;
int count_insns;
static void *
-allocate (int n)
+allocate (size_t n)
{
return obstack_alloc (&mempool, n);
}
diff --git a/binutils-2.25/gas/config/tc-bfin.h b/binutils-2.25/gas/config/tc-bfin.h
index 9ec990df..38f8c67c 100644
--- a/binutils-2.25/gas/config/tc-bfin.h
+++ b/binutils-2.25/gas/config/tc-bfin.h
@@ -1,6 +1,5 @@
/* tc-bfin.h - header file for tc-bfin.c
- Copyright 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-cr16.c b/binutils-2.25/gas/config/tc-cr16.c
index 8d6e780b..bcdf9781 100644
--- a/binutils-2.25/gas/config/tc-cr16.c
+++ b/binutils-2.25/gas/config/tc-cr16.c
@@ -1,6 +1,5 @@
/* tc-cr16.c -- Assembler code for the CR16 CPU core.
- Copyright 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2007-2014 Free Software Foundation, Inc.
Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>
@@ -493,10 +492,9 @@ cr16_force_relocation (fixS *fix)
/* Record a fixup for a cons expression. */
void
-cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp)
+cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
+ bfd_reloc_code_real_type rtype)
{
- int rtype = BFD_RELOC_UNUSED;
-
switch (len)
{
default: rtype = BFD_RELOC_NONE; break;
diff --git a/binutils-2.25/gas/config/tc-cr16.h b/binutils-2.25/gas/config/tc-cr16.h
index 739317ff..9da8cb78 100644
--- a/binutils-2.25/gas/config/tc-cr16.h
+++ b/binutils-2.25/gas/config/tc-cr16.h
@@ -1,5 +1,5 @@
/* tc-cr16.h -- Header file for tc-cr16.c, the CR16 GAS port.
- Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2007-2014 Free Software Foundation, Inc.
Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>
@@ -57,12 +57,13 @@ extern int cr16_force_relocation (struct fix *);
of two bytes long. */
#define DWARF2_LINE_MIN_INSN_LENGTH 2
-extern void cr16_cons_fix_new (struct frag *, int, int, struct expressionS *);
+extern void cr16_cons_fix_new (struct frag *, int, int, struct expressionS *,
+ bfd_reloc_code_real_type);
/* This is called by emit_expr when creating a reloc for a cons.
We could use the definition there, except that we want to handle
the CR16 reloc type specially, rather than the BFD_RELOC type. */
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
- cr16_cons_fix_new (FRAG, OFF, LEN, EXP)
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+ cr16_cons_fix_new (FRAG, OFF, LEN, EXP, RELOC)
/* Give an error if a frag containing code is not aligned to a 2-byte
boundary. */
diff --git a/binutils-2.25/gas/config/tc-cris.c b/binutils-2.25/gas/config/tc-cris.c
index 657c7ede..2989f02d 100644
--- a/binutils-2.25/gas/config/tc-cris.c
+++ b/binutils-2.25/gas/config/tc-cris.c
@@ -1,6 +1,5 @@
/* tc-cris.c -- Assembler code for the CRIS CPU core.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
Contributed by Axis Communications AB, Lund, Sweden.
Originally written for GAS 1.38.1 by Mikael Asker.
@@ -1125,9 +1124,15 @@ md_create_long_jump (char *storep, addressT from_addr, addressT to_addr,
if (max_short_minus_distance <= distance
&& distance <= max_short_plus_distance)
- /* Then make it a "short" long jump. */
- md_create_short_jump (storep, from_addr, to_addr, fragP,
+ {
+ /* Then make it a "short" long jump. */
+ md_create_short_jump (storep, from_addr, to_addr, fragP,
to_symbol);
+ if (cris_arch == arch_crisv32)
+ md_number_to_chars (storep + 6, NOP_OPCODE_V32, 2);
+ else
+ md_number_to_chars (storep + 6, NOP_OPCODE, 2);
+ }
else
{
/* We have a "long" long jump: "JUMP [PC+]". If CRISv32, always
@@ -1487,6 +1492,19 @@ md_assemble (char *str)
}
}
+/* Helper error-reporting function: calls as_bad for a format string
+ for a single value and zeroes the offending value (zero assumed
+ being a valid value) to avoid repeated error reports in later value
+ checking. */
+
+static void
+cris_bad (const char *format, offsetT *valp)
+{
+ /* We cast to long so the format string can assume that format. */
+ as_bad (format, (long) *valp);
+ *valp = 0;
+}
+
/* Low level text-to-bits assembly. */
static void
@@ -1641,8 +1659,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 31))
- as_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_5;
continue;
@@ -1657,8 +1675,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 15))
- as_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_4;
continue;
@@ -1709,8 +1727,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < -32
|| out_insnp->expr.X_add_number > 31))
- as_bad (_("Immediate value not in 6 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 6 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
+
out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_6;
continue;
}
@@ -1724,8 +1743,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 63))
- as_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
+
out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_6;
continue;
}
@@ -2117,8 +2137,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < -128
|| out_insnp->expr.X_add_number > 255))
- as_bad (_("Immediate value not in 8 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
/* Fall through. */
case 2:
/* FIXME: We need an indicator in the instruction
@@ -2127,8 +2147,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < -32768
|| out_insnp->expr.X_add_number > 65535))
- as_bad (_("Immediate value not in 16 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
out_insnp->imm_oprnd_size = 2;
break;
@@ -2157,18 +2177,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (instruction->imm_oprnd_size == SIZE_FIELD
&& (out_insnp->expr.X_add_number < -128
|| out_insnp->expr.X_add_number > 255))
- as_bad (_("Immediate value not in 8 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
&& (out_insnp->expr.X_add_number < -128
|| out_insnp->expr.X_add_number > 127))
- as_bad (_("Immediate value not in 8 bit signed range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit signed range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 255))
- as_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
}
/* Fall through. */
@@ -2178,18 +2198,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
if (instruction->imm_oprnd_size == SIZE_FIELD
&& (out_insnp->expr.X_add_number < -32768
|| out_insnp->expr.X_add_number > 65535))
- as_bad (_("Immediate value not in 16 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
&& (out_insnp->expr.X_add_number < -32768
|| out_insnp->expr.X_add_number > 32767))
- as_bad (_("Immediate value not in 16 bit signed range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit signed range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 65535))
- as_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
}
out_insnp->imm_oprnd_size = 2;
break;
diff --git a/binutils-2.25/gas/config/tc-cris.h b/binutils-2.25/gas/config/tc-cris.h
index 56584bfb..ce3ad739 100644
--- a/binutils-2.25/gas/config/tc-cris.h
+++ b/binutils-2.25/gas/config/tc-cris.h
@@ -1,6 +1,5 @@
/* tc-cris.h -- Header file for tc-cris.c, the CRIS GAS port.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
Contributed by Axis Communications AB, Lund, Sweden.
Originally written for GAS 1.38.1 by Mikael Asker.
diff --git a/binutils-2.25/gas/config/tc-crx.c b/binutils-2.25/gas/config/tc-crx.c
index 3b06a788..61a31b3b 100644
--- a/binutils-2.25/gas/config/tc-crx.c
+++ b/binutils-2.25/gas/config/tc-crx.c
@@ -1,6 +1,5 @@
/* tc-crx.c -- Assembler code for the CRX CPU core.
- Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
Contributed by Tomer Levi, NSC, Israel.
Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
diff --git a/binutils-2.25/gas/config/tc-crx.h b/binutils-2.25/gas/config/tc-crx.h
index 3036dc6e..da6d7102 100644
--- a/binutils-2.25/gas/config/tc-crx.h
+++ b/binutils-2.25/gas/config/tc-crx.h
@@ -1,5 +1,5 @@
/* tc-crx.h -- Header file for tc-crx.c, the CRX GAS port.
- Copyright 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
Contributed by Tomer Levi, NSC, Israel.
Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
@@ -60,7 +60,8 @@ extern int crx_force_relocation (struct fix *);
/* This is called by emit_expr when creating a reloc for a cons.
We could use the definition there, except that we want to handle
the CRX reloc type specially, rather than the BFD_RELOC type. */
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+ (void) RELOC, \
fix_new_exp (FRAG, OFF, (int) LEN, EXP, 0, \
LEN == 1 ? BFD_RELOC_CRX_NUM8 \
: LEN == 2 ? BFD_RELOC_CRX_NUM16 \
diff --git a/binutils-2.25/gas/config/tc-d10v.c b/binutils-2.25/gas/config/tc-d10v.c
index 983c2f80..8e3d171c 100644
--- a/binutils-2.25/gas/config/tc-d10v.c
+++ b/binutils-2.25/gas/config/tc-d10v.c
@@ -1,7 +1,5 @@
/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
- 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-d10v.h b/binutils-2.25/gas/config/tc-d10v.h
index 3c326248..55dc1cc6 100644
--- a/binutils-2.25/gas/config/tc-d10v.h
+++ b/binutils-2.25/gas/config/tc-d10v.h
@@ -1,6 +1,5 @@
/* tc-d10v.h -- Header file for tc-d10v.c.
- Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2009,
- 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
Written by Martin Hunt, Cygnus Support.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-d30v.c b/binutils-2.25/gas/config/tc-d30v.c
index 9a3477b6..9076e412 100644
--- a/binutils-2.25/gas/config/tc-d30v.c
+++ b/binutils-2.25/gas/config/tc-d30v.c
@@ -1,6 +1,5 @@
/* tc-d30v.c -- Assembler code for the Mitsubishi D30V
- Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-d30v.h b/binutils-2.25/gas/config/tc-d30v.h
index e75f3d81..3e11a1cc 100644
--- a/binutils-2.25/gas/config/tc-d30v.h
+++ b/binutils-2.25/gas/config/tc-d30v.h
@@ -1,6 +1,5 @@
/* tc-310v.h -- Header file for tc-d30v.c.
- Copyright 1997, 1998, 2000, 2001, 2002, 2005, 2007, 2009, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
Written by Martin Hunt, Cygnus Support.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-dlx.c b/binutils-2.25/gas/config/tc-dlx.c
index a629533b..3c487f25 100644
--- a/binutils-2.25/gas/config/tc-dlx.c
+++ b/binutils-2.25/gas/config/tc-dlx.c
@@ -1,6 +1,5 @@
/* tc-dlx.c -- Assemble for the DLX
- Copyright 2002, 2003, 2004, 2005, 2007, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -667,6 +666,9 @@ machine_ip (char *str)
expressionS *operand = &the_operand;
unsigned int reg, reg_shift = 0;
+ memset (&the_insn, '\0', sizeof (the_insn));
+ the_insn.reloc = NO_RELOC;
+
/* Fixup the opcode string to all lower cases, and also
allow numerical digits. */
s = str;
@@ -691,19 +693,12 @@ machine_ip (char *str)
return;
}
- /* Hash the opcode, insn will have the string from opcode table.
- also initialized the_insn struct. */
+ /* Hash the opcode, insn will have the string from opcode table. */
if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
{
/* Handle the ret and return macro here. */
if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0))
- {
- memset (&the_insn, '\0', sizeof (the_insn));
- the_insn.reloc = NO_RELOC;
- the_insn.pcrel = 0;
- the_insn.opcode =
- (unsigned long)(JROP | 0x03e00000); /* 0x03e00000 = r31 << 21 */
- }
+ the_insn.opcode = JROP | 0x03e00000; /* 0x03e00000 = r31 << 21 */
else
as_bad (_("Unknown opcode `%s'."), str);
@@ -711,9 +706,6 @@ machine_ip (char *str)
}
opcode = insn->opcode;
- memset (&the_insn, '\0', sizeof (the_insn));
- the_insn.reloc = NO_RELOC;
- the_insn.pcrel = 0;
/* Set the sip reloc HI16 flag. */
if (!set_dlx_skip_hi16_flag (1))
diff --git a/binutils-2.25/gas/config/tc-dlx.h b/binutils-2.25/gas/config/tc-dlx.h
index de5506b3..e299f27f 100644
--- a/binutils-2.25/gas/config/tc-dlx.h
+++ b/binutils-2.25/gas/config/tc-dlx.h
@@ -1,5 +1,5 @@
/* tc-dlx.h -- Assemble for the DLX
- Copyright 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-epiphany.c b/binutils-2.25/gas/config/tc-epiphany.c
index d4729684..ebaedc41 100755..100644
--- a/binutils-2.25/gas/config/tc-epiphany.c
+++ b/binutils-2.25/gas/config/tc-epiphany.c
@@ -1,5 +1,5 @@
/* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
- Copyright 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by Embecosm on behalf of Adapteva, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-epiphany.h b/binutils-2.25/gas/config/tc-epiphany.h
index ed5782ed..ddfb4756 100755..100644
--- a/binutils-2.25/gas/config/tc-epiphany.h
+++ b/binutils-2.25/gas/config/tc-epiphany.h
@@ -1,5 +1,5 @@
/* tc-epiphany.h -- Header file for tc-epiphany.c.
- Copyright 2009, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by Embecosm on behalf of Adapteva, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-fr30.c b/binutils-2.25/gas/config/tc-fr30.c
index 8e01fb2b..07c2b8f3 100644
--- a/binutils-2.25/gas/config/tc-fr30.c
+++ b/binutils-2.25/gas/config/tc-fr30.c
@@ -1,6 +1,5 @@
/* tc-fr30.c -- Assembler for the Fujitsu FR30.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-fr30.h b/binutils-2.25/gas/config/tc-fr30.h
index 9709cdd3..3ed399b4 100644
--- a/binutils-2.25/gas/config/tc-fr30.h
+++ b/binutils-2.25/gas/config/tc-fr30.h
@@ -1,6 +1,5 @@
/* tc-fr30.h -- Header file for tc-fr30.c.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-frv.c b/binutils-2.25/gas/config/tc-frv.c
index 9cdbe265..faaa1c2b 100644
--- a/binutils-2.25/gas/config/tc-frv.c
+++ b/binutils-2.25/gas/config/tc-frv.c
@@ -1,6 +1,5 @@
/* tc-frv.c -- Assembler for the Fujitsu FRV.
- Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation. Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-frv.h b/binutils-2.25/gas/config/tc-frv.h
index c29210e1..9b4e6067 100644
--- a/binutils-2.25/gas/config/tc-frv.h
+++ b/binutils-2.25/gas/config/tc-frv.h
@@ -1,6 +1,5 @@
/* tc-frv.h -- Header file for tc-frv.c.
- Copyright 2002, 2004, 2005, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-generic.c b/binutils-2.25/gas/config/tc-generic.c
index 258878a5..778429ae 100644
--- a/binutils-2.25/gas/config/tc-generic.c
+++ b/binutils-2.25/gas/config/tc-generic.c
@@ -1,6 +1,6 @@
/* This file is tc-generic.c
- Copyright 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-generic.h b/binutils-2.25/gas/config/tc-generic.h
index bbaa359f..ec7593f6 100644
--- a/binutils-2.25/gas/config/tc-generic.h
+++ b/binutils-2.25/gas/config/tc-generic.h
@@ -1,7 +1,6 @@
/* This file is tc-generic.h
- Copyright 1987, 1991, 1992, 1995, 1997, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-h8300.c b/binutils-2.25/gas/config/tc-h8300.c
index 032831b6..e4b827be 100644
--- a/binutils-2.25/gas/config/tc-h8300.c
+++ b/binutils-2.25/gas/config/tc-h8300.c
@@ -1,5 +1,5 @@
/* tc-h8300.c -- Assemble code for the Renesas H8/300
- Copyright 1991-2013 Free Software Foundation, Inc.
+ Copyright (C) 1991-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-h8300.h b/binutils-2.25/gas/config/tc-h8300.h
index 0a2e8280..35dfea8b 100644
--- a/binutils-2.25/gas/config/tc-h8300.h
+++ b/binutils-2.25/gas/config/tc-h8300.h
@@ -1,5 +1,5 @@
/* This file is tc-h8300.h
- Copyright 1987-2013 Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-hppa.c b/binutils-2.25/gas/config/tc-hppa.c
index 6e2debe9..5ee7f726 100644
--- a/binutils-2.25/gas/config/tc-hppa.c
+++ b/binutils-2.25/gas/config/tc-hppa.c
@@ -1,7 +1,5 @@
/* tc-hppa.c -- Assemble for the PA
- Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -608,9 +606,6 @@ static int within_procedure;
seen in each subspace. */
static label_symbol_struct *label_symbols_rootp = NULL;
-/* Holds the last field selector. */
-static int hppa_field_selector;
-
/* Nonzero when strict matching is enabled. Zero otherwise.
Each opcode in the table has a flag which indicates whether or
@@ -1265,7 +1260,8 @@ fix_new_hppa (fragS *frag,
hppa_field_selector is set by the parse_cons_expression_hppa. */
void
-cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
+cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp,
+ int hppa_field_selector)
{
unsigned int rel_type;
@@ -1302,9 +1298,6 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
fix_new_hppa (frag, where, size,
(symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
hppa_field_selector, size * 8, 0, 0);
-
- /* Reset field selector to its default state. */
- hppa_field_selector = 0;
}
/* Mark (via expr_end) the end of an expression (I think). FIXME. */
@@ -2519,11 +2512,12 @@ pa_chk_field_selector (char **str)
/* Parse a .byte, .word, .long expression for the HPPA. Called by
cons via the TC_PARSE_CONS_EXPRESSION macro. */
-void
+int
parse_cons_expression_hppa (expressionS *exp)
{
- hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
+ int hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
expression (exp);
+ return hppa_field_selector;
}
/* Evaluate an absolute expression EXP which may be modified by
diff --git a/binutils-2.25/gas/config/tc-hppa.h b/binutils-2.25/gas/config/tc-hppa.h
index 78d9edfd..4277e10d 100644
--- a/binutils-2.25/gas/config/tc-hppa.h
+++ b/binutils-2.25/gas/config/tc-hppa.h
@@ -1,7 +1,5 @@
/* tc-hppa.h -- Header file for the PA
- Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -92,8 +90,8 @@
/* pa_define_label gets used outside of tc-hppa.c via tc_frob_label. */
extern void pa_define_label (symbolS *);
-extern void parse_cons_expression_hppa (expressionS *);
-extern void cons_fix_new_hppa (fragS *, int, int, expressionS *);
+extern int parse_cons_expression_hppa (expressionS *);
+extern void cons_fix_new_hppa (fragS *, int, int, expressionS *, int);
extern int hppa_force_relocation (struct fix *);
/* This gets called before writing the object file to make sure
@@ -114,6 +112,8 @@ extern const char hppa_symbol_chars[];
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
parse_cons_expression_hppa (EXP)
#define TC_CONS_FIX_NEW cons_fix_new_hppa
+#define TC_PARSE_CONS_RETURN_TYPE int
+#define TC_PARSE_CONS_RETURN_NONE e_fsel
/* On the PA, an exclamation point can appear in an instruction. It is
used in FP comparison instructions and as an end of line marker.
diff --git a/binutils-2.25/gas/config/tc-i370.c b/binutils-2.25/gas/config/tc-i370.c
index bf362a3b..399b7f36 100644
--- a/binutils-2.25/gas/config/tc-i370.c
+++ b/binutils-2.25/gas/config/tc-i370.c
@@ -1,7 +1,6 @@
/* tc-i370.c -- Assembler for the IBM 360/370/390 instruction set.
Loosely based on the ppc files by Linas Vepstas <linas@linas.org> 1998, 99
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-i370.h b/binutils-2.25/gas/config/tc-i370.h
index 71e7184d..6ee29a3e 100644
--- a/binutils-2.25/gas/config/tc-i370.h
+++ b/binutils-2.25/gas/config/tc-i370.h
@@ -1,6 +1,5 @@
/* tc-i370.h -- Header file for tc-i370.c.
- Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-i386-intel.c b/binutils-2.25/gas/config/tc-i386-intel.c
index e534110f..86b96ebe 100644
--- a/binutils-2.25/gas/config/tc-i386-intel.c
+++ b/binutils-2.25/gas/config/tc-i386-intel.c
@@ -1,6 +1,5 @@
/* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64
- Copyright 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -415,23 +414,21 @@ static int i386_intel_simplify (expressionS *e)
if (this_operand >= 0 && intel_state.in_bracket)
{
expressionS *scale = NULL;
-
- if (intel_state.index)
- --scale;
+ int has_index = (intel_state.index != NULL);
if (!intel_state.in_scale++)
intel_state.scale_factor = 1;
ret = i386_intel_simplify_symbol (e->X_add_symbol);
- if (ret && !scale && intel_state.index)
+ if (ret && !has_index && intel_state.index)
scale = symbol_get_value_expression (e->X_op_symbol);
if (ret)
ret = i386_intel_simplify_symbol (e->X_op_symbol);
- if (ret && !scale && intel_state.index)
+ if (ret && !scale && !has_index && intel_state.index)
scale = symbol_get_value_expression (e->X_add_symbol);
- if (ret && scale && (scale + 1))
+ if (ret && scale)
{
resolve_expression (scale);
if (scale->X_op != O_constant
diff --git a/binutils-2.25/gas/config/tc-i386.c b/binutils-2.25/gas/config/tc-i386.c
index 32f6d48a..6f7a1ae7 100644
--- a/binutils-2.25/gas/config/tc-i386.c
+++ b/binutils-2.25/gas/config/tc-i386.c
@@ -1,8 +1,5 @@
/* tc-i386.c -- Assemble code for the Intel 80386
- Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
- 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -516,6 +513,11 @@ enum x86_elf_abi
static enum x86_elf_abi x86_elf_abi = I386_ABI;
#endif
+#if defined (TE_PE) || defined (TE_PEP)
+/* Use big object file format. */
+static int use_big_obj = 0;
+#endif
+
/* 1 for intel syntax,
0 if att syntax. */
static int intel_syntax = 0;
@@ -541,6 +543,10 @@ static int add_bnd_prefix = 0;
/* 1 if pseudo index register, eiz/riz, is allowed . */
static int allow_index_reg = 0;
+/* 1 if the assembler should ignore LOCK prefix, even if it was
+ specified explicitly. */
+static int omit_lock_prefix = 0;
+
static enum check_kind
{
check_none = 0,
@@ -614,6 +620,9 @@ static enum
evexw1
} evexwig;
+/* Value to encode in EVEX RC bits, for SAE-only instructions. */
+static enum rc_type evexrcig = rne;
+
/* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
static symbolS *GOT_symbol;
@@ -818,6 +827,12 @@ static const arch_entry cpu_arch[] =
CPU_AVX512ER_FLAGS, 0, 0 },
{ STRING_COMMA_LEN (".avx512pf"), PROCESSOR_UNKNOWN,
CPU_AVX512PF_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".avx512dq"), PROCESSOR_UNKNOWN,
+ CPU_AVX512DQ_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".avx512bw"), PROCESSOR_UNKNOWN,
+ CPU_AVX512BW_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".avx512vl"), PROCESSOR_UNKNOWN,
+ CPU_AVX512VL_FLAGS, 0, 0 },
{ STRING_COMMA_LEN (".noavx"), PROCESSOR_UNKNOWN,
CPU_ANY_AVX_FLAGS, 0, 1 },
{ STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN,
@@ -830,6 +845,10 @@ static const arch_entry cpu_arch[] =
CPU_XSAVE_FLAGS, 0, 0 },
{ STRING_COMMA_LEN (".xsaveopt"), PROCESSOR_UNKNOWN,
CPU_XSAVEOPT_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".xsavec"), PROCESSOR_UNKNOWN,
+ CPU_XSAVEC_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".xsaves"), PROCESSOR_UNKNOWN,
+ CPU_XSAVES_FLAGS, 0, 0 },
{ STRING_COMMA_LEN (".aes"), PROCESSOR_UNKNOWN,
CPU_AES_FLAGS, 0, 0 },
{ STRING_COMMA_LEN (".pclmul"), PROCESSOR_UNKNOWN,
@@ -904,6 +923,20 @@ static const arch_entry cpu_arch[] =
CPU_MPX_FLAGS, 0, 0 },
{ STRING_COMMA_LEN (".sha"), PROCESSOR_UNKNOWN,
CPU_SHA_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".clflushopt"), PROCESSOR_UNKNOWN,
+ CPU_CLFLUSHOPT_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".prefetchwt1"), PROCESSOR_UNKNOWN,
+ CPU_PREFETCHWT1_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".se1"), PROCESSOR_UNKNOWN,
+ CPU_SE1_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".clwb"), PROCESSOR_UNKNOWN,
+ CPU_CLWB_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".pcommit"), PROCESSOR_UNKNOWN,
+ CPU_PCOMMIT_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".avx512ifma"), PROCESSOR_UNKNOWN,
+ CPU_AVX512IFMA_FLAGS, 0, 0 },
+ { STRING_COMMA_LEN (".avx512vbmi"), PROCESSOR_UNKNOWN,
+ CPU_AVX512VBMI_FLAGS, 0, 0 },
};
#ifdef I386COFF
@@ -1667,8 +1700,6 @@ static const i386_operand_type imm16_32 = OPERAND_TYPE_IMM16_32;
static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S;
static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S;
static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4;
-static const i386_operand_type regbnd = OPERAND_TYPE_REGBND;
-static const i386_operand_type vec_disp8 = OPERAND_TYPE_VEC_DISP8;
enum operand_type
{
@@ -1923,47 +1954,46 @@ mode_from_disp_size (i386_operand_type t)
}
static INLINE int
-fits_in_signed_byte (offsetT num)
+fits_in_signed_byte (addressT num)
{
- return (num >= -128) && (num <= 127);
+ return num + 0x80 <= 0xff;
}
static INLINE int
-fits_in_unsigned_byte (offsetT num)
+fits_in_unsigned_byte (addressT num)
{
- return (num & 0xff) == num;
+ return num <= 0xff;
}
static INLINE int
-fits_in_unsigned_word (offsetT num)
+fits_in_unsigned_word (addressT num)
{
- return (num & 0xffff) == num;
+ return num <= 0xffff;
}
static INLINE int
-fits_in_signed_word (offsetT num)
+fits_in_signed_word (addressT num)
{
- return (-32768 <= num) && (num <= 32767);
+ return num + 0x8000 <= 0xffff;
}
static INLINE int
-fits_in_signed_long (offsetT num ATTRIBUTE_UNUSED)
+fits_in_signed_long (addressT num ATTRIBUTE_UNUSED)
{
#ifndef BFD64
return 1;
#else
- return (!(((offsetT) -1 << 31) & num)
- || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));
+ return num + 0x80000000 <= 0xffffffff;
#endif
} /* fits_in_signed_long() */
static INLINE int
-fits_in_unsigned_long (offsetT num ATTRIBUTE_UNUSED)
+fits_in_unsigned_long (addressT num ATTRIBUTE_UNUSED)
{
#ifndef BFD64
return 1;
#else
- return (num & (((offsetT) 2 << 31) - 1)) == num;
+ return num <= 0xffffffff;
#endif
} /* fits_in_unsigned_long() */
@@ -2835,9 +2865,12 @@ reloc (unsigned int size,
if (other == BFD_RELOC_SIZE32)
{
if (size == 8)
- return BFD_RELOC_SIZE64;
+ other = BFD_RELOC_SIZE64;
if (pcrel)
- as_bad (_("there are no pc-relative size relocations"));
+ {
+ as_bad (_("there are no pc-relative size relocations"));
+ return NO_RELOC;
+ }
}
#endif
@@ -3147,14 +3180,8 @@ build_vex_prefix (const insn_template *t)
/* Check the REX.W bit. */
w = (i.rex & REX_W) ? 1 : 0;
- if (i.tm.opcode_modifier.vexw)
- {
- if (w)
- abort ();
-
- if (i.tm.opcode_modifier.vexw == VEXW1)
- w = 1;
- }
+ if (i.tm.opcode_modifier.vexw == VEXW1)
+ w = 1;
i.vex.bytes[2] = (w << 7
| register_specifier << 3
@@ -3325,7 +3352,7 @@ build_evex_prefix (void)
if (i.rounding->type != saeonly)
i.vex.bytes[3] |= 0x10 | (i.rounding->type << 5);
else
- i.vex.bytes[3] |= 0x10;
+ i.vex.bytes[3] |= 0x10 | (evexrcig << 5);
}
if (i.mask && i.mask->mask)
@@ -3610,11 +3637,20 @@ md_assemble (char *line)
as_warn (_("translating to `%sp'"), i.tm.name);
}
- if (i.tm.opcode_modifier.vex)
- build_vex_prefix (t);
+ if (i.tm.opcode_modifier.vex || i.tm.opcode_modifier.evex)
+ {
+ if (flag_code == CODE_16BIT)
+ {
+ as_bad (_("instruction `%s' isn't supported in 16-bit mode."),
+ i.tm.name);
+ return;
+ }
- if (i.tm.opcode_modifier.evex)
- build_evex_prefix ();
+ if (i.tm.opcode_modifier.vex)
+ build_vex_prefix (t);
+ else
+ build_evex_prefix ();
+ }
/* Handle conversion of 'int $3' --> special int3 insn. XOP or FMA4
instructions may define INT_OPCODE as well, so avoid this corner
@@ -4345,6 +4381,14 @@ check_VecOperands (const insn_template *t)
return 1;
}
+ /* Check if default mask is allowed. */
+ if (t->opcode_modifier.nodefmask
+ && (!i.mask || i.mask->mask->reg_num == 0))
+ {
+ i.error = no_default_mask;
+ return 1;
+ }
+
/* For VSIB byte, we need a vector register for index, and all vector
registers must be distinct. */
if (t->opcode_modifier.vecsib)
@@ -4365,11 +4409,9 @@ check_VecOperands (const insn_template *t)
if (i.reg_operands == 2 && !i.mask)
{
gas_assert (i.types[0].bitfield.regxmm
- || i.types[0].bitfield.regymm
- || i.types[0].bitfield.regzmm);
+ || i.types[0].bitfield.regymm);
gas_assert (i.types[2].bitfield.regxmm
- || i.types[2].bitfield.regymm
- || i.types[2].bitfield.regzmm);
+ || i.types[2].bitfield.regymm);
if (operand_check == check_none)
return 0;
if (register_number (i.op[0].regs)
@@ -4386,6 +4428,22 @@ check_VecOperands (const insn_template *t)
}
as_warn (_("mask, index, and destination registers should be distinct"));
}
+ else if (i.reg_operands == 1 && i.mask)
+ {
+ if ((i.types[1].bitfield.regymm
+ || i.types[1].bitfield.regzmm)
+ && (register_number (i.op[1].regs)
+ == register_number (i.index_reg)))
+ {
+ if (operand_check == check_error)
+ {
+ i.error = invalid_vector_register_set;
+ return 1;
+ }
+ if (operand_check != check_none)
+ as_warn (_("index and destination registers should be distinct"));
+ }
+ }
}
/* Check if broadcast is supported by the instruction and is applied
@@ -4412,6 +4470,10 @@ check_VecOperands (const insn_template *t)
broadcasted_opnd_size <<= 4; /* Broadcast 1to16. */
else if (i.broadcast->type == BROADCAST_1TO8)
broadcasted_opnd_size <<= 3; /* Broadcast 1to8. */
+ else if (i.broadcast->type == BROADCAST_1TO4)
+ broadcasted_opnd_size <<= 2; /* Broadcast 1to4. */
+ else if (i.broadcast->type == BROADCAST_1TO2)
+ broadcasted_opnd_size <<= 1; /* Broadcast 1to2. */
else
goto bad_broadcast;
@@ -4462,14 +4524,6 @@ check_VecOperands (const insn_template *t)
return 1;
}
- /* Check if default mask is allowed. */
- if (t->opcode_modifier.nodefmask
- && (!i.mask || i.mask->mask->reg_num == 0))
- {
- i.error = no_default_mask;
- return 1;
- }
-
/* Check RC/SAE. */
if (i.rounding)
{
@@ -4671,9 +4725,9 @@ match_template (void)
&& !operand_types[0].bitfield.regymm
&& !operand_types[0].bitfield.regzmm)
|| (!operand_types[t->operands > 1].bitfield.regmmx
- && !!operand_types[t->operands > 1].bitfield.regxmm
- && !!operand_types[t->operands > 1].bitfield.regymm
- && !!operand_types[t->operands > 1].bitfield.regzmm))
+ && operand_types[t->operands > 1].bitfield.regxmm
+ && operand_types[t->operands > 1].bitfield.regymm
+ && operand_types[t->operands > 1].bitfield.regzmm))
&& (t->base_opcode != 0x0fc7
|| t->extension_opcode != 1 /* cmpxchg8b */))
continue;
@@ -4688,7 +4742,7 @@ match_template (void)
&& ((!operand_types[0].bitfield.regmmx
&& !operand_types[0].bitfield.regxmm)
|| (!operand_types[t->operands > 1].bitfield.regmmx
- && !!operand_types[t->operands > 1].bitfield.regxmm)))
+ && operand_types[t->operands > 1].bitfield.regxmm)))
continue;
/* Do not verify operands when there are none. */
@@ -5418,7 +5472,7 @@ check_long_reg (void)
i.suffix);
return 0;
}
- /* Warn if the e prefix on a general reg is missing. */
+ /* Warn if the e prefix on a general reg is missing. */
else if ((!quiet_warnings || flag_code == CODE_64BIT)
&& i.types[op].bitfield.reg16
&& (i.tm.operand_types[op].bitfield.reg32
@@ -5440,7 +5494,7 @@ check_long_reg (void)
register_prefix, i.op[op].regs->reg_name, i.suffix);
#endif
}
- /* Warn if the r prefix on a general reg is missing. */
+ /* Warn if the r prefix on a general reg is present. */
else if (i.types[op].bitfield.reg64
&& (i.tm.operand_types[op].bitfield.reg32
|| i.tm.operand_types[op].bitfield.acc))
@@ -5483,7 +5537,7 @@ check_qword_reg (void)
i.suffix);
return 0;
}
- /* Warn if the e prefix on a general reg is missing. */
+ /* Warn if the r prefix on a general reg is missing. */
else if ((i.types[op].bitfield.reg16
|| i.types[op].bitfield.reg32)
&& (i.tm.operand_types[op].bitfield.reg32
@@ -5528,9 +5582,10 @@ check_word_reg (void)
i.suffix);
return 0;
}
- /* Warn if the e prefix on a general reg is present. */
+ /* Warn if the e or r prefix on a general reg is present. */
else if ((!quiet_warnings || flag_code == CODE_64BIT)
- && i.types[op].bitfield.reg32
+ && (i.types[op].bitfield.reg32
+ || i.types[op].bitfield.reg64)
&& (i.tm.operand_types[op].bitfield.reg16
|| i.tm.operand_types[op].bitfield.acc))
{
@@ -6132,8 +6187,8 @@ build_modrm_byte (void)
op = i.tm.operand_types[vvvv];
op.bitfield.regmem = 0;
if ((dest + 1) >= i.operands
- || (op.bitfield.reg32 != 1
- && !op.bitfield.reg64 != 1
+ || (!op.bitfield.reg32
+ && op.bitfield.reg64
&& !operand_type_equal (&op, &regxmm)
&& !operand_type_equal (&op, &regymm)
&& !operand_type_equal (&op, &regzmm)
@@ -6894,6 +6949,15 @@ output_insn (void)
unsigned int j;
unsigned int prefix;
+ /* Some processors fail on LOCK prefix. This options makes
+ assembler ignore LOCK prefix and serves as a workaround. */
+ if (omit_lock_prefix)
+ {
+ if (i.tm.base_opcode == LOCK_PREFIX_OPCODE)
+ return;
+ i.prefix[LOCK_PREFIX] = 0;
+ }
+
/* Since the VEX/EVEX prefix contains the implicit prefix, we
don't need the explicit prefix. */
if (!i.tm.opcode_modifier.vex && !i.tm.opcode_modifier.evex)
@@ -6929,6 +6993,17 @@ check_prefix:
abort ();
}
+#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
+ /* For x32, add a dummy REX_OPCODE prefix for mov/add with
+ R_X86_64_GOTTPOFF relocation so that linker can safely
+ perform IE->LE optimization. */
+ if (x86_elf_abi == X86_64_X32_ABI
+ && i.operands == 2
+ && i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
+ && i.prefix[REX_PREFIX] == 0)
+ add_prefix (REX_OPCODE);
+#endif
+
/* The prefix bytes. */
for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
if (*q)
@@ -7294,16 +7369,13 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off)
/* x86_cons_fix_new is called via the expression parsing code when a
reloc is needed. We use this hook to get the correct .got reloc. */
-static enum bfd_reloc_code_real got_reloc = NO_RELOC;
static int cons_sign = -1;
void
x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
- expressionS *exp)
+ expressionS *exp, bfd_reloc_code_real_type r)
{
- enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, got_reloc);
-
- got_reloc = NO_RELOC;
+ r = reloc (len, 0, cons_sign, r);
#ifdef TE_PE
if (exp->X_op == O_secrel)
@@ -7510,7 +7582,7 @@ lex_got (enum bfd_reloc_code_real *rel,
static char *
lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
int *adjust ATTRIBUTE_UNUSED,
- i386_operand_type *types ATTRIBUTE_UNUSED)
+ i386_operand_type *types)
{
static const struct
{
@@ -7595,9 +7667,11 @@ lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
#endif /* TE_PE */
-void
+bfd_reloc_code_real_type
x86_cons (expressionS *exp, int size)
{
+ bfd_reloc_code_real_type got_reloc = NO_RELOC;
+
intel_syntax = -intel_syntax;
exp->X_md = 0;
@@ -7644,6 +7718,8 @@ x86_cons (expressionS *exp, int size)
if (intel_syntax)
i386_intel_simplify (exp);
+
+ return got_reloc;
}
static void
@@ -7704,6 +7780,10 @@ check_VecOperations (char *op_string, char *op_end)
op_string += 3;
if (*op_string == '8')
bcst_type = BROADCAST_1TO8;
+ else if (*op_string == '4')
+ bcst_type = BROADCAST_1TO4;
+ else if (*op_string == '2')
+ bcst_type = BROADCAST_1TO2;
else if (*op_string == '1'
&& *(op_string+1) == '6')
{
@@ -7903,7 +7983,7 @@ i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp,
return 0;
}
#endif
- else if (!intel_syntax && exp->X_op == O_register)
+ else if (!intel_syntax && exp_seg == reg_section)
{
if (imm_start)
as_bad (_("illegal immediate register operand %s"), imm_start);
@@ -9096,8 +9176,21 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
#endif
}
#if defined (OBJ_COFF) && defined (TE_PE)
- if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
- {
+ if (fixP->fx_addsy != NULL
+ && S_IS_WEAK (fixP->fx_addsy)
+ /* PR 16858: Do not modify weak function references. */
+ && ! fixP->fx_pcrel)
+ {
+#if !defined (TE_PEP)
+ /* For x86 PE weak function symbols are neither PC-relative
+ nor do they set S_IS_FUNCTION. So the only reliable way
+ to detect them is to check the flags of their containing
+ section. */
+ if (S_GET_SEGMENT (fixP->fx_addsy) != NULL
+ && S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_CODE)
+ ;
+ else
+#endif
value -= S_GET_VALUE (fixP->fx_addsy);
}
#endif
@@ -9361,6 +9454,8 @@ parse_register (char *reg_string, char **end_op)
know (e->X_add_number >= 0
&& (valueT) e->X_add_number < i386_regtab_size);
r = i386_regtab + e->X_add_number;
+ if ((r->reg_flags & RegVRex))
+ i.need_vrex = 1;
*end_op = input_line_pointer;
}
*input_line_pointer = c;
@@ -9454,6 +9549,9 @@ const char *md_shortopts = "qn";
#define OPTION_MADD_BND_PREFIX (OPTION_MD_BASE + 15)
#define OPTION_MEVEXLIG (OPTION_MD_BASE + 16)
#define OPTION_MEVEXWIG (OPTION_MD_BASE + 17)
+#define OPTION_MBIG_OBJ (OPTION_MD_BASE + 18)
+#define OPTION_OMIT_LOCK_PREFIX (OPTION_MD_BASE + 19)
+#define OPTION_MEVEXRCIG (OPTION_MD_BASE + 20)
struct option md_longopts[] =
{
@@ -9480,6 +9578,11 @@ struct option md_longopts[] =
{"madd-bnd-prefix", no_argument, NULL, OPTION_MADD_BND_PREFIX},
{"mevexlig", required_argument, NULL, OPTION_MEVEXLIG},
{"mevexwig", required_argument, NULL, OPTION_MEVEXWIG},
+# if defined (TE_PE) || defined (TE_PEP)
+ {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ},
+#endif
+ {"momit-lock-prefix", required_argument, NULL, OPTION_OMIT_LOCK_PREFIX},
+ {"mevexrcig", required_argument, NULL, OPTION_MEVEXRCIG},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
@@ -9752,6 +9855,19 @@ md_parse_option (int c, char *arg)
as_fatal (_("invalid -mevexlig= option: `%s'"), arg);
break;
+ case OPTION_MEVEXRCIG:
+ if (strcmp (arg, "rne") == 0)
+ evexrcig = rne;
+ else if (strcmp (arg, "rd") == 0)
+ evexrcig = rd;
+ else if (strcmp (arg, "ru") == 0)
+ evexrcig = ru;
+ else if (strcmp (arg, "rz") == 0)
+ evexrcig = rz;
+ else
+ as_fatal (_("invalid -mevexrcig= option: `%s'"), arg);
+ break;
+
case OPTION_MEVEXWIG:
if (strcmp (arg, "0") == 0)
evexwig = evexw0;
@@ -9761,6 +9877,21 @@ md_parse_option (int c, char *arg)
as_fatal (_("invalid -mevexwig= option: `%s'"), arg);
break;
+# if defined (TE_PE) || defined (TE_PEP)
+ case OPTION_MBIG_OBJ:
+ use_big_obj = 1;
+ break;
+#endif
+
+ case OPTION_OMIT_LOCK_PREFIX:
+ if (strcasecmp (arg, "yes") == 0)
+ omit_lock_prefix = 1;
+ else if (strcasecmp (arg, "no") == 0)
+ omit_lock_prefix = 0;
+ else
+ as_fatal (_("invalid -momit-lock-prefix= option: `%s'"), arg);
+ break;
+
default:
return 0;
}
@@ -9902,6 +10033,10 @@ md_show_usage (FILE *stream)
-mevexwig=[0|1] encode EVEX instructions with specific EVEX.W value\n\
for EVEX.W bit ignored instructions\n"));
fprintf (stream, _("\
+ -mevexrcig=[rne|rd|ru|rz]\n\
+ encode EVEX instructions with specific EVEX.RC value\n\
+ for SAE-only ignored instructions\n"));
+ fprintf (stream, _("\
-mmnemonic=[att|intel] use AT&T/Intel mnemonic\n"));
fprintf (stream, _("\
-msyntax=[att|intel] use AT&T/Intel syntax\n"));
@@ -9913,6 +10048,13 @@ md_show_usage (FILE *stream)
-mold-gcc support old (<= 2.8.1) versions of gcc\n"));
fprintf (stream, _("\
-madd-bnd-prefix add BND prefix for all valid branches\n"));
+# if defined (TE_PE) || defined (TE_PEP)
+ fprintf (stream, _("\
+ -mbig-obj generate big object files\n"));
+#endif
+ fprintf (stream, _("\
+ -momit-lock-prefix=[no|yes]\n\
+ strip all lock prefixes\n"));
}
#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
@@ -9951,7 +10093,10 @@ i386_target_format (void)
#if defined (OBJ_MAYBE_COFF) || defined (OBJ_COFF)
# if defined (TE_PE) || defined (TE_PEP)
case bfd_target_coff_flavour:
- return flag_code == CODE_64BIT ? "pe-x86-64" : "pe-i386";
+ if (flag_code == CODE_64BIT)
+ return use_big_obj ? "pe-bigobj-x86-64" : "pe-x86-64";
+ else
+ return "pe-i386";
# elif defined (TE_GO32)
case bfd_target_coff_flavour:
return "coff-go32";
diff --git a/binutils-2.25/gas/config/tc-i386.h b/binutils-2.25/gas/config/tc-i386.h
index de132d69..8b5c7d7c 100644
--- a/binutils-2.25/gas/config/tc-i386.h
+++ b/binutils-2.25/gas/config/tc-i386.h
@@ -1,7 +1,5 @@
/* tc-i386.h -- Header file for tc-i386.c
- Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -134,11 +132,12 @@ extern const char *i386_comment_chars;
#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT)
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES)
#endif
-extern void x86_cons (expressionS *, int);
+extern bfd_reloc_code_real_type x86_cons (expressionS *, int);
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP)
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+ x86_cons_fix_new(FRAG, OFF, LEN, EXP, RELOC)
extern void x86_cons_fix_new
- (fragS *, unsigned int, unsigned int, expressionS *);
+(fragS *, unsigned int, unsigned int, expressionS *, bfd_reloc_code_real_type);
#define TC_ADDRESS_BYTES x86_address_bytes
extern int x86_address_bytes (void);
diff --git a/binutils-2.25/gas/config/tc-i860.c b/binutils-2.25/gas/config/tc-i860.c
index 32aed0fc..1b55b807 100644
--- a/binutils-2.25/gas/config/tc-i860.c
+++ b/binutils-2.25/gas/config/tc-i860.c
@@ -1,6 +1,5 @@
/* tc-i860.c -- Assembler for the Intel i860 architecture.
- Copyright 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002,
- 2003, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
Brought back from the dead and completely reworked
by Jason Eckhardt <jle@cygnus.com>.
diff --git a/binutils-2.25/gas/config/tc-i860.h b/binutils-2.25/gas/config/tc-i860.h
index c2618927..692ea304 100644
--- a/binutils-2.25/gas/config/tc-i860.h
+++ b/binutils-2.25/gas/config/tc-i860.h
@@ -1,6 +1,5 @@
/* tc-i860.h -- Header file for the i860.
- Copyright 1991, 1992, 1995, 1998, 2000, 2001, 2002, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1991-2014 Free Software Foundation, Inc.
Brought back from the dead and completely reworked
by Jason Eckhardt <jle@cygnus.com>.
diff --git a/binutils-2.25/gas/config/tc-i960.c b/binutils-2.25/gas/config/tc-i960.c
index 44664df3..91469eb9 100644
--- a/binutils-2.25/gas/config/tc-i960.c
+++ b/binutils-2.25/gas/config/tc-i960.c
@@ -1,7 +1,5 @@
/* tc-i960.c - All the i80960-specific stuff
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS.
@@ -66,7 +64,6 @@
#include "as.h"
#include "safe-ctype.h"
-#include "obstack.h"
#include "opcode/i960.h"
diff --git a/binutils-2.25/gas/config/tc-i960.h b/binutils-2.25/gas/config/tc-i960.h
index 3949b6c4..ee6d050c 100644
--- a/binutils-2.25/gas/config/tc-i960.h
+++ b/binutils-2.25/gas/config/tc-i960.h
@@ -1,7 +1,5 @@
/* tc-i960.h - Basic 80960 instruction formats.
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2005, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-ia64.c b/binutils-2.25/gas/config/tc-ia64.c
index b8ffe4e1..38b6b673 100644
--- a/binutils-2.25/gas/config/tc-ia64.c
+++ b/binutils-2.25/gas/config/tc-ia64.c
@@ -1,5 +1,5 @@
/* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
- Copyright 1998-2013 Free Software Foundation, Inc.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of GAS, the GNU Assembler.
@@ -4466,14 +4466,15 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
symbol_get_frag (unwind.proc_pending.sym));
else
e.X_add_symbol = unwind.proc_pending.sym;
- ia64_cons_fix_new (frag_now, where, bytes_per_address, &e);
+ ia64_cons_fix_new (frag_now, where, bytes_per_address, &e,
+ BFD_RELOC_NONE);
e.X_op = O_pseudo_fixup;
e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
e.X_add_number = 0;
e.X_add_symbol = proc_end;
ia64_cons_fix_new (frag_now, where + bytes_per_address,
- bytes_per_address, &e);
+ bytes_per_address, &e, BFD_RELOC_NONE);
if (unwind.info)
{
@@ -4482,7 +4483,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
e.X_add_number = 0;
e.X_add_symbol = unwind.info;
ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2),
- bytes_per_address, &e);
+ bytes_per_address, &e, BFD_RELOC_NONE);
}
}
subseg_set (saved_seg, saved_subseg);
@@ -11056,9 +11057,9 @@ ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
fixup. We pick the right reloc code depending on the byteorder
currently in effect. */
void
-ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp)
+ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp,
+ bfd_reloc_code_real_type code)
{
- bfd_reloc_code_real_type code;
fixS *fix;
switch (nbytes)
diff --git a/binutils-2.25/gas/config/tc-ia64.h b/binutils-2.25/gas/config/tc-ia64.h
index 7cade496..6884c59e 100644
--- a/binutils-2.25/gas/config/tc-ia64.h
+++ b/binutils-2.25/gas/config/tc-ia64.h
@@ -1,6 +1,5 @@
/* tc-ia64.h -- Header file for tc-ia64.c.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of GAS, the GNU Assembler.
@@ -107,7 +106,8 @@ extern void ia64_cons_align (int);
extern void ia64_flush_insns (void);
extern int ia64_fix_adjustable (struct fix *);
extern int ia64_force_relocation (struct fix *);
-extern void ia64_cons_fix_new (fragS *, int, int, expressionS *);
+extern void ia64_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
extern void ia64_validate_fix (struct fix *);
extern char * ia64_canonicalize_symbol_name (char *);
extern bfd_vma ia64_elf_section_letter (int, char **);
@@ -149,7 +149,7 @@ extern void ia64_convert_frag (fragS *);
#define md_elf_section_flags ia64_elf_section_flags
#define TC_FIX_TYPE struct ia64_fix
#define TC_INIT_FIX_DATA(f) { f->tc_fix_data.opnd = 0; }
-#define TC_CONS_FIX_NEW(f,o,l,e) ia64_cons_fix_new (f, o, l, e)
+#define TC_CONS_FIX_NEW(f,o,l,e,r) ia64_cons_fix_new (f, o, l, e, r)
#define TC_VALIDATE_FIX(fix,seg,skip) ia64_validate_fix (fix)
#define MD_PCREL_FROM_SECTION(fix,sec) ia64_pcrel_from_section (fix, sec)
#define md_section_align(seg,size) (size)
diff --git a/binutils-2.25/gas/config/tc-ip2k.c b/binutils-2.25/gas/config/tc-ip2k.c
index 3836cc9e..9c8c22ce 100644
--- a/binutils-2.25/gas/config/tc-ip2k.c
+++ b/binutils-2.25/gas/config/tc-ip2k.c
@@ -1,6 +1,5 @@
/* tc-ip2k.c -- Assembler for the Scenix IP2xxx.
- Copyright (C) 2000, 2002, 2003, 2005, 2006, 2007, 2009
- Free Software Foundation. Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-ip2k.h b/binutils-2.25/gas/config/tc-ip2k.h
index 01efdc2e..c33ab2b0 100644
--- a/binutils-2.25/gas/config/tc-ip2k.h
+++ b/binutils-2.25/gas/config/tc-ip2k.h
@@ -1,5 +1,5 @@
/* tc-ip2k.h -- Header file for tc-ip2k.c.
- Copyright (C) 2000, 2002, 2005, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-iq2000.c b/binutils-2.25/gas/config/tc-iq2000.c
index e8ed21d6..7939abc2 100644
--- a/binutils-2.25/gas/config/tc-iq2000.c
+++ b/binutils-2.25/gas/config/tc-iq2000.c
@@ -1,6 +1,5 @@
/* tc-iq2000.c -- Assembler for the Sitera IQ2000.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010
- Free Software Foundation. Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-iq2000.h b/binutils-2.25/gas/config/tc-iq2000.h
index 0b1de12f..ab4f8774 100644
--- a/binutils-2.25/gas/config/tc-iq2000.h
+++ b/binutils-2.25/gas/config/tc-iq2000.h
@@ -1,5 +1,5 @@
/* tc-iq2000.h -- Header file for tc-iq2000.c.
- Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-lm32.c b/binutils-2.25/gas/config/tc-lm32.c
index 88ffabb5..07c8c827 100644
--- a/binutils-2.25/gas/config/tc-lm32.c
+++ b/binutils-2.25/gas/config/tc-lm32.c
@@ -1,5 +1,5 @@
/* tc-lm32.c - Lattice Mico32 assembler.
- Copyright 2008, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
Contributed by Jon Beniston <jon@beniston.com>
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-lm32.h b/binutils-2.25/gas/config/tc-lm32.h
index dbba939d..295efc10 100644
--- a/binutils-2.25/gas/config/tc-lm32.h
+++ b/binutils-2.25/gas/config/tc-lm32.h
@@ -1,5 +1,5 @@
/* tc-lm32.h -- Header file for tc-lm32.c
- Copyright 2008 Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
Contributed by Jon Beniston <jon@beniston.com>
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-m32c.c b/binutils-2.25/gas/config/tc-m32c.c
index 9c523e27..8e24edbf 100644
--- a/binutils-2.25/gas/config/tc-m32c.c
+++ b/binutils-2.25/gas/config/tc-m32c.c
@@ -1,5 +1,5 @@
/* tc-m32c.c -- Assembler for the Renesas M32C.
- Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by RedHat.
This file is part of GAS, the GNU Assembler.
@@ -1019,10 +1019,9 @@ void
m32c_cons_fix_new (fragS * frag,
int where,
int size,
- expressionS *exp)
+ expressionS *exp,
+ bfd_reloc_code_real_type type)
{
- bfd_reloc_code_real_type type;
-
switch (size)
{
case 1:
diff --git a/binutils-2.25/gas/config/tc-m32c.h b/binutils-2.25/gas/config/tc-m32c.h
index b69ab506..3af0092b 100644
--- a/binutils-2.25/gas/config/tc-m32c.h
+++ b/binutils-2.25/gas/config/tc-m32c.h
@@ -1,6 +1,5 @@
/* tc-m32c.h -- Header file for tc-m32c.c.
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -58,9 +57,10 @@ extern bfd_boolean m32c_fix_adjustable (struct fix *);
#define TC_FORCE_RELOCATION(fix) m32c_force_relocation (fix)
extern int m32c_force_relocation (struct fix *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
- m32c_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
-extern void m32c_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \
+ m32c_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC)
+extern void m32c_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
extern const struct relax_type md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table
diff --git a/binutils-2.25/gas/config/tc-m32r.c b/binutils-2.25/gas/config/tc-m32r.c
index c8a6584d..172b8f99 100644
--- a/binutils-2.25/gas/config/tc-m32r.c
+++ b/binutils-2.25/gas/config/tc-m32r.c
@@ -1,6 +1,5 @@
/* tc-m32r.c -- Assembler for the Renesas M32R.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2009, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-m32r.h b/binutils-2.25/gas/config/tc-m32r.h
index 32657122..892b3abb 100644
--- a/binutils-2.25/gas/config/tc-m32r.h
+++ b/binutils-2.25/gas/config/tc-m32r.h
@@ -1,6 +1,5 @@
/* tc-m32r.h -- Header file for tc-m32r.c.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007, 2009, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-m68851.h b/binutils-2.25/gas/config/tc-m68851.h
index 79121f17..7c449d6a 100644
--- a/binutils-2.25/gas/config/tc-m68851.h
+++ b/binutils-2.25/gas/config/tc-m68851.h
@@ -1,7 +1,6 @@
/* This file is tc-m68851.h
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-m68hc11.c b/binutils-2.25/gas/config/tc-m68hc11.c
index 3189121c..36419123 100644
--- a/binutils-2.25/gas/config/tc-m68hc11.c
+++ b/binutils-2.25/gas/config/tc-m68hc11.c
@@ -1,7 +1,5 @@
/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
- 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@nerim.fr)
XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
diff --git a/binutils-2.25/gas/config/tc-m68hc11.h b/binutils-2.25/gas/config/tc-m68hc11.h
index 51c489cc..59079dd6 100644
--- a/binutils-2.25/gas/config/tc-m68hc11.h
+++ b/binutils-2.25/gas/config/tc-m68hc11.h
@@ -1,6 +1,5 @@
/* tc-m68hc11.h -- Header file for tc-m68hc11.c.
- Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-m68k.c b/binutils-2.25/gas/config/tc-m68k.c
index d16b5d97..7fc4efeb 100644
--- a/binutils-2.25/gas/config/tc-m68k.c
+++ b/binutils-2.25/gas/config/tc-m68k.c
@@ -1,7 +1,5 @@
/* tc-m68k.c -- Assemble for the m68k family
- Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -4513,7 +4511,8 @@ md_assemble (char *str)
(relax_substateT) (the_ins.fragb[n].fragty),
the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
}
- n = (the_ins.numo - the_ins.fragb[n - 1].fragoff);
+ gas_assert (the_ins.nfrag >= 1);
+ n = the_ins.numo - the_ins.fragb[the_ins.nfrag - 1].fragoff;
shorts_this_frag = 0;
if (n)
{
@@ -5168,10 +5167,6 @@ md_convert_frag_1 (fragS *fragP)
/* Only DBcc instructions can come here.
Change dbcc into dbcc/bral.
JF: these used to be fr_opcode[2-7], but that's wrong. */
- if (flag_keep_pcrel)
- as_bad_where (fragP->fr_file, fragP->fr_line,
- _("Conversion of DBcc to absolute jump"));
-
*buffer_address++ = 0x00; /* Branch offset = 4. */
*buffer_address++ = 0x04;
*buffer_address++ = 0x60; /* Put in bra pc+6. */
diff --git a/binutils-2.25/gas/config/tc-m68k.h b/binutils-2.25/gas/config/tc-m68k.h
index bf938f26..3978b6a2 100644
--- a/binutils-2.25/gas/config/tc-m68k.h
+++ b/binutils-2.25/gas/config/tc-m68k.h
@@ -1,7 +1,5 @@
/* This file is tc-m68k.h
- Copyright 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mcore.c b/binutils-2.25/gas/config/tc-mcore.c
index 04cf3361..d111eda7 100644
--- a/binutils-2.25/gas/config/tc-mcore.c
+++ b/binutils-2.25/gas/config/tc-mcore.c
@@ -1,6 +1,5 @@
/* tc-mcore.c -- Assemble code for M*Core
- Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mcore.h b/binutils-2.25/gas/config/tc-mcore.h
index 36087c63..3437e009 100644
--- a/binutils-2.25/gas/config/tc-mcore.h
+++ b/binutils-2.25/gas/config/tc-mcore.h
@@ -1,7 +1,6 @@
/* This file is tc-mcore.h
- Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mep.c b/binutils-2.25/gas/config/tc-mep.c
index 377e4c3f..cb068817 100644
--- a/binutils-2.25/gas/config/tc-mep.c
+++ b/binutils-2.25/gas/config/tc-mep.c
@@ -1,6 +1,5 @@
/* tc-mep.c -- Assembler for the Toshiba Media Processor.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009, 2012
- Free Software Foundation. Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mep.h b/binutils-2.25/gas/config/tc-mep.h
index 59f83b05..0df5de88 100644
--- a/binutils-2.25/gas/config/tc-mep.h
+++ b/binutils-2.25/gas/config/tc-mep.h
@@ -1,5 +1,5 @@
/* tc-mep.h -- Header file for tc-mep.c.
- Copyright (C) 2001, 2002, 2005, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-metag.c b/binutils-2.25/gas/config/tc-metag.c
index f42d2f18..cb2fc991 100644
--- a/binutils-2.25/gas/config/tc-metag.c
+++ b/binutils-2.25/gas/config/tc-metag.c
@@ -1,5 +1,5 @@
/* tc-metag.c -- Assembler for the Imagination Technologies Meta.
- Copyright (C) 2013 Free Software Foundation, Inc.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
Contributed by Imagination Technologies Ltd.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-metag.h b/binutils-2.25/gas/config/tc-metag.h
index e0411f56..10a2c7bb 100644
--- a/binutils-2.25/gas/config/tc-metag.h
+++ b/binutils-2.25/gas/config/tc-metag.h
@@ -1,5 +1,5 @@
/* tc-metag.h -- Header file for tc-metag.c.
- Copyright (C) 2013 Free Software Foundation, Inc.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
Contributed by Imagination Technologies Ltd.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-microblaze.c b/binutils-2.25/gas/config/tc-microblaze.c
index 872737b3..cf4ee44f 100644
--- a/binutils-2.25/gas/config/tc-microblaze.c
+++ b/binutils-2.25/gas/config/tc-microblaze.c
@@ -1,6 +1,6 @@
/* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
- Copyright 2009, 2010, 2012 Free Software Foundation.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -802,7 +802,7 @@ check_got (int * got_type, int * got_len)
return tmpbuf;
}
-extern void
+extern bfd_reloc_code_real_type
parse_cons_expression_microblaze (expressionS *exp, int size)
{
if (size == 4)
@@ -828,6 +828,7 @@ parse_cons_expression_microblaze (expressionS *exp, int size)
}
else
expression (exp);
+ return BFD_RELOC_NONE;
}
/* This is the guts of the machine-dependent assembler. STR points to a
@@ -2485,11 +2486,9 @@ void
cons_fix_new_microblaze (fragS * frag,
int where,
int size,
- expressionS *exp)
+ expressionS *exp,
+ bfd_reloc_code_real_type r)
{
-
- bfd_reloc_code_real_type r;
-
if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
(exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
&& (!S_IS_LOCAL (exp->X_op_symbol)))
diff --git a/binutils-2.25/gas/config/tc-microblaze.h b/binutils-2.25/gas/config/tc-microblaze.h
index 06510400..d44f2fae 100644
--- a/binutils-2.25/gas/config/tc-microblaze.h
+++ b/binutils-2.25/gas/config/tc-microblaze.h
@@ -1,6 +1,6 @@
/* tc-microblaze.h -- Header file for tc-microblaze.c.
- Copyright 2009 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -36,8 +36,10 @@
relocs for such expressions as -relax in linker can change the value
of such expressions */
#define TC_CONS_FIX_NEW cons_fix_new_microblaze
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_microblaze (EXP, NBYTES)
-extern void parse_cons_expression_microblaze PARAMS ((expressionS *, int));
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+ parse_cons_expression_microblaze (EXP, NBYTES)
+extern bfd_reloc_code_real_type parse_cons_expression_microblaze
+ (expressionS *, int);
#define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) 1
#define UNDEFINED_DIFFERENCE_OK 1
@@ -108,7 +110,9 @@ extern void md_number_to_chars (char *, valueT, int);
extern valueT md_section_align (segT, valueT);
extern long md_pcrel_from_section (fixS *, segT);
extern arelent * tc_gen_reloc (asection *, fixS *);
-extern void cons_fix_new_microblaze (fragS *, int, int, expressionS *);
+extern void cons_fix_new_microblaze (fragS *, int, int,
+ expressionS *,
+ bfd_reloc_code_real_type);
extern void md_apply_fix3 (fixS *, valueT *, segT);
#define EXTERN_FORCE_RELOC -1
diff --git a/binutils-2.25/gas/config/tc-mips.c b/binutils-2.25/gas/config/tc-mips.c
index 08ad7bab..cfc4fa54 100644
--- a/binutils-2.25/gas/config/tc-mips.c
+++ b/binutils-2.25/gas/config/tc-mips.c
@@ -1,7 +1,5 @@
/* tc-mips.c -- assemble code for a MIPS chip.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
- Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
@@ -44,6 +42,8 @@ typedef char static_assert2[sizeof (valueT) < 8 ? -1 : 1];
#define DBG(x)
#endif
+#define streq(a, b) (strcmp (a, b) == 0)
+
#define SKIP_SPACE_TABS(S) \
do { while (*(S) == ' ' || *(S) == '\t') ++(S); } while (0)
@@ -89,6 +89,7 @@ int mips_flag_pdr = TRUE;
#include "ecoff.h"
static char *mips_regmask_frag;
+static char *mips_flags_frag;
#define ZERO 0
#define ATREG 1
@@ -241,8 +242,8 @@ struct mips_set_options
/* Restrict general purpose registers and floating point registers
to 32 bit. This is initially determined when -mgp32 or -mfp32
is passed but can changed if the assembler code uses .set mipsN. */
- int gp32;
- int fp32;
+ int gp;
+ int fp;
/* MIPS architecture (CPU) type. Changed by .set arch=FOO, the -march
command line option, and the default CPU. */
int arch;
@@ -257,40 +258,45 @@ struct mips_set_options
Changed by .set singlefloat or .set doublefloat, command-line options
-msingle-float or -mdouble-float. The default is false. */
bfd_boolean single_float;
-};
-/* This is the struct we use to hold the current set of options. Note
- that we must set the isa field to ISA_UNKNOWN and the ASE fields to
- -1 to indicate that they have not been initialized. */
+ /* 1 if single-precision operations on odd-numbered registers are
+ allowed. */
+ int oddspreg;
+};
-/* True if -mgp32 was passed. */
-static int file_mips_gp32 = -1;
+/* Specifies whether module level options have been checked yet. */
+static bfd_boolean file_mips_opts_checked = FALSE;
-/* True if -mfp32 was passed. */
-static int file_mips_fp32 = -1;
+/* Do we support nan2008? 0 if we don't, 1 if we do, and -1 if the
+ value has not been initialized. Changed by `.nan legacy' and
+ `.nan 2008', and the -mnan=legacy and -mnan=2008 command line
+ options, and the default CPU. */
+static int mips_nan2008 = -1;
-/* 1 if -msoft-float, 0 if -mhard-float. The default is 0. */
-static int file_mips_soft_float = 0;
+/* This is the struct we use to hold the module level set of options.
+ Note that we must set the isa field to ISA_UNKNOWN and the ASE, gp and
+ fp fields to -1 to indicate that they have not been initialized. */
-/* 1 if -msingle-float, 0 if -mdouble-float. The default is 0. */
-static int file_mips_single_float = 0;
+static struct mips_set_options file_mips_opts =
+{
+ /* isa */ ISA_UNKNOWN, /* ase */ 0, /* mips16 */ -1, /* micromips */ -1,
+ /* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
+ /* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* insn32 */ FALSE,
+ /* gp */ -1, /* fp */ -1, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
+ /* soft_float */ FALSE, /* single_float */ FALSE, /* oddspreg */ -1
+};
-/* True if -mnan=2008, false if -mnan=legacy. */
-static bfd_boolean mips_flag_nan2008 = FALSE;
+/* This is similar to file_mips_opts, but for the current set of options. */
static struct mips_set_options mips_opts =
{
/* isa */ ISA_UNKNOWN, /* ase */ 0, /* mips16 */ -1, /* micromips */ -1,
/* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
/* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* insn32 */ FALSE,
- /* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
- /* soft_float */ FALSE, /* single_float */ FALSE
+ /* gp */ -1, /* fp */ -1, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
+ /* soft_float */ FALSE, /* single_float */ FALSE, /* oddspreg */ -1
};
-/* The set of ASEs that were selected on the command line, either
- explicitly via ASE options or implicitly through things like -march. */
-static unsigned int file_ase;
-
/* Which bits of file_ase were explicitly set or cleared by ASE options. */
static unsigned int file_ase_explicit;
@@ -300,16 +306,17 @@ static unsigned int file_ase_explicit;
unsigned long mips_gprmask;
unsigned long mips_cprmask[4];
-/* MIPS ISA we are using for this output file. */
-static int file_mips_isa = ISA_UNKNOWN;
-
/* True if any MIPS16 code was produced. */
static int file_ase_mips16;
#define ISA_SUPPORTS_MIPS16E (mips_opts.isa == ISA_MIPS32 \
|| mips_opts.isa == ISA_MIPS32R2 \
+ || mips_opts.isa == ISA_MIPS32R3 \
+ || mips_opts.isa == ISA_MIPS32R5 \
|| mips_opts.isa == ISA_MIPS64 \
- || mips_opts.isa == ISA_MIPS64R2)
+ || mips_opts.isa == ISA_MIPS64R2 \
+ || mips_opts.isa == ISA_MIPS64R3 \
+ || mips_opts.isa == ISA_MIPS64R5)
/* True if any microMIPS code was produced. */
static int file_ase_micromips;
@@ -327,7 +334,6 @@ static int file_ase_micromips;
#endif
/* The argument of the -march= flag. The architecture we are assembling. */
-static int file_mips_arch = CPU_UNKNOWN;
static const char *mips_arch_string;
/* The argument of the -mtune= flag. The architecture for which we
@@ -347,13 +353,20 @@ static int mips_32bitmode = 0;
|| (ABI) == N64_ABI \
|| (ABI) == O64_ABI)
+#define ISA_IS_R6(ISA) \
+ ((ISA) == ISA_MIPS32R6 \
+ || (ISA) == ISA_MIPS64R6)
+
/* Return true if ISA supports 64 bit wide gp registers. */
#define ISA_HAS_64BIT_REGS(ISA) \
((ISA) == ISA_MIPS3 \
|| (ISA) == ISA_MIPS4 \
|| (ISA) == ISA_MIPS5 \
|| (ISA) == ISA_MIPS64 \
- || (ISA) == ISA_MIPS64R2)
+ || (ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5 \
+ || (ISA) == ISA_MIPS64R6)
/* Return true if ISA supports 64 bit wide float registers. */
#define ISA_HAS_64BIT_FPRS(ISA) \
@@ -361,13 +374,22 @@ static int mips_32bitmode = 0;
|| (ISA) == ISA_MIPS4 \
|| (ISA) == ISA_MIPS5 \
|| (ISA) == ISA_MIPS32R2 \
+ || (ISA) == ISA_MIPS32R3 \
+ || (ISA) == ISA_MIPS32R5 \
+ || (ISA) == ISA_MIPS32R6 \
|| (ISA) == ISA_MIPS64 \
- || (ISA) == ISA_MIPS64R2)
+ || (ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5 \
+ || (ISA) == ISA_MIPS64R6)
/* Return true if ISA supports 64-bit right rotate (dror et al.)
instructions. */
#define ISA_HAS_DROR(ISA) \
((ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5 \
+ || (ISA) == ISA_MIPS64R6 \
|| (mips_opts.micromips \
&& ISA_HAS_64BIT_REGS (ISA)) \
)
@@ -376,32 +398,69 @@ static int mips_32bitmode = 0;
instructions. */
#define ISA_HAS_ROR(ISA) \
((ISA) == ISA_MIPS32R2 \
+ || (ISA) == ISA_MIPS32R3 \
+ || (ISA) == ISA_MIPS32R5 \
+ || (ISA) == ISA_MIPS32R6 \
|| (ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5 \
+ || (ISA) == ISA_MIPS64R6 \
|| (mips_opts.ase & ASE_SMARTMIPS) \
|| mips_opts.micromips \
)
/* Return true if ISA supports single-precision floats in odd registers. */
-#define ISA_HAS_ODD_SINGLE_FPR(ISA) \
- ((ISA) == ISA_MIPS32 \
- || (ISA) == ISA_MIPS32R2 \
- || (ISA) == ISA_MIPS64 \
- || (ISA) == ISA_MIPS64R2)
+#define ISA_HAS_ODD_SINGLE_FPR(ISA, CPU)\
+ (((ISA) == ISA_MIPS32 \
+ || (ISA) == ISA_MIPS32R2 \
+ || (ISA) == ISA_MIPS32R3 \
+ || (ISA) == ISA_MIPS32R5 \
+ || (ISA) == ISA_MIPS32R6 \
+ || (ISA) == ISA_MIPS64 \
+ || (ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5 \
+ || (ISA) == ISA_MIPS64R6 \
+ || (CPU) == CPU_R5900) \
+ && (CPU) != CPU_LOONGSON_3A)
/* Return true if ISA supports move to/from high part of a 64-bit
floating-point register. */
#define ISA_HAS_MXHC1(ISA) \
((ISA) == ISA_MIPS32R2 \
- || (ISA) == ISA_MIPS64R2)
-
-#define HAVE_32BIT_GPRS \
- (mips_opts.gp32 || !ISA_HAS_64BIT_REGS (mips_opts.isa))
+ || (ISA) == ISA_MIPS32R3 \
+ || (ISA) == ISA_MIPS32R5 \
+ || (ISA) == ISA_MIPS32R6 \
+ || (ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5 \
+ || (ISA) == ISA_MIPS64R6)
+
+/* Return true if ISA supports legacy NAN. */
+#define ISA_HAS_LEGACY_NAN(ISA) \
+ ((ISA) == ISA_MIPS1 \
+ || (ISA) == ISA_MIPS2 \
+ || (ISA) == ISA_MIPS3 \
+ || (ISA) == ISA_MIPS4 \
+ || (ISA) == ISA_MIPS5 \
+ || (ISA) == ISA_MIPS32 \
+ || (ISA) == ISA_MIPS32R2 \
+ || (ISA) == ISA_MIPS32R3 \
+ || (ISA) == ISA_MIPS32R5 \
+ || (ISA) == ISA_MIPS64 \
+ || (ISA) == ISA_MIPS64R2 \
+ || (ISA) == ISA_MIPS64R3 \
+ || (ISA) == ISA_MIPS64R5)
-#define HAVE_32BIT_FPRS \
- (mips_opts.fp32 || !ISA_HAS_64BIT_FPRS (mips_opts.isa))
+#define GPR_SIZE \
+ (mips_opts.gp == 64 && !ISA_HAS_64BIT_REGS (mips_opts.isa) \
+ ? 32 \
+ : mips_opts.gp)
-#define HAVE_64BIT_GPRS (!HAVE_32BIT_GPRS)
-#define HAVE_64BIT_FPRS (!HAVE_32BIT_FPRS)
+#define FPR_SIZE \
+ (mips_opts.fp == 64 && !ISA_HAS_64BIT_FPRS (mips_opts.isa) \
+ ? 32 \
+ : mips_opts.fp)
#define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI)
@@ -412,7 +471,7 @@ static int mips_32bitmode = 0;
/* The ABI-derived address size. */
#define HAVE_64BIT_ADDRESSES \
- (HAVE_64BIT_GPRS && (mips_abi == EABI_ABI || mips_abi == N64_ABI))
+ (GPR_SIZE == 64 && (mips_abi == EABI_ABI || mips_abi == N64_ABI))
#define HAVE_32BIT_ADDRESSES (!HAVE_64BIT_ADDRESSES)
/* The size of symbolic constants (i.e., expressions of the form
@@ -475,8 +534,14 @@ static int mips_32bitmode = 0;
#define hilo_interlocks \
(mips_opts.isa == ISA_MIPS32 \
|| mips_opts.isa == ISA_MIPS32R2 \
+ || mips_opts.isa == ISA_MIPS32R3 \
+ || mips_opts.isa == ISA_MIPS32R5 \
+ || mips_opts.isa == ISA_MIPS32R6 \
|| mips_opts.isa == ISA_MIPS64 \
|| mips_opts.isa == ISA_MIPS64R2 \
+ || mips_opts.isa == ISA_MIPS64R3 \
+ || mips_opts.isa == ISA_MIPS64R5 \
+ || mips_opts.isa == ISA_MIPS64R6 \
|| mips_opts.arch == CPU_R4010 \
|| mips_opts.arch == CPU_R5900 \
|| mips_opts.arch == CPU_R10000 \
@@ -491,7 +556,7 @@ static int mips_32bitmode = 0;
/* Whether the processor uses hardware interlocks to protect reads
from the GPRs after they are loaded from memory, and thus does not
require nops to be inserted. This applies to instructions marked
- INSN_LOAD_MEMORY_DELAY. These nops are only required at MIPS ISA
+ INSN_LOAD_MEMORY. These nops are only required at MIPS ISA
level I and microMIPS mode instructions are always interlocked. */
#define gpr_interlocks \
(mips_opts.isa != ISA_MIPS1 \
@@ -503,8 +568,8 @@ static int mips_32bitmode = 0;
/* Whether the processor uses hardware interlocks to avoid delays
required by coprocessor instructions, and thus does not require
nops to be inserted. This applies to instructions marked
- INSN_LOAD_COPROC_DELAY, INSN_COPROC_MOVE_DELAY, and to delays
- between instructions marked INSN_WRITE_COND_CODE and ones marked
+ INSN_LOAD_COPROC, INSN_COPROC_MOVE, and to delays between
+ instructions marked INSN_WRITE_COND_CODE and ones marked
INSN_READ_COND_CODE. These nops are only required at MIPS ISA
levels I, II, and III and microMIPS mode instructions are always
interlocked. */
@@ -539,7 +604,7 @@ static int mips_32bitmode = 0;
((mips_opts.mips16 | mips_opts.micromips) != 0)
/* The minimum and maximum signed values that can be stored in a GPR. */
-#define GPR_SMAX ((offsetT) (((valueT) 1 << (HAVE_64BIT_GPRS ? 63 : 31)) - 1))
+#define GPR_SMAX ((offsetT) (((valueT) 1 << (GPR_SIZE - 1)) - 1))
#define GPR_SMIN (-GPR_SMAX - 1)
/* MIPS PIC level. */
@@ -865,6 +930,9 @@ static int mips_fix_vr4130;
/* ...likewise -mfix-24k. */
static int mips_fix_24k;
+/* ...likewise -mfix-rm7000 */
+static int mips_fix_rm7000;
+
/* ...likewise -mfix-cn63xxp1 */
static bfd_boolean mips_fix_cn63xxp1;
@@ -1268,8 +1336,7 @@ static void s_ehword (int);
static void s_cpadd (int);
static void s_insn (int);
static void s_nan (int);
-static void md_obj_begin (void);
-static void md_obj_end (void);
+static void s_module (int);
static void s_mips_ent (int);
static void s_mips_end (int);
static void s_mips_frame (int);
@@ -1282,6 +1349,7 @@ static bfd_boolean pic_need_relax (symbolS *, asection *);
static int relaxed_branch_length (fragS *, asection *, int);
static int relaxed_micromips_16bit_branch_length (fragS *, asection *, int);
static int relaxed_micromips_32bit_branch_length (fragS *, asection *, int);
+static void file_mips_check_options (void);
/* Table and functions used to map between CPU/ISA names, and
ISA levels, and CPU numbers. */
@@ -1316,7 +1384,13 @@ enum options
OPTION_MIPS32,
OPTION_MIPS64,
OPTION_MIPS32R2,
+ OPTION_MIPS32R3,
+ OPTION_MIPS32R5,
+ OPTION_MIPS32R6,
OPTION_MIPS64R2,
+ OPTION_MIPS64R3,
+ OPTION_MIPS64R5,
+ OPTION_MIPS64R6,
OPTION_MIPS16,
OPTION_NO_MIPS16,
OPTION_MIPS3D,
@@ -1337,6 +1411,8 @@ enum options
OPTION_NO_DSPR2,
OPTION_EVA,
OPTION_NO_EVA,
+ OPTION_XPA,
+ OPTION_NO_XPA,
OPTION_MICROMIPS,
OPTION_NO_MICROMIPS,
OPTION_MCU,
@@ -1354,6 +1430,8 @@ enum options
OPTION_MNO_7000_HILO_FIX,
OPTION_FIX_24K,
OPTION_NO_FIX_24K,
+ OPTION_FIX_RM7000,
+ OPTION_NO_FIX_RM7000,
OPTION_FIX_LOONGSON2F_JUMP,
OPTION_NO_FIX_LOONGSON2F_JUMP,
OPTION_FIX_LOONGSON2F_NOP,
@@ -1373,6 +1451,7 @@ enum options
OPTION_CONSTRUCT_FLOATS,
OPTION_NO_CONSTRUCT_FLOATS,
OPTION_FP64,
+ OPTION_FPXX,
OPTION_GP64,
OPTION_RELAX_BRANCH,
OPTION_NO_RELAX_BRANCH,
@@ -1400,6 +1479,8 @@ enum options
OPTION_NO_PDR,
OPTION_MVXWORKS_PIC,
OPTION_NAN,
+ OPTION_ODD_SPREG,
+ OPTION_NO_ODD_SPREG,
OPTION_END_OF_ENUM
};
@@ -1417,7 +1498,13 @@ struct option md_longopts[] =
{"mips32", no_argument, NULL, OPTION_MIPS32},
{"mips64", no_argument, NULL, OPTION_MIPS64},
{"mips32r2", no_argument, NULL, OPTION_MIPS32R2},
+ {"mips32r3", no_argument, NULL, OPTION_MIPS32R3},
+ {"mips32r5", no_argument, NULL, OPTION_MIPS32R5},
+ {"mips32r6", no_argument, NULL, OPTION_MIPS32R6},
{"mips64r2", no_argument, NULL, OPTION_MIPS64R2},
+ {"mips64r3", no_argument, NULL, OPTION_MIPS64R3},
+ {"mips64r5", no_argument, NULL, OPTION_MIPS64R5},
+ {"mips64r6", no_argument, NULL, OPTION_MIPS64R6},
/* Options which specify Application Specific Extensions (ASEs). */
{"mips16", no_argument, NULL, OPTION_MIPS16},
@@ -1444,6 +1531,8 @@ struct option md_longopts[] =
{"mno-virt", no_argument, NULL, OPTION_NO_VIRT},
{"mmsa", no_argument, NULL, OPTION_MSA},
{"mno-msa", no_argument, NULL, OPTION_NO_MSA},
+ {"mxpa", no_argument, NULL, OPTION_XPA},
+ {"mno-xpa", no_argument, NULL, OPTION_NO_XPA},
/* Old-style architecture options. Don't add more of these. */
{"m4650", no_argument, NULL, OPTION_M4650},
@@ -1469,6 +1558,8 @@ struct option md_longopts[] =
{"mno-fix-vr4130", no_argument, NULL, OPTION_NO_FIX_VR4130},
{"mfix-24k", no_argument, NULL, OPTION_FIX_24K},
{"mno-fix-24k", no_argument, NULL, OPTION_NO_FIX_24K},
+ {"mfix-rm7000", no_argument, NULL, OPTION_FIX_RM7000},
+ {"mno-fix-rm7000", no_argument, NULL, OPTION_NO_FIX_RM7000},
{"mfix-cn63xxp1", no_argument, NULL, OPTION_FIX_CN63XXP1},
{"mno-fix-cn63xxp1", no_argument, NULL, OPTION_NO_FIX_CN63XXP1},
@@ -1484,6 +1575,7 @@ struct option md_longopts[] =
{"construct-floats", no_argument, NULL, OPTION_CONSTRUCT_FLOATS},
{"no-construct-floats", no_argument, NULL, OPTION_NO_CONSTRUCT_FLOATS},
{"mfp64", no_argument, NULL, OPTION_FP64},
+ {"mfpxx", no_argument, NULL, OPTION_FPXX},
{"mgp64", no_argument, NULL, OPTION_GP64},
{"relax-branch", no_argument, NULL, OPTION_RELAX_BRANCH},
{"no-relax-branch", no_argument, NULL, OPTION_NO_RELAX_BRANCH},
@@ -1497,6 +1589,8 @@ struct option md_longopts[] =
{"mhard-float", no_argument, NULL, OPTION_HARD_FLOAT},
{"msingle-float", no_argument, NULL, OPTION_SINGLE_FLOAT},
{"mdouble-float", no_argument, NULL, OPTION_DOUBLE_FLOAT},
+ {"modd-spreg", no_argument, NULL, OPTION_ODD_SPREG},
+ {"mno-odd-spreg", no_argument, NULL, OPTION_NO_ODD_SPREG},
/* Strictly speaking this next option is ELF specific,
but we allow it for other ports as well in order to
@@ -1550,55 +1644,74 @@ struct mips_ase
int mips64_rev;
int micromips32_rev;
int micromips64_rev;
+
+ /* The architecture where the ASE was removed or -1 if the extension has not
+ been removed. */
+ int rem_rev;
};
/* A table of all supported ASEs. */
static const struct mips_ase mips_ases[] = {
{ "dsp", ASE_DSP, ASE_DSP64,
OPTION_DSP, OPTION_NO_DSP,
- 2, 2, 2, 2 },
+ 2, 2, 2, 2,
+ -1 },
{ "dspr2", ASE_DSP | ASE_DSPR2, 0,
OPTION_DSPR2, OPTION_NO_DSPR2,
- 2, 2, 2, 2 },
+ 2, 2, 2, 2,
+ -1 },
{ "eva", ASE_EVA, 0,
OPTION_EVA, OPTION_NO_EVA,
- 2, 2, 2, 2 },
+ 2, 2, 2, 2,
+ -1 },
{ "mcu", ASE_MCU, 0,
OPTION_MCU, OPTION_NO_MCU,
- 2, 2, 2, 2 },
+ 2, 2, 2, 2,
+ -1 },
/* Deprecated in MIPS64r5, but we don't implement that yet. */
{ "mdmx", ASE_MDMX, 0,
OPTION_MDMX, OPTION_NO_MDMX,
- -1, 1, -1, -1 },
+ -1, 1, -1, -1,
+ 6 },
/* Requires 64-bit FPRs, so the minimum MIPS32 revision is 2. */
{ "mips3d", ASE_MIPS3D, 0,
OPTION_MIPS3D, OPTION_NO_MIPS3D,
- 2, 1, -1, -1 },
+ 2, 1, -1, -1,
+ 6 },
{ "mt", ASE_MT, 0,
OPTION_MT, OPTION_NO_MT,
- 2, 2, -1, -1 },
+ 2, 2, -1, -1,
+ -1 },
{ "smartmips", ASE_SMARTMIPS, 0,
OPTION_SMARTMIPS, OPTION_NO_SMARTMIPS,
- 1, -1, -1, -1 },
+ 1, -1, -1, -1,
+ 6 },
{ "virt", ASE_VIRT, ASE_VIRT64,
OPTION_VIRT, OPTION_NO_VIRT,
- 2, 2, 2, 2 },
+ 2, 2, 2, 2,
+ -1 },
{ "msa", ASE_MSA, ASE_MSA64,
OPTION_MSA, OPTION_NO_MSA,
- 2, 2, 2, 2 }
+ 2, 2, 2, 2,
+ -1 },
+
+ { "xpa", ASE_XPA, 0,
+ OPTION_XPA, OPTION_NO_XPA,
+ 2, 2, -1, -1,
+ -1 },
};
/* The set of ASEs that require -mfp64. */
-#define FP64_ASES (ASE_MIPS3D | ASE_MDMX)
+#define FP64_ASES (ASE_MIPS3D | ASE_MDMX | ASE_MSA)
/* Groups of ASE_* flags that represent different revisions of an ASE. */
static const unsigned int mips_ase_groups[] = {
@@ -1647,6 +1760,7 @@ static const pseudo_typeS mips_pseudo_table[] =
{"cpadd", s_cpadd, 0},
{"insn", s_insn, 0},
{"nan", s_nan, 0},
+ {"module", s_module, 0},
/* Relatively generic pseudo-ops that happen to be used on MIPS
chips. */
@@ -1714,6 +1828,7 @@ static const pseudo_typeS mips_nonecoff_pseudo_table[] =
int
mips_address_bytes (void)
{
+ file_mips_check_options ();
return HAVE_64BIT_ADDRESSES ? 8 : 4;
}
@@ -1848,6 +1963,15 @@ mips_isa_rev (void)
if (mips_opts.isa == ISA_MIPS32R2 || mips_opts.isa == ISA_MIPS64R2)
return 2;
+ if (mips_opts.isa == ISA_MIPS32R3 || mips_opts.isa == ISA_MIPS64R3)
+ return 3;
+
+ if (mips_opts.isa == ISA_MIPS32R5 || mips_opts.isa == ISA_MIPS64R5)
+ return 5;
+
+ if (mips_opts.isa == ISA_MIPS32R6 || mips_opts.isa == ISA_MIPS64R6)
+ return 6;
+
/* microMIPS implies revision 2 or above. */
if (mips_opts.micromips)
return 2;
@@ -1899,8 +2023,18 @@ mips_check_isa_supports_ase (const struct mips_ase *ase)
as_warn (_("the `%s' extension requires %s%d revision %d or greater"),
ase->name, base, size, min_rev);
}
+ else if ((ase->rem_rev > 0 && mips_isa_rev () >= ase->rem_rev)
+ && (warned_isa & ase->flags) != ase->flags)
+ {
+ warned_isa |= ase->flags;
+ base = mips_opts.micromips ? "microMIPS" : "MIPS";
+ size = ISA_HAS_64BIT_REGS (mips_opts.isa) ? 64 : 32;
+ as_warn (_("the `%s' extension was removed in %s%d revision %d"),
+ ase->name, base, size, ase->rem_rev);
+ }
+
if ((ase->flags & FP64_ASES)
- && mips_opts.fp32
+ && mips_opts.fp != 64
&& (warned_fp32 & ase->flags) != ase->flags)
{
warned_fp32 |= ase->flags;
@@ -1928,14 +2062,15 @@ mips_check_isa_supports_ases (void)
that were affected. */
static unsigned int
-mips_set_ase (const struct mips_ase *ase, bfd_boolean enabled_p)
+mips_set_ase (const struct mips_ase *ase, struct mips_set_options *opts,
+ bfd_boolean enabled_p)
{
unsigned int mask;
mask = mips_ase_mask (ase->flags);
- mips_opts.ase &= ~mask;
+ opts->ase &= ~mask;
if (enabled_p)
- mips_opts.ase |= ase->flags;
+ opts->ase |= ase->flags;
return mask;
}
@@ -3226,7 +3361,7 @@ validate_mips_insn (const struct mips_opcode *opcode,
used_bits &= ~(mask & 0x700);
}
/* Skip prefix characters. */
- if (decode_operand && (*s == '+' || *s == 'm'))
+ if (decode_operand && (*s == '+' || *s == 'm' || *s == '-'))
++s;
opno += 1;
break;
@@ -3331,7 +3466,7 @@ md_begin (void)
g_switch_value = 0;
}
- if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_arch))
+ if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
as_warn (_("could not set architecture and machine"));
op_hash = hash_new ();
@@ -3557,6 +3692,12 @@ md_begin (void)
}
}
+ sec = subseg_new (".MIPS.abiflags", (subsegT) 0);
+ bfd_set_section_flags (stdoutput, sec,
+ SEC_READONLY | SEC_DATA | SEC_ALLOC | SEC_LOAD);
+ bfd_set_section_alignment (stdoutput, sec, 3);
+ mips_flags_frag = frag_more (sizeof (Elf_External_ABIFlags_v0));
+
if (ECOFF_DEBUGGING)
{
sec = subseg_new (".mdebug", (subsegT) 0);
@@ -3576,19 +3717,263 @@ md_begin (void)
subseg_set (seg, subseg);
}
- if (! ECOFF_DEBUGGING)
- md_obj_begin ();
-
if (mips_fix_vr4120)
init_vr4120_conflicts ();
}
-void
-md_mips_end (void)
+static inline void
+fpabi_incompatible_with (int fpabi, const char *what)
{
- mips_emit_delays ();
- if (! ECOFF_DEBUGGING)
- md_obj_end ();
+ as_warn (_(".gnu_attribute %d,%d is incompatible with `%s'"),
+ Tag_GNU_MIPS_ABI_FP, fpabi, what);
+}
+
+static inline void
+fpabi_requires (int fpabi, const char *what)
+{
+ as_warn (_(".gnu_attribute %d,%d requires `%s'"),
+ Tag_GNU_MIPS_ABI_FP, fpabi, what);
+}
+
+/* Check -mabi and register sizes against the specified FP ABI. */
+static void
+check_fpabi (int fpabi)
+{
+ switch (fpabi)
+ {
+ case Val_GNU_MIPS_ABI_FP_DOUBLE:
+ if (file_mips_opts.soft_float)
+ fpabi_incompatible_with (fpabi, "softfloat");
+ else if (file_mips_opts.single_float)
+ fpabi_incompatible_with (fpabi, "singlefloat");
+ if (file_mips_opts.gp == 64 && file_mips_opts.fp == 32)
+ fpabi_incompatible_with (fpabi, "gp=64 fp=32");
+ else if (file_mips_opts.gp == 32 && file_mips_opts.fp == 64)
+ fpabi_incompatible_with (fpabi, "gp=32 fp=64");
+ break;
+
+ case Val_GNU_MIPS_ABI_FP_XX:
+ if (mips_abi != O32_ABI)
+ fpabi_requires (fpabi, "-mabi=32");
+ else if (file_mips_opts.soft_float)
+ fpabi_incompatible_with (fpabi, "softfloat");
+ else if (file_mips_opts.single_float)
+ fpabi_incompatible_with (fpabi, "singlefloat");
+ else if (file_mips_opts.fp != 0)
+ fpabi_requires (fpabi, "fp=xx");
+ break;
+
+ case Val_GNU_MIPS_ABI_FP_64A:
+ case Val_GNU_MIPS_ABI_FP_64:
+ if (mips_abi != O32_ABI)
+ fpabi_requires (fpabi, "-mabi=32");
+ else if (file_mips_opts.soft_float)
+ fpabi_incompatible_with (fpabi, "softfloat");
+ else if (file_mips_opts.single_float)
+ fpabi_incompatible_with (fpabi, "singlefloat");
+ else if (file_mips_opts.fp != 64)
+ fpabi_requires (fpabi, "fp=64");
+ else if (fpabi == Val_GNU_MIPS_ABI_FP_64 && !file_mips_opts.oddspreg)
+ fpabi_incompatible_with (fpabi, "nooddspreg");
+ else if (fpabi == Val_GNU_MIPS_ABI_FP_64A && file_mips_opts.oddspreg)
+ fpabi_requires (fpabi, "nooddspreg");
+ break;
+
+ case Val_GNU_MIPS_ABI_FP_SINGLE:
+ if (file_mips_opts.soft_float)
+ fpabi_incompatible_with (fpabi, "softfloat");
+ else if (!file_mips_opts.single_float)
+ fpabi_requires (fpabi, "singlefloat");
+ break;
+
+ case Val_GNU_MIPS_ABI_FP_SOFT:
+ if (!file_mips_opts.soft_float)
+ fpabi_requires (fpabi, "softfloat");
+ break;
+
+ case Val_GNU_MIPS_ABI_FP_OLD_64:
+ as_warn (_(".gnu_attribute %d,%d is no longer supported"),
+ Tag_GNU_MIPS_ABI_FP, fpabi);
+ break;
+
+ default:
+ as_warn (_(".gnu_attribute %d,%d is not a recognized"
+ " floating-point ABI"), Tag_GNU_MIPS_ABI_FP, fpabi);
+ break;
+ }
+}
+
+/* Perform consistency checks on the current options. */
+
+static void
+mips_check_options (struct mips_set_options *opts, bfd_boolean abi_checks)
+{
+ /* Check the size of integer registers agrees with the ABI and ISA. */
+ if (opts->gp == 64 && !ISA_HAS_64BIT_REGS (opts->isa))
+ as_bad (_("`gp=64' used with a 32-bit processor"));
+ else if (abi_checks
+ && opts->gp == 32 && ABI_NEEDS_64BIT_REGS (mips_abi))
+ as_bad (_("`gp=32' used with a 64-bit ABI"));
+ else if (abi_checks
+ && opts->gp == 64 && ABI_NEEDS_32BIT_REGS (mips_abi))
+ as_bad (_("`gp=64' used with a 32-bit ABI"));
+
+ /* Check the size of the float registers agrees with the ABI and ISA. */
+ switch (opts->fp)
+ {
+ case 0:
+ if (!CPU_HAS_LDC1_SDC1 (opts->arch))
+ as_bad (_("`fp=xx' used with a cpu lacking ldc1/sdc1 instructions"));
+ else if (opts->single_float == 1)
+ as_bad (_("`fp=xx' cannot be used with `singlefloat'"));
+ break;
+ case 64:
+ if (!ISA_HAS_64BIT_FPRS (opts->isa))
+ as_bad (_("`fp=64' used with a 32-bit fpu"));
+ else if (abi_checks
+ && ABI_NEEDS_32BIT_REGS (mips_abi)
+ && !ISA_HAS_MXHC1 (opts->isa))
+ as_warn (_("`fp=64' used with a 32-bit ABI"));
+ break;
+ case 32:
+ if (abi_checks
+ && ABI_NEEDS_64BIT_REGS (mips_abi))
+ as_warn (_("`fp=32' used with a 64-bit ABI"));
+ if (ISA_IS_R6 (mips_opts.isa) && opts->single_float == 0)
+ as_bad (_("`fp=32' used with a MIPS R6 cpu"));
+ break;
+ default:
+ as_bad (_("Unknown size of floating point registers"));
+ break;
+ }
+
+ if (ABI_NEEDS_64BIT_REGS (mips_abi) && !opts->oddspreg)
+ as_bad (_("`nooddspreg` cannot be used with a 64-bit ABI"));
+
+ if (opts->micromips == 1 && opts->mips16 == 1)
+ as_bad (_("`mips16' cannot be used with `micromips'"));
+ else if (ISA_IS_R6 (mips_opts.isa)
+ && (opts->micromips == 1
+ || opts->mips16 == 1))
+ as_fatal (_("`%s' can not be used with `%s'"),
+ opts->micromips ? "micromips" : "mips16",
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
+
+ if (ISA_IS_R6 (opts->isa) && mips_relax_branch)
+ as_fatal (_("branch relaxation is not supported in `%s'"),
+ mips_cpu_info_from_isa (opts->isa)->name);
+}
+
+/* Perform consistency checks on the module level options exactly once.
+ This is a deferred check that happens:
+ at the first .set directive
+ or, at the first pseudo op that generates code (inc .dc.a)
+ or, at the first instruction
+ or, at the end. */
+
+static void
+file_mips_check_options (void)
+{
+ const struct mips_cpu_info *arch_info = 0;
+
+ if (file_mips_opts_checked)
+ return;
+
+ /* The following code determines the register size.
+ Similar code was added to GCC 3.3 (see override_options() in
+ config/mips/mips.c). The GAS and GCC code should be kept in sync
+ as much as possible. */
+
+ if (file_mips_opts.gp < 0)
+ {
+ /* Infer the integer register size from the ABI and processor.
+ Restrict ourselves to 32-bit registers if that's all the
+ processor has, or if the ABI cannot handle 64-bit registers. */
+ file_mips_opts.gp = (ABI_NEEDS_32BIT_REGS (mips_abi)
+ || !ISA_HAS_64BIT_REGS (file_mips_opts.isa))
+ ? 32 : 64;
+ }
+
+ if (file_mips_opts.fp < 0)
+ {
+ /* No user specified float register size.
+ ??? GAS treats single-float processors as though they had 64-bit
+ float registers (although it complains when double-precision
+ instructions are used). As things stand, saying they have 32-bit
+ registers would lead to spurious "register must be even" messages.
+ So here we assume float registers are never smaller than the
+ integer ones. */
+ if (file_mips_opts.gp == 64)
+ /* 64-bit integer registers implies 64-bit float registers. */
+ file_mips_opts.fp = 64;
+ else if ((file_mips_opts.ase & FP64_ASES)
+ && ISA_HAS_64BIT_FPRS (file_mips_opts.isa))
+ /* Handle ASEs that require 64-bit float registers, if possible. */
+ file_mips_opts.fp = 64;
+ else if (ISA_IS_R6 (mips_opts.isa))
+ /* R6 implies 64-bit float registers. */
+ file_mips_opts.fp = 64;
+ else
+ /* 32-bit float registers. */
+ file_mips_opts.fp = 32;
+ }
+
+ arch_info = mips_cpu_info_from_arch (file_mips_opts.arch);
+
+ /* Disable operations on odd-numbered floating-point registers by default
+ when using the FPXX ABI. */
+ if (file_mips_opts.oddspreg < 0)
+ {
+ if (file_mips_opts.fp == 0)
+ file_mips_opts.oddspreg = 0;
+ else
+ file_mips_opts.oddspreg = 1;
+ }
+
+ /* End of GCC-shared inference code. */
+
+ /* This flag is set when we have a 64-bit capable CPU but use only
+ 32-bit wide registers. Note that EABI does not use it. */
+ if (ISA_HAS_64BIT_REGS (file_mips_opts.isa)
+ && ((mips_abi == NO_ABI && file_mips_opts.gp == 32)
+ || mips_abi == O32_ABI))
+ mips_32bitmode = 1;
+
+ if (file_mips_opts.isa == ISA_MIPS1 && mips_trap)
+ as_bad (_("trap exception not supported at ISA 1"));
+
+ /* If the selected architecture includes support for ASEs, enable
+ generation of code for them. */
+ if (file_mips_opts.mips16 == -1)
+ file_mips_opts.mips16 = (CPU_HAS_MIPS16 (file_mips_opts.arch)) ? 1 : 0;
+ if (file_mips_opts.micromips == -1)
+ file_mips_opts.micromips = (CPU_HAS_MICROMIPS (file_mips_opts.arch))
+ ? 1 : 0;
+
+ if (mips_nan2008 == -1)
+ mips_nan2008 = (ISA_HAS_LEGACY_NAN (file_mips_opts.isa)) ? 0 : 1;
+ else if (!ISA_HAS_LEGACY_NAN (file_mips_opts.isa) && mips_nan2008 == 0)
+ as_fatal (_("`%s' does not support legacy NaN"),
+ mips_cpu_info_from_arch (file_mips_opts.arch)->name);
+
+ /* Some ASEs require 64-bit FPRs, so -mfp32 should stop those ASEs from
+ being selected implicitly. */
+ if (file_mips_opts.fp != 64)
+ file_ase_explicit |= ASE_MIPS3D | ASE_MDMX | ASE_MSA;
+
+ /* If the user didn't explicitly select or deselect a particular ASE,
+ use the default setting for the CPU. */
+ file_mips_opts.ase |= (arch_info->ase & ~file_ase_explicit);
+
+ /* Set up the current options. These may change throughout assembly. */
+ mips_opts = file_mips_opts;
+
+ mips_check_isa_supports_ases ();
+ mips_check_options (&file_mips_opts, TRUE);
+ file_mips_opts_checked = TRUE;
+
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
+ as_warn (_("could not set architecture and machine"));
}
void
@@ -3598,6 +3983,8 @@ md_assemble (char *str)
bfd_reloc_code_real_type unused_reloc[3]
= {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+ file_mips_check_options ();
+
imm_expr.X_op = O_absent;
offset_expr.X_op = O_absent;
offset_reloc[0] = BFD_RELOC_UNUSED;
@@ -3748,9 +4135,15 @@ limited_pcrel_reloc_p (bfd_reloc_code_real_type reloc)
case BFD_RELOC_MICROMIPS_7_PCREL_S1:
case BFD_RELOC_MICROMIPS_10_PCREL_S1:
case BFD_RELOC_MICROMIPS_16_PCREL_S1:
+ case BFD_RELOC_MIPS_21_PCREL_S2:
+ case BFD_RELOC_MIPS_26_PCREL_S2:
+ case BFD_RELOC_MIPS_18_PCREL_S3:
+ case BFD_RELOC_MIPS_19_PCREL_S2:
return TRUE;
case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_LO16_PCREL:
return HAVE_64BIT_ADDRESSES;
default:
@@ -4053,6 +4446,20 @@ operand_reg_mask (const struct mips_cl_insn *insn,
uval = insn_extract_operand (insn, operand);
return (1 << (uval & 31)) | (1 << (uval >> 5));
+ case OP_SAME_RS_RT:
+ if (!(type_mask & (1 << OP_REG_GP)))
+ return 0;
+ uval = insn_extract_operand (insn, operand);
+ gas_assert ((uval & 31) == (uval >> 5));
+ return 1 << (uval & 31);
+
+ case OP_CHECK_PREV:
+ case OP_NON_ZERO_REG:
+ if (!(type_mask & (1 << OP_REG_GP)))
+ return 0;
+ uval = insn_extract_operand (insn, operand);
+ return 1 << (uval & 31);
+
case OP_LWM_SWM_LIST:
abort ();
@@ -4167,7 +4574,7 @@ fpr_read_mask (const struct mips_cl_insn *ip)
pinfo = ip->insn_mo->pinfo;
/* Conservatively treat all operands to an FP_D instruction are doubles.
(This is overly pessimistic for things like cvt.d.s.) */
- if (HAVE_32BIT_FPRS && (pinfo & FP_D))
+ if (FPR_SIZE != 64 && (pinfo & FP_D))
mask |= mask << 1;
return mask;
}
@@ -4186,7 +4593,7 @@ fpr_write_mask (const struct mips_cl_insn *ip)
pinfo = ip->insn_mo->pinfo;
/* Conservatively treat all operands to an FP_D instruction are doubles.
(This is overly pessimistic for things like cvt.s.d.) */
- if (HAVE_32BIT_FPRS && (pinfo & FP_D))
+ if (FPR_SIZE != 64 && (pinfo & FP_D))
mask |= mask << 1;
return mask;
}
@@ -4198,39 +4605,42 @@ static bfd_boolean
mips_oddfpreg_ok (const struct mips_opcode *insn, int opnum)
{
const char *s = insn->name;
+ bfd_boolean oddspreg = (ISA_HAS_ODD_SINGLE_FPR (mips_opts.isa, mips_opts.arch)
+ || FPR_SIZE == 64)
+ && mips_opts.oddspreg;
if (insn->pinfo == INSN_MACRO)
/* Let a macro pass, we'll catch it later when it is expanded. */
return TRUE;
- if (ISA_HAS_ODD_SINGLE_FPR (mips_opts.isa) || mips_opts.arch == CPU_R5900)
- {
- /* Allow odd registers for single-precision ops. */
- switch (insn->pinfo & (FP_S | FP_D))
- {
- case FP_S:
- case 0:
- return TRUE;
- case FP_D:
- return FALSE;
- default:
- break;
- }
+ /* Single-precision coprocessor loads and moves are OK for 32-bit registers,
+ otherwise it depends on oddspreg. */
+ if ((insn->pinfo & FP_S)
+ && (insn->pinfo & (INSN_LOAD_MEMORY | INSN_STORE_MEMORY
+ | INSN_LOAD_COPROC | INSN_COPROC_MOVE)))
+ return FPR_SIZE == 32 || oddspreg;
- /* Cvt.w.x and cvt.x.w allow an odd register for a 'w' or 's' operand. */
- s = strchr (insn->name, '.');
- if (s != NULL && opnum == 2)
- s = strchr (s + 1, '.');
- return (s != NULL && (s[1] == 'w' || s[1] == 's'));
+ /* Allow odd registers for single-precision ops and double-precision if the
+ floating-point registers are 64-bit wide. */
+ switch (insn->pinfo & (FP_S | FP_D))
+ {
+ case FP_S:
+ case 0:
+ return oddspreg;
+ case FP_D:
+ return FPR_SIZE == 64;
+ default:
+ break;
}
- /* Single-precision coprocessor loads and moves are OK too. */
- if ((insn->pinfo & FP_S)
- && (insn->pinfo & (INSN_COPROC_MEMORY_DELAY | INSN_STORE_MEMORY
- | INSN_LOAD_COPROC_DELAY | INSN_COPROC_MOVE_DELAY)))
- return TRUE;
+ /* Cvt.w.x and cvt.x.w allow an odd register for a 'w' or 's' operand. */
+ s = strchr (insn->name, '.');
+ if (s != NULL && opnum == 2)
+ s = strchr (s + 1, '.');
+ if (s != NULL && (s[1] == 'w' || s[1] == 's'))
+ return oddspreg;
- return FALSE;
+ return FPR_SIZE == 64;
}
/* Information about an instruction argument that we're trying to match. */
@@ -4386,10 +4796,10 @@ convert_reg_type (const struct mips_opcode *opcode,
FPR load, store or move (including moves to and from GPRs). */
if ((mips_opts.ase & ASE_MDMX)
&& (opcode->pinfo & FP_D)
- && (opcode->pinfo & (INSN_COPROC_MOVE_DELAY
+ && (opcode->pinfo & (INSN_COPROC_MOVE
| INSN_COPROC_MEMORY_DELAY
- | INSN_LOAD_COPROC_DELAY
- | INSN_LOAD_MEMORY_DELAY
+ | INSN_LOAD_COPROC
+ | INSN_LOAD_MEMORY
| INSN_STORE_MEMORY)))
return RTYPE_FPU | RTYPE_VEC;
return RTYPE_FPU;
@@ -4453,9 +4863,16 @@ check_regno (struct mips_arg_info *arg,
if (type == OP_REG_FP
&& (regno & 1) != 0
- && HAVE_32BIT_FPRS
&& !mips_oddfpreg_ok (arg->insn->insn_mo, arg->opnum))
- as_warn (_("float register should be even, was %d"), regno);
+ {
+ /* This was a warning prior to introducing O32 FPXX and FP64 support
+ so maintain a warning for FP32 but raise an error for the new
+ cases. */
+ if (FPR_SIZE == 32)
+ as_warn (_("float register should be even, was %d"), regno);
+ else
+ as_bad (_("float register should be even, was %d"), regno);
+ }
if (type == OP_REG_CCC)
{
@@ -4835,6 +5252,58 @@ match_clo_clz_dest_operand (struct mips_arg_info *arg,
return TRUE;
}
+/* OP_CHECK_PREV matcher. */
+
+static bfd_boolean
+match_check_prev_operand (struct mips_arg_info *arg,
+ const struct mips_operand *operand_base)
+{
+ const struct mips_check_prev_operand *operand;
+ unsigned int regno;
+
+ operand = (const struct mips_check_prev_operand *) operand_base;
+
+ if (!match_reg (arg, OP_REG_GP, &regno))
+ return FALSE;
+
+ if (!operand->zero_ok && regno == 0)
+ return FALSE;
+
+ if ((operand->less_than_ok && regno < arg->last_regno)
+ || (operand->greater_than_ok && regno > arg->last_regno)
+ || (operand->equal_ok && regno == arg->last_regno))
+ {
+ arg->last_regno = regno;
+ insn_insert_operand (arg->insn, operand_base, regno);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* OP_SAME_RS_RT matcher. */
+
+static bfd_boolean
+match_same_rs_rt_operand (struct mips_arg_info *arg,
+ const struct mips_operand *operand)
+{
+ unsigned int regno;
+
+ if (!match_reg (arg, OP_REG_GP, &regno))
+ return FALSE;
+
+ if (regno == 0)
+ {
+ set_insn_error (arg->argnum, _("the source register must not be $0"));
+ return FALSE;
+ }
+
+ arg->last_regno = regno;
+
+ insn_insert_operand (arg->insn, operand, regno | (regno << 5));
+ return TRUE;
+}
+
/* OP_LWM_SWM_LIST matcher. */
static bfd_boolean
@@ -5228,6 +5697,25 @@ match_pc_operand (struct mips_arg_info *arg)
return FALSE;
}
+/* OP_NON_ZERO_REG matcher. */
+
+static bfd_boolean
+match_non_zero_reg_operand (struct mips_arg_info *arg,
+ const struct mips_operand *operand)
+{
+ unsigned int regno;
+
+ if (!match_reg (arg, OP_REG_GP, &regno))
+ return FALSE;
+
+ if (regno == 0)
+ return FALSE;
+
+ arg->last_regno = regno;
+ insn_insert_operand (arg->insn, operand, regno);
+ return TRUE;
+}
+
/* OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG matcher. OTHER_REGNO is the
register that we need to match. */
@@ -5309,13 +5797,16 @@ match_float_constant (struct mips_arg_info *arg, expressionS *imm,
/* Handle 64-bit constants for which an immediate value is best. */
if (length == 8
&& !mips_disable_float_construction
- /* Constants can only be constructed in GPRs and copied
- to FPRs if the GPRs are at least as wide as the FPRs.
- Force the constant into memory if we are using 64-bit FPRs
- but the GPRs are only 32 bits wide. */
- /* ??? No longer true with the addition of MTHC1, but this
- is legacy code... */
- && (using_gprs || !(HAVE_64BIT_FPRS && HAVE_32BIT_GPRS))
+ /* Constants can only be constructed in GPRs and copied to FPRs if the
+ GPRs are at least as wide as the FPRs or MTHC1 is available.
+ Unlike most tests for 32-bit floating-point registers this check
+ specifically looks for GPR_SIZE == 32 as the FPXX ABI does not
+ permit 64-bit moves without MXHC1.
+ Force the constant into memory otherwise. */
+ && (using_gprs
+ || GPR_SIZE == 64
+ || ISA_HAS_MXHC1 (mips_opts.isa)
+ || FPR_SIZE == 32)
&& ((data[0] == 0 && data[1] == 0)
|| (data[2] == 0 && data[3] == 0))
&& ((data[4] == 0 && data[5] == 0)
@@ -5325,7 +5816,7 @@ match_float_constant (struct mips_arg_info *arg, expressionS *imm,
If using 32-bit registers, set IMM to the high order 32 bits and
OFFSET to the low order 32 bits. Otherwise, set IMM to the entire
64 bit constant. */
- if (using_gprs ? HAVE_32BIT_GPRS : HAVE_32BIT_FPRS)
+ if (GPR_SIZE == 32 || (!using_gprs && FPR_SIZE != 64))
{
imm->X_op = O_constant;
offset->X_op = O_constant;
@@ -5501,6 +5992,15 @@ match_operand (struct mips_arg_info *arg,
case OP_REG_INDEX:
return match_reg_index_operand (arg, operand);
+
+ case OP_SAME_RS_RT:
+ return match_same_rs_rt_operand (arg, operand);
+
+ case OP_CHECK_PREV:
+ return match_check_prev_operand (arg, operand);
+
+ case OP_NON_ZERO_REG:
+ return match_non_zero_reg_operand (arg, operand);
}
abort ();
}
@@ -5529,8 +6029,8 @@ reg_needs_delay (unsigned int reg)
prev_pinfo = history[0].insn_mo->pinfo;
if (!mips_opts.noreorder
- && (((prev_pinfo & INSN_LOAD_MEMORY_DELAY) && !gpr_interlocks)
- || ((prev_pinfo & INSN_LOAD_COPROC_DELAY) && !cop_interlocks))
+ && (((prev_pinfo & INSN_LOAD_MEMORY) && !gpr_interlocks)
+ || ((prev_pinfo & INSN_LOAD_COPROC) && !cop_interlocks))
&& (gpr_write_mask (&history[0]) & (1 << reg)))
return TRUE;
@@ -5559,8 +6059,10 @@ classify_vr4120_insn (const char *name)
return NUM_FIX_VR4120_CLASSES;
}
-#define INSN_ERET 0x42000018
-#define INSN_DERET 0x4200001f
+#define INSN_ERET 0x42000018
+#define INSN_DERET 0x4200001f
+#define INSN_DMULT 0x1c
+#define INSN_DMULTU 0x1d
/* Return the number of instructions that must separate INSN1 and INSN2,
where INSN1 is the earlier instruction. Return the worst-case value
@@ -5611,6 +6113,18 @@ insns_between (const struct mips_cl_insn *insn1,
}
}
+ /* If we're working around PMC RM7000 errata, there must be three
+ nops between a dmult and a load instruction. */
+ if (mips_fix_rm7000 && !mips_opts.micromips)
+ {
+ if ((insn1->insn_opcode & insn1->insn_mo->mask) == INSN_DMULT
+ || (insn1->insn_opcode & insn1->insn_mo->mask) == INSN_DMULTU)
+ {
+ if (pinfo2 & INSN_LOAD_MEMORY)
+ return 3;
+ }
+ }
+
/* If working around VR4120 errata, check for combinations that need
a single intervening instruction. */
if (mips_fix_vr4120 && !mips_opts.micromips)
@@ -5633,8 +6147,8 @@ insns_between (const struct mips_cl_insn *insn1,
/* Check for GPR or coprocessor load delays. All such delays
are on the RT register. */
/* Itbl support may require additional care here. */
- if ((!gpr_interlocks && (pinfo1 & INSN_LOAD_MEMORY_DELAY))
- || (!cop_interlocks && (pinfo1 & INSN_LOAD_COPROC_DELAY)))
+ if ((!gpr_interlocks && (pinfo1 & INSN_LOAD_MEMORY))
+ || (!cop_interlocks && (pinfo1 & INSN_LOAD_COPROC)))
{
if (insn2 == NULL || (gpr_read_mask (insn2) & gpr_write_mask (insn1)))
return 1;
@@ -5648,7 +6162,7 @@ insns_between (const struct mips_cl_insn *insn1,
/* Itbl support may require additional care here. FIXME!
Need to modify this to include knowledge about
user specified delays! */
- else if ((!cop_interlocks && (pinfo1 & INSN_COPROC_MOVE_DELAY))
+ else if ((!cop_interlocks && (pinfo1 & INSN_COPROC_MOVE))
|| (!cop_mem_interlocks && (pinfo1 & INSN_COPROC_MEMORY_DELAY)))
{
/* Handle cases where INSN1 writes to a known general coprocessor
@@ -5687,6 +6201,14 @@ insns_between (const struct mips_cl_insn *insn1,
return 1;
}
+ /* Forbidden slots can not contain Control Transfer Instructions (CTIs)
+ CTIs include all branches and jumps, nal, eret, eretnc, deret, wait
+ and pause. */
+ if ((insn1->insn_mo->pinfo2 & INSN2_FORBIDDEN_SLOT)
+ && ((pinfo2 & INSN_NO_DELAY_SLOT)
+ || (insn2 && delayed_branch_p (insn2))))
+ return 1;
+
return 0;
}
@@ -6544,6 +7066,40 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
}
break;
+ case BFD_RELOC_MIPS_21_PCREL_S2:
+ {
+ int shift;
+
+ shift = 2;
+ if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
+ as_bad (_("branch to misaligned address (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ if ((address_expr->X_add_number + (1 << (shift + 20)))
+ & ~((1 << (shift + 21)) - 1))
+ as_bad (_("branch address range overflow (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ ip->insn_opcode |= ((address_expr->X_add_number >> shift)
+ & 0x1fffff);
+ }
+ break;
+
+ case BFD_RELOC_MIPS_26_PCREL_S2:
+ {
+ int shift;
+
+ shift = 2;
+ if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
+ as_bad (_("branch to misaligned address (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ if ((address_expr->X_add_number + (1 << (shift + 25)))
+ & ~((1 << (shift + 26)) - 1))
+ as_bad (_("branch address range overflow (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ ip->insn_opcode |= ((address_expr->X_add_number >> shift)
+ & 0x3ffffff);
+ }
+ break;
+
default:
{
offsetT value;
@@ -6807,7 +7363,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
/* These relocations can have an addend that won't fit in
4 octets for 64bit assembly. */
- if (HAVE_64BIT_GPRS
+ if (GPR_SIZE == 64
&& ! howto->partial_inplace
&& (reloc_type[0] == BFD_RELOC_16
|| reloc_type[0] == BFD_RELOC_32
@@ -7208,12 +7764,33 @@ match_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode,
arg.opnum += 1;
switch (*args)
{
+ case '-':
+ switch (args[1])
+ {
+ case 'A':
+ *offset_reloc = BFD_RELOC_MIPS_19_PCREL_S2;
+ break;
+
+ case 'B':
+ *offset_reloc = BFD_RELOC_MIPS_18_PCREL_S3;
+ break;
+ }
+ break;
+
case '+':
switch (args[1])
{
case 'i':
*offset_reloc = BFD_RELOC_MIPS_JMP;
break;
+
+ case '\'':
+ *offset_reloc = BFD_RELOC_MIPS_26_PCREL_S2;
+ break;
+
+ case '\"':
+ *offset_reloc = BFD_RELOC_MIPS_21_PCREL_S2;
+ break;
}
break;
@@ -7221,7 +7798,7 @@ match_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode,
if (!match_const_int (&arg, &imm_expr.X_add_number))
return FALSE;
imm_expr.X_op = O_constant;
- if (HAVE_32BIT_GPRS)
+ if (GPR_SIZE == 32)
normalize_constant_expr (&imm_expr);
continue;
@@ -7299,7 +7876,7 @@ match_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode,
abort ();
/* Skip prefixes. */
- if (*args == '+' || *args == 'm')
+ if (*args == '+' || *args == 'm' || *args == '-')
args++;
if (mips_optional_operand_p (operand)
@@ -7431,7 +8008,7 @@ match_mips16_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode,
if (!match_const_int (&arg, &imm_expr.X_add_number))
return FALSE;
imm_expr.X_op = O_constant;
- if (HAVE_32BIT_GPRS)
+ if (GPR_SIZE == 32)
normalize_constant_expr (&imm_expr);
continue;
@@ -7769,10 +8346,13 @@ static const char * const shft_fmt[2] = { "d,w,<", "t,r,<" };
static const char * const trap_fmt[2] = { "s,t,q", "s,t,|" };
#define BRK_FMT (brk_fmt[mips_opts.micromips][mips_opts.insn32])
-#define COP12_FMT (cop12_fmt[mips_opts.micromips])
+#define COP12_FMT (ISA_IS_R6 (mips_opts.isa) ? "E,+:(d)" \
+ : cop12_fmt[mips_opts.micromips])
#define JALR_FMT (jalr_fmt[mips_opts.micromips])
#define LUI_FMT (lui_fmt[mips_opts.micromips])
#define MEM12_FMT (mem12_fmt[mips_opts.micromips])
+#define LL_SC_FMT (ISA_IS_R6 (mips_opts.isa) ? "t,+j(b)" \
+ : mem12_fmt[mips_opts.micromips])
#define MFHL_FMT (mfhl_fmt[mips_opts.micromips][mips_opts.insn32])
#define SHFT_FMT (shft_fmt[mips_opts.micromips])
#define TRAP_FMT (trap_fmt[mips_opts.micromips])
@@ -7950,7 +8530,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
uval |= (uval << 5);
insn_insert_operand (&insn, operand, uval);
- if (*fmt == '+' || *fmt == 'm')
+ if (*fmt == '+' || *fmt == 'm' || *fmt == '-')
++fmt;
break;
}
@@ -8158,7 +8738,7 @@ set_at (int reg, int unsignedp)
AT, reg, BFD_RELOC_LO16);
else
{
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, unsignedp ? "sltu" : "slt", "d,v,t", AT, reg, AT);
}
}
@@ -8284,7 +8864,7 @@ load_register (int reg, expressionS *ep, int dbl)
/* The value is larger than 32 bits. */
- if (!dbl || HAVE_32BIT_GPRS)
+ if (!dbl || GPR_SIZE == 32)
{
char value[32];
@@ -8740,7 +9320,7 @@ move_register (int dest, int source)
&& !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
macro_build (NULL, "move", "mp,mj", dest, source);
else
- macro_build (NULL, HAVE_32BIT_GPRS ? "addu" : "daddu", "d,v,t",
+ macro_build (NULL, GPR_SIZE == 32 ? "addu" : "daddu", "d,v,t",
dest, source, 0);
}
@@ -9223,7 +9803,7 @@ macro (struct mips_cl_insn *ip, char *str)
}
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, s2, "d,v,t", op[0], op[1], AT);
break;
@@ -9267,7 +9847,7 @@ macro (struct mips_cl_insn *ip, char *str)
{
op[1] = AT;
used_at = 1;
- load_register (op[1], &imm_expr, HAVE_64BIT_GPRS);
+ load_register (op[1], &imm_expr, GPR_SIZE == 64);
}
/* Fall through. */
case M_BEQL:
@@ -9367,7 +9947,7 @@ macro (struct mips_cl_insn *ip, char *str)
likely = 1;
case M_BGTU_I:
if (op[0] == 0
- || (HAVE_32BIT_GPRS
+ || (GPR_SIZE == 32
&& imm_expr.X_add_number == -1))
goto do_false;
++imm_expr.X_add_number;
@@ -9484,7 +10064,7 @@ macro (struct mips_cl_insn *ip, char *str)
likely = 1;
case M_BLEU_I:
if (op[0] == 0
- || (HAVE_32BIT_GPRS
+ || (GPR_SIZE == 32
&& imm_expr.X_add_number == -1))
goto do_true;
++imm_expr.X_add_number;
@@ -9749,7 +10329,7 @@ macro (struct mips_cl_insn *ip, char *str)
zero, we then add a base register to it. */
breg = op[2];
- if (dbl && HAVE_32BIT_GPRS)
+ if (dbl && GPR_SIZE == 32)
as_warn (_("dla used to load 32-bit register"));
if (!dbl && HAVE_64BIT_OBJECTS)
@@ -10719,7 +11299,9 @@ macro (struct mips_cl_insn *ip, char *str)
case M_LWC2_AB:
s = "lwc2";
fmt = COP12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 11
+ : 16);
/* Itbl support may require additional care here. */
coproc = 1;
goto ld_st;
@@ -10749,7 +11331,9 @@ macro (struct mips_cl_insn *ip, char *str)
case M_LDC2_AB:
s = "ldc2";
fmt = COP12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 11
+ : 16);
/* Itbl support may require additional care here. */
coproc = 1;
goto ld_st;
@@ -10777,13 +11361,17 @@ macro (struct mips_cl_insn *ip, char *str)
goto ld_st;
case M_LL_AB:
s = "ll";
- fmt = MEM12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ fmt = LL_SC_FMT;
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 9
+ : 16);
goto ld;
case M_LLD_AB:
s = "lld";
- fmt = MEM12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ fmt = LL_SC_FMT;
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 9
+ : 16);
goto ld;
case M_LWU_AB:
s = "lwu";
@@ -10853,7 +11441,9 @@ macro (struct mips_cl_insn *ip, char *str)
case M_SWC2_AB:
s = "swc2";
fmt = COP12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 11
+ : 16);
/* Itbl support may require additional care here. */
coproc = 1;
goto ld_st;
@@ -10876,18 +11466,26 @@ macro (struct mips_cl_insn *ip, char *str)
goto ld_st;
case M_SC_AB:
s = "sc";
- fmt = MEM12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ fmt = LL_SC_FMT;
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 9
+ : 16);
goto ld_st;
case M_SCD_AB:
s = "scd";
- fmt = MEM12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ fmt = LL_SC_FMT;
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 9
+ : 16);
goto ld_st;
case M_CACHE_AB:
s = "cache";
- fmt = mips_opts.micromips ? "k,~(b)" : "k,o(b)";
- offbits = (mips_opts.micromips ? 12 : 16);
+ fmt = (mips_opts.micromips ? "k,~(b)"
+ : ISA_IS_R6 (mips_opts.isa) ? "k,+j(b)"
+ : "k,o(b)");
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 9
+ : 16);
goto ld_st;
case M_CACHEE_AB:
s = "cachee";
@@ -10896,8 +11494,12 @@ macro (struct mips_cl_insn *ip, char *str)
goto ld_st;
case M_PREF_AB:
s = "pref";
- fmt = !mips_opts.micromips ? "k,o(b)" : "k,~(b)";
- offbits = (mips_opts.micromips ? 12 : 16);
+ fmt = (mips_opts.micromips ? "k,~(b)"
+ : ISA_IS_R6 (mips_opts.isa) ? "k,+j(b)"
+ : "k,o(b)");
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 9
+ : 16);
goto ld_st;
case M_PREFE_AB:
s = "prefe";
@@ -10913,7 +11515,9 @@ macro (struct mips_cl_insn *ip, char *str)
case M_SDC2_AB:
s = "sdc2";
fmt = COP12_FMT;
- offbits = (mips_opts.micromips ? 12 : 16);
+ offbits = (mips_opts.micromips ? 12
+ : ISA_IS_R6 (mips_opts.isa) ? 11
+ : 16);
/* Itbl support may require additional care here. */
coproc = 1;
goto ld_st;
@@ -11412,7 +12016,7 @@ macro (struct mips_cl_insn *ip, char *str)
zero or in OFFSET_EXPR. */
if (imm_expr.X_op == O_constant)
{
- if (HAVE_64BIT_GPRS)
+ if (GPR_SIZE == 64)
load_register (op[0], &imm_expr, 1);
else
{
@@ -11461,7 +12065,7 @@ macro (struct mips_cl_insn *ip, char *str)
}
/* Now we load the register(s). */
- if (HAVE_64BIT_GPRS)
+ if (GPR_SIZE == 64)
{
used_at = 1;
macro_build (&offset_expr, "ld", "t,o(b)", op[0],
@@ -11492,15 +12096,19 @@ macro (struct mips_cl_insn *ip, char *str)
if (imm_expr.X_op == O_constant)
{
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_FPRS);
- if (HAVE_64BIT_FPRS)
- {
- gas_assert (HAVE_64BIT_GPRS);
- macro_build (NULL, "dmtc1", "t,S", AT, op[0]);
- }
+ load_register (AT, &imm_expr, FPR_SIZE == 64);
+ if (FPR_SIZE == 64 && GPR_SIZE == 64)
+ macro_build (NULL, "dmtc1", "t,S", AT, op[0]);
else
{
- macro_build (NULL, "mtc1", "t,G", AT, op[0] + 1);
+ if (ISA_HAS_MXHC1 (mips_opts.isa))
+ macro_build (NULL, "mthc1", "t,G", AT, op[0]);
+ else if (FPR_SIZE != 32)
+ as_bad (_("Unable to generate `%s' compliant code "
+ "without mthc1"),
+ (FPR_SIZE == 64) ? "fp64" : "fpxx");
+ else
+ macro_build (NULL, "mtc1", "t,G", AT, op[0] + 1);
if (offset_expr.X_op == O_absent)
macro_build (NULL, "mtc1", "t,G", 0, op[0]);
else
@@ -11593,7 +12201,7 @@ macro (struct mips_cl_insn *ip, char *str)
case M_LD_AB:
fmt = "t,o(b)";
- if (HAVE_64BIT_GPRS)
+ if (GPR_SIZE == 64)
{
s = "ld";
goto ld;
@@ -11603,7 +12211,7 @@ macro (struct mips_cl_insn *ip, char *str)
case M_SD_AB:
fmt = "t,o(b)";
- if (HAVE_64BIT_GPRS)
+ if (GPR_SIZE == 64)
{
s = "sd";
goto ld_st;
@@ -11876,11 +12484,11 @@ macro (struct mips_cl_insn *ip, char *str)
case M_SAA_AB:
s = "saa";
- offbits = 0;
- fmt = "t,(b)";
- goto ld_st;
+ goto saa_saad;
case M_SAAD_AB:
s = "saad";
+ saa_saad:
+ gas_assert (!mips_opts.micromips);
offbits = 0;
fmt = "t,(b)";
goto ld_st;
@@ -12244,19 +12852,19 @@ macro (struct mips_cl_insn *ip, char *str)
&& imm_expr.X_add_number < 0)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
- macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
+ macro_build (&imm_expr, GPR_SIZE == 32 ? "addiu" : "daddiu",
"t,r,j", op[0], op[1], BFD_RELOC_LO16);
}
else if (CPU_HAS_SEQ (mips_opts.arch))
{
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, "seq", "d,v,t", op[0], op[1], AT);
break;
}
else
{
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, "xor", "d,v,t", op[0], op[1], AT);
used_at = 1;
}
@@ -12281,7 +12889,7 @@ macro (struct mips_cl_insn *ip, char *str)
op[0], op[1], BFD_RELOC_LO16);
else
{
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, mask == M_SGE_I ? "slt" : "sltu", "d,v,t",
op[0], op[1], AT);
used_at = 1;
@@ -12305,7 +12913,7 @@ macro (struct mips_cl_insn *ip, char *str)
s = "sltu";
sgti:
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, s, "d,v,t", op[0], AT, op[1]);
break;
@@ -12326,7 +12934,7 @@ macro (struct mips_cl_insn *ip, char *str)
s = "sltu";
slei:
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, s, "d,v,t", op[0], AT, op[1]);
macro_build (&expr1, "xori", "t,r,i", op[0], op[0], BFD_RELOC_LO16);
break;
@@ -12340,7 +12948,7 @@ macro (struct mips_cl_insn *ip, char *str)
break;
}
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, "slt", "d,v,t", op[0], op[1], AT);
break;
@@ -12353,7 +12961,7 @@ macro (struct mips_cl_insn *ip, char *str)
break;
}
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, "sltu", "d,v,t", op[0], op[1], AT);
break;
@@ -12379,7 +12987,7 @@ macro (struct mips_cl_insn *ip, char *str)
{
as_warn (_("instruction %s: result is always true"),
ip->insn_mo->name);
- macro_build (&expr1, HAVE_32BIT_GPRS ? "addiu" : "daddiu", "t,r,j",
+ macro_build (&expr1, GPR_SIZE == 32 ? "addiu" : "daddiu", "t,r,j",
op[0], 0, BFD_RELOC_LO16);
break;
}
@@ -12401,19 +13009,19 @@ macro (struct mips_cl_insn *ip, char *str)
&& imm_expr.X_add_number < 0)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
- macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
+ macro_build (&imm_expr, GPR_SIZE == 32 ? "addiu" : "daddiu",
"t,r,j", op[0], op[1], BFD_RELOC_LO16);
}
else if (CPU_HAS_SEQ (mips_opts.arch))
{
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, "sne", "d,v,t", op[0], op[1], AT);
break;
}
else
{
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, "xor", "d,v,t", op[0], op[1], AT);
used_at = 1;
}
@@ -12479,7 +13087,7 @@ macro (struct mips_cl_insn *ip, char *str)
s = "tne";
trap:
used_at = 1;
- load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+ load_register (AT, &imm_expr, GPR_SIZE == 64);
macro_build (NULL, s, "s,t", op[0], AT);
break;
@@ -13236,7 +13844,9 @@ static const struct percent_op_match mips_percent_op[] =
{"%tprel_hi", BFD_RELOC_MIPS_TLS_TPREL_HI16},
{"%tprel_lo", BFD_RELOC_MIPS_TLS_TPREL_LO16},
{"%gottprel", BFD_RELOC_MIPS_TLS_GOTTPREL},
- {"%hi", BFD_RELOC_HI16_S}
+ {"%hi", BFD_RELOC_HI16_S},
+ {"%pcrel_hi", BFD_RELOC_HI16_S_PCREL},
+ {"%pcrel_lo", BFD_RELOC_LO16_PCREL}
};
static const struct percent_op_match mips16_percent_op[] =
@@ -13429,7 +14039,7 @@ md_parse_option (int c, char *arg)
for (i = 0; i < ARRAY_SIZE (mips_ases); i++)
if (c == mips_ases[i].option_on || c == mips_ases[i].option_off)
{
- file_ase_explicit |= mips_set_ase (&mips_ases[i],
+ file_ase_explicit |= mips_set_ase (&mips_ases[i], &file_mips_opts,
c == mips_ases[i].option_on);
return 1;
}
@@ -13479,39 +14089,63 @@ md_parse_option (int c, char *arg)
break;
case OPTION_MIPS1:
- file_mips_isa = ISA_MIPS1;
+ file_mips_opts.isa = ISA_MIPS1;
break;
case OPTION_MIPS2:
- file_mips_isa = ISA_MIPS2;
+ file_mips_opts.isa = ISA_MIPS2;
break;
case OPTION_MIPS3:
- file_mips_isa = ISA_MIPS3;
+ file_mips_opts.isa = ISA_MIPS3;
break;
case OPTION_MIPS4:
- file_mips_isa = ISA_MIPS4;
+ file_mips_opts.isa = ISA_MIPS4;
break;
case OPTION_MIPS5:
- file_mips_isa = ISA_MIPS5;
+ file_mips_opts.isa = ISA_MIPS5;
break;
case OPTION_MIPS32:
- file_mips_isa = ISA_MIPS32;
+ file_mips_opts.isa = ISA_MIPS32;
break;
case OPTION_MIPS32R2:
- file_mips_isa = ISA_MIPS32R2;
+ file_mips_opts.isa = ISA_MIPS32R2;
+ break;
+
+ case OPTION_MIPS32R3:
+ file_mips_opts.isa = ISA_MIPS32R3;
+ break;
+
+ case OPTION_MIPS32R5:
+ file_mips_opts.isa = ISA_MIPS32R5;
+ break;
+
+ case OPTION_MIPS32R6:
+ file_mips_opts.isa = ISA_MIPS32R6;
break;
case OPTION_MIPS64R2:
- file_mips_isa = ISA_MIPS64R2;
+ file_mips_opts.isa = ISA_MIPS64R2;
+ break;
+
+ case OPTION_MIPS64R3:
+ file_mips_opts.isa = ISA_MIPS64R3;
+ break;
+
+ case OPTION_MIPS64R5:
+ file_mips_opts.isa = ISA_MIPS64R5;
+ break;
+
+ case OPTION_MIPS64R6:
+ file_mips_opts.isa = ISA_MIPS64R6;
break;
case OPTION_MIPS64:
- file_mips_isa = ISA_MIPS64;
+ file_mips_opts.isa = ISA_MIPS64;
break;
case OPTION_MTUNE:
@@ -13555,32 +14189,32 @@ md_parse_option (int c, char *arg)
break;
case OPTION_MICROMIPS:
- if (mips_opts.mips16 == 1)
+ if (file_mips_opts.mips16 == 1)
{
as_bad (_("-mmicromips cannot be used with -mips16"));
return 0;
}
- mips_opts.micromips = 1;
+ file_mips_opts.micromips = 1;
mips_no_prev_insn ();
break;
case OPTION_NO_MICROMIPS:
- mips_opts.micromips = 0;
+ file_mips_opts.micromips = 0;
mips_no_prev_insn ();
break;
case OPTION_MIPS16:
- if (mips_opts.micromips == 1)
+ if (file_mips_opts.micromips == 1)
{
as_bad (_("-mips16 cannot be used with -micromips"));
return 0;
}
- mips_opts.mips16 = 1;
+ file_mips_opts.mips16 = 1;
mips_no_prev_insn ();
break;
case OPTION_NO_MIPS16:
- mips_opts.mips16 = 0;
+ file_mips_opts.mips16 = 0;
mips_no_prev_insn ();
break;
@@ -13592,6 +14226,14 @@ md_parse_option (int c, char *arg)
mips_fix_24k = 0;
break;
+ case OPTION_FIX_RM7000:
+ mips_fix_rm7000 = 1;
+ break;
+
+ case OPTION_NO_FIX_RM7000:
+ mips_fix_rm7000 = 0;
+ break;
+
case OPTION_FIX_LOONGSON2F_JUMP:
mips_fix_loongson2f_jump = TRUE;
break;
@@ -13641,11 +14283,11 @@ md_parse_option (int c, char *arg)
break;
case OPTION_INSN32:
- mips_opts.insn32 = TRUE;
+ file_mips_opts.insn32 = TRUE;
break;
case OPTION_NO_INSN32:
- mips_opts.insn32 = FALSE;
+ file_mips_opts.insn32 = FALSE;
break;
case OPTION_MSHARED:
@@ -13657,11 +14299,11 @@ md_parse_option (int c, char *arg)
break;
case OPTION_MSYM32:
- mips_opts.sym32 = TRUE;
+ file_mips_opts.sym32 = TRUE;
break;
case OPTION_MNO_SYM32:
- mips_opts.sym32 = FALSE;
+ file_mips_opts.sym32 = FALSE;
break;
/* When generating ELF code, we permit -KPIC and -call_shared to
@@ -13711,35 +14353,47 @@ md_parse_option (int c, char *arg)
break;
case OPTION_GP32:
- file_mips_gp32 = 1;
+ file_mips_opts.gp = 32;
break;
case OPTION_GP64:
- file_mips_gp32 = 0;
+ file_mips_opts.gp = 64;
break;
case OPTION_FP32:
- file_mips_fp32 = 1;
+ file_mips_opts.fp = 32;
+ break;
+
+ case OPTION_FPXX:
+ file_mips_opts.fp = 0;
break;
case OPTION_FP64:
- file_mips_fp32 = 0;
+ file_mips_opts.fp = 64;
+ break;
+
+ case OPTION_ODD_SPREG:
+ file_mips_opts.oddspreg = 1;
+ break;
+
+ case OPTION_NO_ODD_SPREG:
+ file_mips_opts.oddspreg = 0;
break;
case OPTION_SINGLE_FLOAT:
- file_mips_single_float = 1;
+ file_mips_opts.single_float = 1;
break;
case OPTION_DOUBLE_FLOAT:
- file_mips_single_float = 0;
+ file_mips_opts.single_float = 0;
break;
case OPTION_SOFT_FLOAT:
- file_mips_soft_float = 1;
+ file_mips_opts.soft_float = 1;
break;
case OPTION_HARD_FLOAT:
- file_mips_soft_float = 0;
+ file_mips_opts.soft_float = 0;
break;
case OPTION_MABI:
@@ -13795,9 +14449,9 @@ md_parse_option (int c, char *arg)
case OPTION_NAN:
if (strcmp (arg, "2008") == 0)
- mips_flag_nan2008 = TRUE;
+ mips_nan2008 = 1;
else if (strcmp (arg, "legacy") == 0)
- mips_flag_nan2008 = FALSE;
+ mips_nan2008 = 0;
else
{
as_fatal (_("invalid NaN setting -mnan=%s"), arg);
@@ -13814,22 +14468,7 @@ md_parse_option (int c, char *arg)
return 1;
}
-/* Set up globals to generate code for the ISA or processor
- described by INFO. */
-
-static void
-mips_set_architecture (const struct mips_cpu_info *info)
-{
- if (info != 0)
- {
- file_mips_arch = info->cpu;
- mips_opts.arch = info->cpu;
- mips_opts.isa = info->isa;
- }
-}
-
-
-/* Likewise for tuning. */
+/* Set up globals to tune for the ISA or processor described by INFO. */
static void
mips_set_tune (const struct mips_cpu_info *info)
@@ -13856,7 +14495,7 @@ mips_after_parse_args (void)
if (mips_abi == NO_ABI)
mips_abi = MIPS_DEFAULT_ABI;
- /* The following code determines the architecture and register size.
+ /* The following code determines the architecture.
Similar code was added to GCC 3.3 (see override_options() in
config/mips/mips.c). The GAS and GCC code should be kept in sync
as much as possible. */
@@ -13864,9 +14503,9 @@ mips_after_parse_args (void)
if (mips_arch_string != 0)
arch_info = mips_parse_cpu ("-march", mips_arch_string);
- if (file_mips_isa != ISA_UNKNOWN)
+ if (file_mips_opts.isa != ISA_UNKNOWN)
{
- /* Handle -mipsN. At this point, file_mips_isa contains the
+ /* Handle -mipsN. At this point, file_mips_opts.isa contains the
ISA level specified by -mipsN, while arch_info->isa contains
the -march selection (if any). */
if (arch_info != 0)
@@ -13874,14 +14513,14 @@ mips_after_parse_args (void)
/* -march takes precedence over -mipsN, since it is more descriptive.
There's no harm in specifying both as long as the ISA levels
are the same. */
- if (file_mips_isa != arch_info->isa)
+ if (file_mips_opts.isa != arch_info->isa)
as_bad (_("-%s conflicts with the other architecture options,"
" which imply -%s"),
- mips_cpu_info_from_isa (file_mips_isa)->name,
+ mips_cpu_info_from_isa (file_mips_opts.isa)->name,
mips_cpu_info_from_isa (arch_info->isa)->name);
}
else
- arch_info = mips_cpu_info_from_isa (file_mips_isa);
+ arch_info = mips_cpu_info_from_isa (file_mips_opts.isa);
}
if (arch_info == 0)
@@ -13894,9 +14533,17 @@ mips_after_parse_args (void)
as_bad (_("-march=%s is not compatible with the selected ABI"),
arch_info->name);
- mips_set_architecture (arch_info);
+ file_mips_opts.arch = arch_info->cpu;
+ file_mips_opts.isa = arch_info->isa;
+
+ /* Set up initial mips_opts state. */
+ mips_opts = file_mips_opts;
+
+ /* The register size inference code is now placed in
+ file_mips_check_options. */
- /* Optimize for file_mips_arch, unless -mtune selects a different processor. */
+ /* Optimize for file_mips_opts.arch, unless -mtune selects a different
+ processor. */
if (mips_tune_string != 0)
tune_info = mips_parse_cpu ("-mtune", mips_tune_string);
@@ -13905,101 +14552,6 @@ mips_after_parse_args (void)
else
mips_set_tune (tune_info);
- if (file_mips_gp32 >= 0)
- {
- /* The user specified the size of the integer registers. Make sure
- it agrees with the ABI and ISA. */
- if (file_mips_gp32 == 0 && !ISA_HAS_64BIT_REGS (mips_opts.isa))
- as_bad (_("-mgp64 used with a 32-bit processor"));
- else if (file_mips_gp32 == 1 && ABI_NEEDS_64BIT_REGS (mips_abi))
- as_bad (_("-mgp32 used with a 64-bit ABI"));
- else if (file_mips_gp32 == 0 && ABI_NEEDS_32BIT_REGS (mips_abi))
- as_bad (_("-mgp64 used with a 32-bit ABI"));
- }
- else
- {
- /* Infer the integer register size from the ABI and processor.
- Restrict ourselves to 32-bit registers if that's all the
- processor has, or if the ABI cannot handle 64-bit registers. */
- file_mips_gp32 = (ABI_NEEDS_32BIT_REGS (mips_abi)
- || !ISA_HAS_64BIT_REGS (mips_opts.isa));
- }
-
- switch (file_mips_fp32)
- {
- default:
- case -1:
- /* No user specified float register size.
- ??? GAS treats single-float processors as though they had 64-bit
- float registers (although it complains when double-precision
- instructions are used). As things stand, saying they have 32-bit
- registers would lead to spurious "register must be even" messages.
- So here we assume float registers are never smaller than the
- integer ones. */
- if (file_mips_gp32 == 0)
- /* 64-bit integer registers implies 64-bit float registers. */
- file_mips_fp32 = 0;
- else if ((mips_opts.ase & FP64_ASES)
- && ISA_HAS_64BIT_FPRS (mips_opts.isa))
- /* -mips3d and -mdmx imply 64-bit float registers, if possible. */
- file_mips_fp32 = 0;
- else
- /* 32-bit float registers. */
- file_mips_fp32 = 1;
- break;
-
- /* The user specified the size of the float registers. Check if it
- agrees with the ABI and ISA. */
- case 0:
- if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
- as_bad (_("-mfp64 used with a 32-bit fpu"));
- else if (ABI_NEEDS_32BIT_REGS (mips_abi)
- && !ISA_HAS_MXHC1 (mips_opts.isa))
- as_warn (_("-mfp64 used with a 32-bit ABI"));
- break;
- case 1:
- if (ABI_NEEDS_64BIT_REGS (mips_abi))
- as_warn (_("-mfp32 used with a 64-bit ABI"));
- break;
- }
-
- /* End of GCC-shared inference code. */
-
- /* This flag is set when we have a 64-bit capable CPU but use only
- 32-bit wide registers. Note that EABI does not use it. */
- if (ISA_HAS_64BIT_REGS (mips_opts.isa)
- && ((mips_abi == NO_ABI && file_mips_gp32 == 1)
- || mips_abi == O32_ABI))
- mips_32bitmode = 1;
-
- if (mips_opts.isa == ISA_MIPS1 && mips_trap)
- as_bad (_("trap exception not supported at ISA 1"));
-
- /* If the selected architecture includes support for ASEs, enable
- generation of code for them. */
- if (mips_opts.mips16 == -1)
- mips_opts.mips16 = (CPU_HAS_MIPS16 (file_mips_arch)) ? 1 : 0;
- if (mips_opts.micromips == -1)
- mips_opts.micromips = (CPU_HAS_MICROMIPS (file_mips_arch)) ? 1 : 0;
-
- /* MIPS3D and MDMX require 64-bit FPRs, so -mfp32 should stop those
- ASEs from being selected implicitly. */
- if (file_mips_fp32 == 1)
- file_ase_explicit |= ASE_MIPS3D | ASE_MDMX;
-
- /* If the user didn't explicitly select or deselect a particular ASE,
- use the default setting for the CPU. */
- mips_opts.ase |= (arch_info->ase & ~file_ase_explicit);
-
- file_mips_isa = mips_opts.isa;
- file_ase = mips_opts.ase;
- mips_opts.gp32 = file_mips_gp32;
- mips_opts.fp32 = file_mips_fp32;
- mips_opts.soft_float = file_mips_soft_float;
- mips_opts.single_float = file_mips_single_float;
-
- mips_check_isa_supports_ases ();
-
if (mips_flag_mdebug < 0)
mips_flag_mdebug = 0;
}
@@ -14026,19 +14578,13 @@ md_pcrel_from (fixS *fixP)
case BFD_RELOC_MICROMIPS_16_PCREL_S1:
case BFD_RELOC_MICROMIPS_JMP:
case BFD_RELOC_16_PCREL_S2:
+ case BFD_RELOC_MIPS_21_PCREL_S2:
+ case BFD_RELOC_MIPS_26_PCREL_S2:
case BFD_RELOC_MIPS_JMP:
/* Return the address of the delay slot. */
return addr + 4;
- case BFD_RELOC_32_PCREL:
- return addr;
-
default:
- /* We have no relocation type for PC relative MIPS16 instructions. */
- if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != now_seg)
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("PC relative MIPS16 instruction references"
- " a different section"));
return addr;
}
}
@@ -14199,6 +14745,17 @@ mips_force_relocation (fixS *fixp)
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1)
return 1;
+ /* We want all PC-relative relocations to be kept for R6 relaxation. */
+ if (ISA_IS_R6 (mips_opts.isa)
+ && (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_MIPS_21_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_MIPS_26_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_MIPS_18_PCREL_S3
+ || fixp->fx_r_type == BFD_RELOC_MIPS_19_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_HI16_S_PCREL
+ || fixp->fx_r_type == BFD_RELOC_LO16_PCREL))
+ return 1;
+
return 0;
}
@@ -14235,13 +14792,44 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
unsigned long insn;
reloc_howto_type *howto;
- /* We ignore generic BFD relocations we don't know about. */
- howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
- if (! howto)
- return;
+ if (fixP->fx_pcrel)
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_16_PCREL_S2:
+ case BFD_RELOC_MICROMIPS_7_PCREL_S1:
+ case BFD_RELOC_MICROMIPS_10_PCREL_S1:
+ case BFD_RELOC_MICROMIPS_16_PCREL_S1:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_MIPS_21_PCREL_S2:
+ case BFD_RELOC_MIPS_26_PCREL_S2:
+ case BFD_RELOC_MIPS_18_PCREL_S3:
+ case BFD_RELOC_MIPS_19_PCREL_S2:
+ case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_LO16_PCREL:
+ break;
+
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("PC-relative reference to a different section"));
+ break;
+ }
+
+ /* Handle BFD_RELOC_8, since it's easy. Punt on other bfd relocations
+ that have no MIPS ELF equivalent. */
+ if (fixP->fx_r_type != BFD_RELOC_8)
+ {
+ howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (!howto)
+ return;
+ }
gas_assert (fixP->fx_size == 2
|| fixP->fx_size == 4
+ || fixP->fx_r_type == BFD_RELOC_8
|| fixP->fx_r_type == BFD_RELOC_16
|| fixP->fx_r_type == BFD_RELOC_64
|| fixP->fx_r_type == BFD_RELOC_CTOR
@@ -14253,12 +14841,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
- gas_assert (!fixP->fx_pcrel || fixP->fx_r_type == BFD_RELOC_16_PCREL_S2
- || fixP->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
- || fixP->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
- || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
- || fixP->fx_r_type == BFD_RELOC_32_PCREL);
-
/* Don't treat parts of a composite relocation as done. There are two
reasons for this:
@@ -14408,6 +14990,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_32:
case BFD_RELOC_32_PCREL:
case BFD_RELOC_16:
+ case BFD_RELOC_8:
/* If we are deleting this reloc entry, we must fill in the
value now. This can happen if we have a .word which is not
resolved when it appears but is later defined. */
@@ -14415,6 +14998,38 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
md_number_to_chars (buf, *valP, fixP->fx_size);
break;
+ case BFD_RELOC_MIPS_21_PCREL_S2:
+ case BFD_RELOC_MIPS_26_PCREL_S2:
+ if ((*valP & 0x3) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch to misaligned address (%lx)"), (long) *valP);
+
+ gas_assert (!fixP->fx_done);
+ break;
+
+ case BFD_RELOC_MIPS_18_PCREL_S3:
+ if ((*valP & 0x7) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("PC-relative access to misaligned address (%lx)"),
+ (long) *valP);
+
+ gas_assert (!fixP->fx_done);
+ break;
+
+ case BFD_RELOC_MIPS_19_PCREL_S2:
+ if ((*valP & 0x3) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("PC-relative access to misaligned address (%lx)"),
+ (long) *valP);
+
+ gas_assert (!fixP->fx_done);
+ break;
+
+ case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_LO16_PCREL:
+ gas_assert (!fixP->fx_done);
+ break;
+
case BFD_RELOC_16_PCREL_S2:
if ((*valP & 0x3) != 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -14875,30 +15490,11 @@ struct mips_option_stack
static struct mips_option_stack *mips_opts_stack;
-/* Handle the .set pseudo-op. */
-
-static void
-s_mipsset (int x ATTRIBUTE_UNUSED)
+static bfd_boolean
+parse_code_option (char * name)
{
- char *name = input_line_pointer, ch;
const struct mips_ase *ase;
-
- while (!is_end_of_line[(unsigned char) *input_line_pointer])
- ++input_line_pointer;
- ch = *input_line_pointer;
- *input_line_pointer = '\0';
-
- if (strcmp (name, "reorder") == 0)
- {
- if (mips_opts.noreorder)
- end_noreorder ();
- }
- else if (strcmp (name, "noreorder") == 0)
- {
- if (!mips_opts.noreorder)
- start_noreorder ();
- }
- else if (strncmp (name, "at=", 3) == 0)
+ if (strncmp (name, "at=", 3) == 0)
{
char *s = name + 3;
@@ -14906,61 +15502,27 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
as_bad (_("unrecognized register name `%s'"), s);
}
else if (strcmp (name, "at") == 0)
- {
- mips_opts.at = ATREG;
- }
+ mips_opts.at = ATREG;
else if (strcmp (name, "noat") == 0)
- {
- mips_opts.at = ZERO;
- }
- else if (strcmp (name, "macro") == 0)
- {
- mips_opts.warn_about_macros = 0;
- }
- else if (strcmp (name, "nomacro") == 0)
- {
- if (mips_opts.noreorder == 0)
- as_bad (_("`noreorder' must be set before `nomacro'"));
- mips_opts.warn_about_macros = 1;
- }
+ mips_opts.at = ZERO;
else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
- {
- mips_opts.nomove = 0;
- }
+ mips_opts.nomove = 0;
else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
- {
- mips_opts.nomove = 1;
- }
+ mips_opts.nomove = 1;
else if (strcmp (name, "bopt") == 0)
- {
- mips_opts.nobopt = 0;
- }
+ mips_opts.nobopt = 0;
else if (strcmp (name, "nobopt") == 0)
- {
- mips_opts.nobopt = 1;
- }
- else if (strcmp (name, "gp=default") == 0)
- mips_opts.gp32 = file_mips_gp32;
+ mips_opts.nobopt = 1;
else if (strcmp (name, "gp=32") == 0)
- mips_opts.gp32 = 1;
+ mips_opts.gp = 32;
else if (strcmp (name, "gp=64") == 0)
- {
- if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
- as_warn (_("%s isa does not support 64-bit registers"),
- mips_cpu_info_from_isa (mips_opts.isa)->name);
- mips_opts.gp32 = 0;
- }
- else if (strcmp (name, "fp=default") == 0)
- mips_opts.fp32 = file_mips_fp32;
+ mips_opts.gp = 64;
else if (strcmp (name, "fp=32") == 0)
- mips_opts.fp32 = 1;
+ mips_opts.fp = 32;
+ else if (strcmp (name, "fp=xx") == 0)
+ mips_opts.fp = 0;
else if (strcmp (name, "fp=64") == 0)
- {
- if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
- as_warn (_("%s isa does not support 64-bit floating point registers"),
- mips_cpu_info_from_isa (mips_opts.isa)->name);
- mips_opts.fp32 = 0;
- }
+ mips_opts.fp = 64;
else if (strcmp (name, "softfloat") == 0)
mips_opts.soft_float = 1;
else if (strcmp (name, "hardfloat") == 0)
@@ -14969,47 +15531,35 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
mips_opts.single_float = 1;
else if (strcmp (name, "doublefloat") == 0)
mips_opts.single_float = 0;
+ else if (strcmp (name, "nooddspreg") == 0)
+ mips_opts.oddspreg = 0;
+ else if (strcmp (name, "oddspreg") == 0)
+ mips_opts.oddspreg = 1;
else if (strcmp (name, "mips16") == 0
|| strcmp (name, "MIPS-16") == 0)
- {
- if (mips_opts.micromips == 1)
- as_fatal (_("`mips16' cannot be used with `micromips'"));
- mips_opts.mips16 = 1;
- }
+ mips_opts.mips16 = 1;
else if (strcmp (name, "nomips16") == 0
|| strcmp (name, "noMIPS-16") == 0)
mips_opts.mips16 = 0;
else if (strcmp (name, "micromips") == 0)
- {
- if (mips_opts.mips16 == 1)
- as_fatal (_("`micromips' cannot be used with `mips16'"));
- mips_opts.micromips = 1;
- }
+ mips_opts.micromips = 1;
else if (strcmp (name, "nomicromips") == 0)
mips_opts.micromips = 0;
else if (name[0] == 'n'
&& name[1] == 'o'
&& (ase = mips_lookup_ase (name + 2)))
- mips_set_ase (ase, FALSE);
+ mips_set_ase (ase, &mips_opts, FALSE);
else if ((ase = mips_lookup_ase (name)))
- mips_set_ase (ase, TRUE);
+ mips_set_ase (ase, &mips_opts, TRUE);
else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
{
- int reset = 0;
-
/* Permit the user to change the ISA and architecture on the fly.
Needless to say, misuse can cause serious problems. */
- if (strcmp (name, "mips0") == 0 || strcmp (name, "arch=default") == 0)
- {
- reset = 1;
- mips_opts.isa = file_mips_isa;
- mips_opts.arch = file_mips_arch;
- }
- else if (strncmp (name, "arch=", 5) == 0)
+ if (strncmp (name, "arch=", 5) == 0)
{
const struct mips_cpu_info *p;
- p = mips_parse_cpu("internal use", name + 5);
+ p = mips_parse_cpu ("internal use", name + 5);
if (!p)
as_bad (_("unknown architecture %s"), name + 5);
else
@@ -15022,7 +15572,7 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
{
const struct mips_cpu_info *p;
- p = mips_parse_cpu("internal use", name);
+ p = mips_parse_cpu ("internal use", name);
if (!p)
as_bad (_("unknown ISA level %s"), name + 4);
else
@@ -15033,42 +15583,6 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
}
else
as_bad (_("unknown ISA or architecture %s"), name);
-
- switch (mips_opts.isa)
- {
- case 0:
- break;
- case ISA_MIPS1:
- case ISA_MIPS2:
- case ISA_MIPS32:
- case ISA_MIPS32R2:
- mips_opts.gp32 = 1;
- mips_opts.fp32 = 1;
- break;
- case ISA_MIPS3:
- case ISA_MIPS4:
- case ISA_MIPS5:
- case ISA_MIPS64:
- case ISA_MIPS64R2:
- mips_opts.gp32 = 0;
- if (mips_opts.arch == CPU_R5900)
- {
- mips_opts.fp32 = 1;
- }
- else
- {
- mips_opts.fp32 = 0;
- }
- break;
- default:
- as_bad (_("unknown ISA level %s"), name + 4);
- break;
- }
- if (reset)
- {
- mips_opts.gp32 = file_mips_gp32;
- mips_opts.fp32 = file_mips_fp32;
- }
}
else if (strcmp (name, "autoextend") == 0)
mips_opts.noautoextend = 0;
@@ -15078,6 +15592,68 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
mips_opts.insn32 = TRUE;
else if (strcmp (name, "noinsn32") == 0)
mips_opts.insn32 = FALSE;
+ else if (strcmp (name, "sym32") == 0)
+ mips_opts.sym32 = TRUE;
+ else if (strcmp (name, "nosym32") == 0)
+ mips_opts.sym32 = FALSE;
+ else
+ return FALSE;
+ return TRUE;
+}
+
+/* Handle the .set pseudo-op. */
+
+static void
+s_mipsset (int x ATTRIBUTE_UNUSED)
+{
+ char *name = input_line_pointer, ch;
+ int prev_isa = mips_opts.isa;
+
+ file_mips_check_options ();
+
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (strchr (name, ','))
+ {
+ /* Generic ".set" directive; use the generic handler. */
+ *input_line_pointer = ch;
+ input_line_pointer = name;
+ s_set (0);
+ return;
+ }
+
+ if (strcmp (name, "reorder") == 0)
+ {
+ if (mips_opts.noreorder)
+ end_noreorder ();
+ }
+ else if (strcmp (name, "noreorder") == 0)
+ {
+ if (!mips_opts.noreorder)
+ start_noreorder ();
+ }
+ else if (strcmp (name, "macro") == 0)
+ mips_opts.warn_about_macros = 0;
+ else if (strcmp (name, "nomacro") == 0)
+ {
+ if (mips_opts.noreorder == 0)
+ as_bad (_("`noreorder' must be set before `nomacro'"));
+ mips_opts.warn_about_macros = 1;
+ }
+ else if (strcmp (name, "gp=default") == 0)
+ mips_opts.gp = file_mips_opts.gp;
+ else if (strcmp (name, "fp=default") == 0)
+ mips_opts.fp = file_mips_opts.fp;
+ else if (strcmp (name, "mips0") == 0 || strcmp (name, "arch=default") == 0)
+ {
+ mips_opts.isa = file_mips_opts.isa;
+ mips_opts.arch = file_mips_opts.arch;
+ mips_opts.gp = file_mips_opts.gp;
+ mips_opts.fp = file_mips_opts.fp;
+ }
else if (strcmp (name, "push") == 0)
{
struct mips_option_stack *s;
@@ -15108,23 +15684,87 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
free (s);
}
}
- else if (strcmp (name, "sym32") == 0)
- mips_opts.sym32 = TRUE;
- else if (strcmp (name, "nosym32") == 0)
- mips_opts.sym32 = FALSE;
- else if (strchr (name, ','))
+ else if (!parse_code_option (name))
+ as_warn (_("tried to set unrecognized symbol: %s\n"), name);
+
+ /* The use of .set [arch|cpu]= historically 'fixes' the width of gp and fp
+ registers based on what is supported by the arch/cpu. */
+ if (mips_opts.isa != prev_isa)
{
- /* Generic ".set" directive; use the generic handler. */
- *input_line_pointer = ch;
- input_line_pointer = name;
- s_set (0);
- return;
+ switch (mips_opts.isa)
+ {
+ case 0:
+ break;
+ case ISA_MIPS1:
+ /* MIPS I cannot support FPXX. */
+ mips_opts.fp = 32;
+ /* fall-through. */
+ case ISA_MIPS2:
+ case ISA_MIPS32:
+ case ISA_MIPS32R2:
+ case ISA_MIPS32R3:
+ case ISA_MIPS32R5:
+ mips_opts.gp = 32;
+ if (mips_opts.fp != 0)
+ mips_opts.fp = 32;
+ break;
+ case ISA_MIPS32R6:
+ mips_opts.gp = 32;
+ mips_opts.fp = 64;
+ break;
+ case ISA_MIPS3:
+ case ISA_MIPS4:
+ case ISA_MIPS5:
+ case ISA_MIPS64:
+ case ISA_MIPS64R2:
+ case ISA_MIPS64R3:
+ case ISA_MIPS64R5:
+ case ISA_MIPS64R6:
+ mips_opts.gp = 64;
+ if (mips_opts.fp != 0)
+ {
+ if (mips_opts.arch == CPU_R5900)
+ mips_opts.fp = 32;
+ else
+ mips_opts.fp = 64;
+ }
+ break;
+ default:
+ as_bad (_("unknown ISA level %s"), name + 4);
+ break;
+ }
}
- else
+
+ mips_check_options (&mips_opts, FALSE);
+
+ mips_check_isa_supports_ases ();
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .module pseudo-op. */
+
+static void
+s_module (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name = input_line_pointer, ch;
+
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (!file_mips_opts_checked)
{
- as_warn (_("tried to set unrecognized symbol: %s\n"), name);
+ if (!parse_code_option (name))
+ as_bad (_(".module used with unrecognized symbol: %s\n"), name);
+
+ /* Update module level settings from mips_opts. */
+ file_mips_opts = mips_opts;
}
- mips_check_isa_supports_ases ();
+ else
+ as_bad (_(".module is not permitted after generating code"));
+
*input_line_pointer = ch;
demand_empty_rest_of_line ();
}
@@ -15171,6 +15811,8 @@ s_cpload (int ignore ATTRIBUTE_UNUSED)
int reg;
int in_shared;
+ file_mips_check_options ();
+
/* If we are not generating SVR4 PIC code, or if this is NewABI code,
.cpload is ignored. */
if (mips_pic != SVR4_PIC || HAVE_NEWABI)
@@ -15248,6 +15890,8 @@ s_cpsetup (int ignore ATTRIBUTE_UNUSED)
expressionS ex_sym;
int reg1;
+ file_mips_check_options ();
+
/* If we are not generating SVR4 PIC code, .cpsetup is ignored.
We also need NewABI support. */
if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
@@ -15351,6 +15995,8 @@ s_cpsetup (int ignore ATTRIBUTE_UNUSED)
static void
s_cplocal (int ignore ATTRIBUTE_UNUSED)
{
+ file_mips_check_options ();
+
/* If we are not generating SVR4 PIC code, or if this is not NewABI code,
.cplocal is ignored. */
if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
@@ -15379,6 +16025,8 @@ s_cprestore (int ignore ATTRIBUTE_UNUSED)
{
expressionS ex;
+ file_mips_check_options ();
+
/* If we are not generating SVR4 PIC code, or if this is NewABI code,
.cprestore is ignored. */
if (mips_pic != SVR4_PIC || HAVE_NEWABI)
@@ -15426,6 +16074,8 @@ s_cpreturn (int ignore ATTRIBUTE_UNUSED)
{
expressionS ex;
+ file_mips_check_options ();
+
/* If we are not generating SVR4 PIC code, .cpreturn is ignored.
We also need NewABI support. */
if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
@@ -15660,6 +16310,8 @@ s_cpadd (int ignore ATTRIBUTE_UNUSED)
{
int reg;
+ file_mips_check_options ();
+
/* This is ignored when not generating SVR4 PIC code. */
if (mips_pic != SVR4_PIC)
{
@@ -15692,6 +16344,10 @@ s_cpadd (int ignore ATTRIBUTE_UNUSED)
static void
s_insn (int ignore ATTRIBUTE_UNUSED)
{
+ file_mips_check_options ();
+ file_ase_mips16 |= mips_opts.mips16;
+ file_ase_micromips |= mips_opts.micromips;
+
mips_mark_labels ();
demand_empty_rest_of_line ();
@@ -15710,10 +16366,16 @@ s_nan (int ignore ATTRIBUTE_UNUSED)
if (i == sizeof (str_2008) - 1
&& memcmp (input_line_pointer, str_2008, i) == 0)
- mips_flag_nan2008 = TRUE;
+ mips_nan2008 = 1;
else if (i == sizeof (str_legacy) - 1
&& memcmp (input_line_pointer, str_legacy, i) == 0)
- mips_flag_nan2008 = FALSE;
+ {
+ if (ISA_HAS_LEGACY_NAN (file_mips_opts.isa))
+ mips_nan2008 = 0;
+ else
+ as_bad (_("`%s' does not support legacy NaN"),
+ mips_cpu_info_from_isa (file_mips_opts.isa)->name);
+ }
else
as_bad (_("bad .nan directive"));
@@ -16410,8 +17072,11 @@ mips_fix_adjustable (fixS *fixp)
/* There is no place to store an in-place offset for JALR relocations.
Likewise an in-range offset of limited PC-relative relocations may
overflow the in-place relocatable field if recalculated against the
- start address of the symbol's containing section. */
- if (HAVE_IN_PLACE_ADDENDS
+ start address of the symbol's containing section.
+
+ Also, PC relative relocations for MIPS R6 need to be symbol rather than
+ section relative to allow linker relaxations to be performed later on. */
+ if ((HAVE_IN_PLACE_ADDENDS || ISA_IS_R6 (mips_opts.isa))
&& (limited_pcrel_reloc_p (fixp->fx_r_type)
|| jalr_reloc_p (fixp->fx_r_type)))
return 0;
@@ -16491,7 +17156,13 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
- || fixp->fx_r_type == BFD_RELOC_32_PCREL);
+ || fixp->fx_r_type == BFD_RELOC_32_PCREL
+ || fixp->fx_r_type == BFD_RELOC_MIPS_21_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_MIPS_26_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_MIPS_18_PCREL_S3
+ || fixp->fx_r_type == BFD_RELOC_MIPS_19_PCREL_S2
+ || fixp->fx_r_type == BFD_RELOC_HI16_S_PCREL
+ || fixp->fx_r_type == BFD_RELOC_LO16_PCREL);
/* At this point, fx_addnumber is "symbol offset - pcrel address".
Relocations want only the symbol offset. */
@@ -17225,11 +17896,131 @@ mips_add_dot_label (symbolS *sym)
mips_compressed_mark_label (sym);
}
+/* Converting ASE flags from internal to .MIPS.abiflags values. */
+static unsigned int
+mips_convert_ase_flags (int ase)
+{
+ unsigned int ext_ases = 0;
+
+ if (ase & ASE_DSP)
+ ext_ases |= AFL_ASE_DSP;
+ if (ase & ASE_DSPR2)
+ ext_ases |= AFL_ASE_DSPR2;
+ if (ase & ASE_EVA)
+ ext_ases |= AFL_ASE_EVA;
+ if (ase & ASE_MCU)
+ ext_ases |= AFL_ASE_MCU;
+ if (ase & ASE_MDMX)
+ ext_ases |= AFL_ASE_MDMX;
+ if (ase & ASE_MIPS3D)
+ ext_ases |= AFL_ASE_MIPS3D;
+ if (ase & ASE_MT)
+ ext_ases |= AFL_ASE_MT;
+ if (ase & ASE_SMARTMIPS)
+ ext_ases |= AFL_ASE_SMARTMIPS;
+ if (ase & ASE_VIRT)
+ ext_ases |= AFL_ASE_VIRT;
+ if (ase & ASE_MSA)
+ ext_ases |= AFL_ASE_MSA;
+ if (ase & ASE_XPA)
+ ext_ases |= AFL_ASE_XPA;
+
+ return ext_ases;
+}
/* Some special processing for a MIPS ELF file. */
void
mips_elf_final_processing (void)
{
+ int fpabi;
+ Elf_Internal_ABIFlags_v0 flags;
+
+ flags.version = 0;
+ flags.isa_rev = 0;
+ switch (file_mips_opts.isa)
+ {
+ case INSN_ISA1:
+ flags.isa_level = 1;
+ break;
+ case INSN_ISA2:
+ flags.isa_level = 2;
+ break;
+ case INSN_ISA3:
+ flags.isa_level = 3;
+ break;
+ case INSN_ISA4:
+ flags.isa_level = 4;
+ break;
+ case INSN_ISA5:
+ flags.isa_level = 5;
+ break;
+ case INSN_ISA32:
+ flags.isa_level = 32;
+ flags.isa_rev = 1;
+ break;
+ case INSN_ISA32R2:
+ flags.isa_level = 32;
+ flags.isa_rev = 2;
+ break;
+ case INSN_ISA32R3:
+ flags.isa_level = 32;
+ flags.isa_rev = 3;
+ break;
+ case INSN_ISA32R5:
+ flags.isa_level = 32;
+ flags.isa_rev = 5;
+ break;
+ case INSN_ISA32R6:
+ flags.isa_level = 32;
+ flags.isa_rev = 6;
+ break;
+ case INSN_ISA64:
+ flags.isa_level = 64;
+ flags.isa_rev = 1;
+ break;
+ case INSN_ISA64R2:
+ flags.isa_level = 64;
+ flags.isa_rev = 2;
+ break;
+ case INSN_ISA64R3:
+ flags.isa_level = 64;
+ flags.isa_rev = 3;
+ break;
+ case INSN_ISA64R5:
+ flags.isa_level = 64;
+ flags.isa_rev = 5;
+ break;
+ case INSN_ISA64R6:
+ flags.isa_level = 64;
+ flags.isa_rev = 6;
+ break;
+ }
+
+ flags.gpr_size = file_mips_opts.gp == 32 ? AFL_REG_32 : AFL_REG_64;
+ flags.cpr1_size = file_mips_opts.soft_float ? AFL_REG_NONE
+ : (file_mips_opts.ase & ASE_MSA) ? AFL_REG_128
+ : (file_mips_opts.fp == 64) ? AFL_REG_64
+ : AFL_REG_32;
+ flags.cpr2_size = AFL_REG_NONE;
+ flags.fp_abi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
+ Tag_GNU_MIPS_ABI_FP);
+ flags.isa_ext = bfd_mips_isa_ext (stdoutput);
+ flags.ases = mips_convert_ase_flags (file_mips_opts.ase);
+ if (file_ase_mips16)
+ flags.ases |= AFL_ASE_MIPS16;
+ if (file_ase_micromips)
+ flags.ases |= AFL_ASE_MICROMIPS;
+ flags.flags1 = 0;
+ if ((ISA_HAS_ODD_SINGLE_FPR (file_mips_opts.isa, file_mips_opts.arch)
+ || file_mips_opts.fp == 64)
+ && file_mips_opts.oddspreg)
+ flags.flags1 |= AFL_FLAGS1_ODDSPREG;
+ flags.flags2 = 0;
+
+ bfd_mips_elf_swap_abiflags_v0_out (stdoutput, &flags,
+ ((Elf_External_ABIFlags_v0 *)
+ mips_flags_frag));
+
/* Write out the register information. */
if (mips_abi != N64_ABI)
{
@@ -17281,7 +18072,7 @@ mips_elf_final_processing (void)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
if (file_ase_micromips)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MICROMIPS;
- if (file_ase & ASE_MDMX)
+ if (file_mips_opts.ase & ASE_MDMX)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MDMX;
/* Set the MIPS ELF ABI flags. */
@@ -17291,7 +18082,7 @@ mips_elf_final_processing (void)
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64;
else if (mips_abi == EABI_ABI)
{
- if (!file_mips_gp32)
+ if (file_mips_opts.gp == 64)
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64;
else
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
@@ -17304,11 +18095,13 @@ mips_elf_final_processing (void)
if (mips_32bitmode)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
- if (mips_flag_nan2008)
+ if (mips_nan2008 == 1)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_NAN2008;
/* 32 bit code with 64 bit FP registers. */
- if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
+ fpabi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
+ Tag_GNU_MIPS_ABI_FP);
+ if (fpabi == Val_GNU_MIPS_ABI_FP_OLD_64)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_FP64;
}
@@ -17412,19 +18205,6 @@ mips_handle_align (fragS *fragp)
fragp->fr_var = size;
}
-static void
-md_obj_begin (void)
-{
-}
-
-static void
-md_obj_end (void)
-{
- /* Check for premature end, nesting errors, etc. */
- if (cur_proc_ptr)
- as_warn (_("missing .end at end of assembly"));
-}
-
static long
get_number (void)
{
@@ -17759,8 +18539,14 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
{ "mips5", MIPS_CPU_IS_ISA, 0, ISA_MIPS5, CPU_MIPS5 },
{ "mips32", MIPS_CPU_IS_ISA, 0, ISA_MIPS32, CPU_MIPS32 },
{ "mips32r2", MIPS_CPU_IS_ISA, 0, ISA_MIPS32R2, CPU_MIPS32R2 },
+ { "mips32r3", MIPS_CPU_IS_ISA, 0, ISA_MIPS32R3, CPU_MIPS32R3 },
+ { "mips32r5", MIPS_CPU_IS_ISA, 0, ISA_MIPS32R5, CPU_MIPS32R5 },
+ { "mips32r6", MIPS_CPU_IS_ISA, 0, ISA_MIPS32R6, CPU_MIPS32R6 },
{ "mips64", MIPS_CPU_IS_ISA, 0, ISA_MIPS64, CPU_MIPS64 },
{ "mips64r2", MIPS_CPU_IS_ISA, 0, ISA_MIPS64R2, CPU_MIPS64R2 },
+ { "mips64r3", MIPS_CPU_IS_ISA, 0, ISA_MIPS64R3, CPU_MIPS64R3 },
+ { "mips64r5", MIPS_CPU_IS_ISA, 0, ISA_MIPS64R5, CPU_MIPS64R5 },
+ { "mips64r6", MIPS_CPU_IS_ISA, 0, ISA_MIPS64R6, CPU_MIPS64R6 },
/* MIPS I */
{ "r3000", 0, 0, ISA_MIPS1, CPU_R3000 },
@@ -17863,6 +18649,8 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
{ "1004kf2_1", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf1_1", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
+ /* P5600 with EVA and Virtualization ASEs, other ASEs are optional. */
+ { "p5600", 0, ASE_VIRT | ASE_EVA | ASE_XPA, ISA_MIPS32R5, CPU_MIPS32R5 },
/* MIPS 64 */
{ "5kc", 0, 0, ISA_MIPS64, CPU_MIPS64 },
@@ -17875,7 +18663,7 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
/* Broadcom SB-1A CPU core */
{ "sb1a", 0, ASE_MIPS3D | ASE_MDMX, ISA_MIPS64, CPU_SB1 },
- { "loongson3a", 0, 0, ISA_MIPS64, CPU_LOONGSON_3A },
+ { "loongson3a", 0, 0, ISA_MIPS64R2, CPU_LOONGSON_3A },
/* MIPS 64 Release 2 */
@@ -17976,8 +18764,9 @@ mips_parse_cpu (const char *option, const char *cpu_string)
if (ABI_NEEDS_64BIT_REGS (mips_abi))
return mips_cpu_info_from_isa (ISA_MIPS3);
- if (file_mips_gp32 >= 0)
- return mips_cpu_info_from_isa (file_mips_gp32 ? ISA_MIPS1 : ISA_MIPS3);
+ if (file_mips_opts.gp >= 0)
+ return mips_cpu_info_from_isa (file_mips_opts.gp == 32
+ ? ISA_MIPS1 : ISA_MIPS3);
return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT
? ISA_MIPS3
@@ -18071,8 +18860,14 @@ MIPS options:\n\
-mips5 generate MIPS ISA V instructions\n\
-mips32 generate MIPS32 ISA instructions\n\
-mips32r2 generate MIPS32 release 2 ISA instructions\n\
+-mips32r3 generate MIPS32 release 3 ISA instructions\n\
+-mips32r5 generate MIPS32 release 5 ISA instructions\n\
+-mips32r6 generate MIPS32 release 6 ISA instructions\n\
-mips64 generate MIPS64 ISA instructions\n\
-mips64r2 generate MIPS64 release 2 ISA instructions\n\
+-mips64r3 generate MIPS64 release 3 ISA instructions\n\
+-mips64r5 generate MIPS64 release 5 ISA instructions\n\
+-mips64r6 generate MIPS64 release 6 ISA instructions\n\
-march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
first = 1;
@@ -18120,6 +18915,9 @@ MIPS options:\n\
-mmsa generate MSA instructions\n\
-mno-msa do not generate MSA instructions\n"));
fprintf (stream, _("\
+-mxpa generate eXtended Physical Address (XPA) instructions\n\
+-mno-xpa do not generate eXtended Physical Address (XPA) instructions\n"));
+ fprintf (stream, _("\
-mvirt generate Virtualization instructions\n\
-mno-virt do not generate Virtualization instructions\n"));
fprintf (stream, _("\
@@ -18220,3 +19018,91 @@ tc_mips_regname_to_dw2regnum (char *regname)
return regnum;
}
+
+/* Implement CONVERT_SYMBOLIC_ATTRIBUTE.
+ Given a symbolic attribute NAME, return the proper integer value.
+ Returns -1 if the attribute is not known. */
+
+int
+mips_convert_symbolic_attribute (const char *name)
+{
+ static const struct
+ {
+ const char * name;
+ const int tag;
+ }
+ attribute_table[] =
+ {
+#define T(tag) {#tag, tag}
+ T (Tag_GNU_MIPS_ABI_FP),
+ T (Tag_GNU_MIPS_ABI_MSA),
+#undef T
+ };
+ unsigned int i;
+
+ if (name == NULL)
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
+ if (streq (name, attribute_table[i].name))
+ return attribute_table[i].tag;
+
+ return -1;
+}
+
+void
+md_mips_end (void)
+{
+ int fpabi = Val_GNU_MIPS_ABI_FP_ANY;
+
+ mips_emit_delays ();
+ if (cur_proc_ptr)
+ as_warn (_("missing .end at end of assembly"));
+
+ /* Just in case no code was emitted, do the consistency check. */
+ file_mips_check_options ();
+
+ /* Set a floating-point ABI if the user did not. */
+ if (obj_elf_seen_attribute (OBJ_ATTR_GNU, Tag_GNU_MIPS_ABI_FP))
+ {
+ /* Perform consistency checks on the floating-point ABI. */
+ fpabi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
+ Tag_GNU_MIPS_ABI_FP);
+ if (fpabi != Val_GNU_MIPS_ABI_FP_ANY)
+ check_fpabi (fpabi);
+ }
+ else
+ {
+ /* Soft-float gets precedence over single-float, the two options should
+ not be used together so this should not matter. */
+ if (file_mips_opts.soft_float == 1)
+ fpabi = Val_GNU_MIPS_ABI_FP_SOFT;
+ /* Single-float gets precedence over all double_float cases. */
+ else if (file_mips_opts.single_float == 1)
+ fpabi = Val_GNU_MIPS_ABI_FP_SINGLE;
+ else
+ {
+ switch (file_mips_opts.fp)
+ {
+ case 32:
+ if (file_mips_opts.gp == 32)
+ fpabi = Val_GNU_MIPS_ABI_FP_DOUBLE;
+ break;
+ case 0:
+ fpabi = Val_GNU_MIPS_ABI_FP_XX;
+ break;
+ case 64:
+ if (file_mips_opts.gp == 32 && !file_mips_opts.oddspreg)
+ fpabi = Val_GNU_MIPS_ABI_FP_64A;
+ else if (file_mips_opts.gp == 32)
+ fpabi = Val_GNU_MIPS_ABI_FP_64;
+ else
+ fpabi = Val_GNU_MIPS_ABI_FP_DOUBLE;
+ break;
+ }
+ }
+
+ bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU,
+ Tag_GNU_MIPS_ABI_FP, fpabi);
+ }
+}
diff --git a/binutils-2.25/gas/config/tc-mips.h b/binutils-2.25/gas/config/tc-mips.h
index c7eaa04e..0b8e6074 100644
--- a/binutils-2.25/gas/config/tc-mips.h
+++ b/binutils-2.25/gas/config/tc-mips.h
@@ -1,6 +1,5 @@
/* tc-mips.h -- header file for tc-mips.c.
- Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
Modified for ECOFF support by Ian Lance Taylor of Cygnus Support.
@@ -190,4 +189,12 @@ extern int tc_mips_regname_to_dw2regnum (char *regname);
#define DWARF2_DEFAULT_RETURN_COLUMN 31
#define DWARF2_CIE_DATA_ALIGNMENT (-4)
+#define DIFF_EXPR_OK
+/* We define DIFF_EXPR_OK because of R_MIPS_PC32, but we have no
+ 64-bit form for n64 CFIs. */
+#define CFI_DIFF_EXPR_OK 0
+
+#define CONVERT_SYMBOLIC_ATTRIBUTE(name) mips_convert_symbolic_attribute (name)
+extern int mips_convert_symbolic_attribute (const char *);
+
#endif /* TC_MIPS */
diff --git a/binutils-2.25/gas/config/tc-mmix.c b/binutils-2.25/gas/config/tc-mmix.c
index 7052b116..82f48ae7 100644
--- a/binutils-2.25/gas/config/tc-mmix.c
+++ b/binutils-2.25/gas/config/tc-mmix.c
@@ -1,6 +1,5 @@
/* tc-mmix.c -- Assembler for Don Knuth's MMIX.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2012 Free Software Foundation.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -113,6 +112,7 @@ static struct loc_assert_s
{
segT old_seg;
symbolS *loc_sym;
+ fragS *frag;
struct loc_assert_s *next;
} *loc_asserts = NULL;
@@ -3007,7 +3007,7 @@ mmix_handle_mmixal (void)
it the same alignment and address as the associated instruction. */
/* Make room for the label including the ending nul. */
- int len_0 = s - label + 1;
+ size_t len_0 = s - label + 1;
/* Save this label on the MMIX symbol obstack. Saving it on an
obstack is needless for "IS"-pseudos, but it's harmless and we
@@ -3561,6 +3561,15 @@ mmix_md_end (void)
as_bad_where (fnam, line,
_("LOC to section unknown or indeterminable "
"at first pass"));
+
+ /* Patch up the generic location data to avoid cascading
+ error messages from later passes. (See original in
+ write.c:relax_segment.) */
+ fragP = loc_assert->frag;
+ fragP->fr_type = rs_align;
+ fragP->fr_subtype = 0;
+ fragP->fr_offset = 0;
+ fragP->fr_fix = 0;
}
}
@@ -4085,6 +4094,7 @@ s_loc (int ignore ATTRIBUTE_UNUSED)
loc_asserts->next = next;
loc_asserts->old_seg = now_seg;
loc_asserts->loc_sym = esym;
+ loc_asserts->frag = frag_now;
}
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0);
diff --git a/binutils-2.25/gas/config/tc-mmix.h b/binutils-2.25/gas/config/tc-mmix.h
index dba24a2d..78d8adf2 100644
--- a/binutils-2.25/gas/config/tc-mmix.h
+++ b/binutils-2.25/gas/config/tc-mmix.h
@@ -1,6 +1,5 @@
/* tc-mmix.h -- Header file for tc-mmix.c.
- Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
Written by Hans-Peter Nilsson (hp@bitrange.com).
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mn10200.c b/binutils-2.25/gas/config/tc-mn10200.c
index e9c70f22..f76fb083 100644
--- a/binutils-2.25/gas/config/tc-mn10200.c
+++ b/binutils-2.25/gas/config/tc-mn10200.c
@@ -1,5 +1,5 @@
/* tc-mn10200.c -- Assembler code for the Matsushita 10200
- Copyright 1996-2013 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mn10200.h b/binutils-2.25/gas/config/tc-mn10200.h
index 1fed4612..6eb0418b 100644
--- a/binutils-2.25/gas/config/tc-mn10200.h
+++ b/binutils-2.25/gas/config/tc-mn10200.h
@@ -1,5 +1,5 @@
/* tc-mn10200.h -- Header file for tc-mn10200.c.
- Copyright 1996, 1997, 2000, 2001, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mn10300.c b/binutils-2.25/gas/config/tc-mn10300.c
index 4029c641..3d159b18 100644
--- a/binutils-2.25/gas/config/tc-mn10300.c
+++ b/binutils-2.25/gas/config/tc-mn10300.c
@@ -1,6 +1,5 @@
/* tc-mn10300.c -- Assembler code for the Matsushita 10300
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -1014,7 +1013,8 @@ mn10300_check_fixup (struct mn10300_fixup *fixup)
}
void
-mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
+mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp,
+ bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
{
struct mn10300_fixup fixup;
diff --git a/binutils-2.25/gas/config/tc-mn10300.h b/binutils-2.25/gas/config/tc-mn10300.h
index 53c41501..d502430a 100644
--- a/binutils-2.25/gas/config/tc-mn10300.h
+++ b/binutils-2.25/gas/config/tc-mn10300.h
@@ -1,6 +1,5 @@
/* tc-mn10300.h -- Header file for tc-mn10300.c.
- Copyright 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -40,9 +39,10 @@ extern bfd_boolean mn10300_force_relocation (struct fix *);
mn10300_parse_name ((NAME), (EXPRP), (MODE), (NEXTCHARP))
int mn10300_parse_name (char const *, expressionS *, enum expr_mode, char *);
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
- mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
-void mn10300_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+ mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP), (RELOC))
+void mn10300_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
symbols. The relocation type is stored in X_md. */
diff --git a/binutils-2.25/gas/config/tc-moxie.c b/binutils-2.25/gas/config/tc-moxie.c
index fa8ace58..02a59b7c 100644
--- a/binutils-2.25/gas/config/tc-moxie.c
+++ b/binutils-2.25/gas/config/tc-moxie.c
@@ -1,6 +1,5 @@
/* tc-moxie.c -- Assemble code for moxie
- Copyright 2009, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -47,7 +46,6 @@ static valueT md_chars_to_number (char * buf, int n);
/* Byte order. */
extern int target_big_endian;
-const char *moxie_target_format = DEFAULT_TARGET_FORMAT;
void
md_operand (expressionS *op __attribute__((unused)))
@@ -76,6 +74,8 @@ md_begin (void)
for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+
bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
}
@@ -618,11 +618,9 @@ md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
{
case OPTION_EB:
target_big_endian = 1;
- moxie_target_format = "elf32-bigmoxie";
break;
case OPTION_EL:
target_big_endian = 0;
- moxie_target_format = "elf32-littlemoxie";
break;
default:
return 0;
diff --git a/binutils-2.25/gas/config/tc-moxie.h b/binutils-2.25/gas/config/tc-moxie.h
index af4fe510..0a88813d 100644
--- a/binutils-2.25/gas/config/tc-moxie.h
+++ b/binutils-2.25/gas/config/tc-moxie.h
@@ -1,6 +1,6 @@
/* tc-moxie.h -- Header file for tc-moxie.c.
- Copyright 2009, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -19,13 +19,13 @@
Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#define TC_MOXIE 1
+#ifndef TARGET_BYTES_BIG_ENDIAN
#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
#define WORKING_DOT_WORD
/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'. */
-const char *moxie_target_format;
-#define DEFAULT_TARGET_FORMAT "elf32-bigmoxie"
-#define TARGET_FORMAT moxie_target_format
+#define TARGET_FORMAT (target_big_endian ? "elf32-bigmoxie" : "elf32-littlemoxie")
#define TARGET_ARCH bfd_arch_moxie
@@ -34,7 +34,7 @@ const char *moxie_target_format;
/* These macros must be defined, but is will be a fatal assembler
error if we ever hit them. */
#define md_estimate_size_before_relax(A, B) (as_fatal (_("estimate size\n")), 0)
-#define md_convert_frag(B, S, F) (as_fatal (_("convert_frag\n")), 0)
+#define md_convert_frag(B, S, F) as_fatal (_("convert_frag\n"))
/* If you define this macro, it should return the offset between the
address of a PC relative fixup and the position from which the PC
diff --git a/binutils-2.25/gas/config/tc-msp430.c b/binutils-2.25/gas/config/tc-msp430.c
index 67aac43f..25ec0ee4 100644
--- a/binutils-2.25/gas/config/tc-msp430.c
+++ b/binutils-2.25/gas/config/tc-msp430.c
@@ -1,6 +1,6 @@
/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
- Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of GAS, the GNU Assembler.
@@ -264,490 +264,36 @@ typedef enum msp_isa
MSP_ISA_430Xv2
} msp_isa;
-struct mcu_type_s
-{
- char * name;
- msp_isa isa;
-};
-
-static struct mcu_type_s mcu_types[] =
-{
- {"msp430afe221", MSP_ISA_430},
- {"msp430afe222", MSP_ISA_430},
- {"msp430afe223", MSP_ISA_430},
- {"msp430afe231", MSP_ISA_430},
- {"msp430afe232", MSP_ISA_430},
- {"msp430afe233", MSP_ISA_430},
- {"msp430afe251", MSP_ISA_430},
- {"msp430afe252", MSP_ISA_430},
- {"msp430afe253", MSP_ISA_430},
- {"msp430c091", MSP_ISA_430},
- {"msp430c092", MSP_ISA_430},
- {"msp430c111", MSP_ISA_430},
- {"msp430c1111", MSP_ISA_430},
- {"msp430c112", MSP_ISA_430},
- {"msp430c1121", MSP_ISA_430},
- {"msp430e112", MSP_ISA_430},
- {"msp430c1331", MSP_ISA_430},
- {"msp430c1351", MSP_ISA_430},
- {"msp430c311s", MSP_ISA_430},
- {"msp430c312", MSP_ISA_430},
- {"msp430c313", MSP_ISA_430},
- {"msp430c314", MSP_ISA_430},
- {"msp430c315", MSP_ISA_430},
- {"msp430c323", MSP_ISA_430},
- {"msp430c325", MSP_ISA_430},
- {"msp430c336", MSP_ISA_430},
- {"msp430c337", MSP_ISA_430},
- {"msp430c412", MSP_ISA_430},
- {"msp430c413", MSP_ISA_430},
- {"msp430e313", MSP_ISA_430},
- {"msp430e315", MSP_ISA_430},
- {"msp430e325", MSP_ISA_430},
- {"msp430e337", MSP_ISA_430},
- {"msp430f110", MSP_ISA_430},
- {"msp430f1101", MSP_ISA_430},
- {"msp430f1101a", MSP_ISA_430},
- {"msp430f1111", MSP_ISA_430},
- {"msp430f1111a", MSP_ISA_430},
- {"msp430f112", MSP_ISA_430},
- {"msp430f1121", MSP_ISA_430},
- {"msp430f1121a", MSP_ISA_430},
- {"msp430f1122", MSP_ISA_430},
- {"msp430f1132", MSP_ISA_430},
- {"msp430f122", MSP_ISA_430},
- {"msp430f1222", MSP_ISA_430},
- {"msp430f123", MSP_ISA_430},
- {"msp430f1232", MSP_ISA_430},
- {"msp430f133", MSP_ISA_430},
- {"msp430f135", MSP_ISA_430},
- {"msp430f147", MSP_ISA_430},
- {"msp430f1471", MSP_ISA_430},
- {"msp430f148", MSP_ISA_430},
- {"msp430f1481", MSP_ISA_430},
- {"msp430f149", MSP_ISA_430},
- {"msp430f1491", MSP_ISA_430},
- {"msp430f155", MSP_ISA_430},
- {"msp430f156", MSP_ISA_430},
- {"msp430f157", MSP_ISA_430},
- {"msp430f1610", MSP_ISA_430},
- {"msp430f1611", MSP_ISA_430},
- {"msp430f1612", MSP_ISA_430},
- {"msp430f167", MSP_ISA_430},
- {"msp430f168", MSP_ISA_430},
- {"msp430f169", MSP_ISA_430},
- {"msp430f2001", MSP_ISA_430},
- {"msp430f2002", MSP_ISA_430},
- {"msp430f2003", MSP_ISA_430},
- {"msp430f2011", MSP_ISA_430},
- {"msp430f2012", MSP_ISA_430},
- {"msp430f2013", MSP_ISA_430},
- {"msp430f2101", MSP_ISA_430},
- {"msp430f2111", MSP_ISA_430},
- {"msp430f2112", MSP_ISA_430},
- {"msp430f2121", MSP_ISA_430},
- {"msp430f2122", MSP_ISA_430},
- {"msp430f2131", MSP_ISA_430},
- {"msp430f2132", MSP_ISA_430},
- {"msp430f2232", MSP_ISA_430},
- {"msp430f2234", MSP_ISA_430},
- {"msp430f2252", MSP_ISA_430},
- {"msp430f2254", MSP_ISA_430},
- {"msp430f2272", MSP_ISA_430},
- {"msp430f2274", MSP_ISA_430},
- {"msp430f233", MSP_ISA_430},
- {"msp430f2330", MSP_ISA_430},
- {"msp430f235", MSP_ISA_430},
- {"msp430f2350", MSP_ISA_430},
- {"msp430f2370", MSP_ISA_430},
- {"msp430f2410", MSP_ISA_430},
- {"msp430f247", MSP_ISA_430},
- {"msp430f2471", MSP_ISA_430},
- {"msp430f248", MSP_ISA_430},
- {"msp430f2481", MSP_ISA_430},
- {"msp430f249", MSP_ISA_430},
- {"msp430f2491", MSP_ISA_430},
- {"msp430f412", MSP_ISA_430},
- {"msp430f413", MSP_ISA_430},
- {"msp430f4132", MSP_ISA_430},
- {"msp430f415", MSP_ISA_430},
- {"msp430f4152", MSP_ISA_430},
- {"msp430f417", MSP_ISA_430},
- {"msp430f423", MSP_ISA_430},
- {"msp430f423a", MSP_ISA_430},
- {"msp430f425", MSP_ISA_430},
- {"msp430f4250", MSP_ISA_430},
- {"msp430f425a", MSP_ISA_430},
- {"msp430f4260", MSP_ISA_430},
- {"msp430f427", MSP_ISA_430},
- {"msp430f4270", MSP_ISA_430},
- {"msp430f427a", MSP_ISA_430},
- {"msp430f435", MSP_ISA_430},
- {"msp430f4351", MSP_ISA_430},
- {"msp430f436", MSP_ISA_430},
- {"msp430f4361", MSP_ISA_430},
- {"msp430f437", MSP_ISA_430},
- {"msp430f4371", MSP_ISA_430},
- {"msp430f438", MSP_ISA_430},
- {"msp430f439", MSP_ISA_430},
- {"msp430f447", MSP_ISA_430},
- {"msp430f448", MSP_ISA_430},
- {"msp430f4481", MSP_ISA_430},
- {"msp430f449", MSP_ISA_430},
- {"msp430f4491", MSP_ISA_430},
- {"msp430f477", MSP_ISA_430},
- {"msp430f478", MSP_ISA_430},
- {"msp430f4783", MSP_ISA_430},
- {"msp430f4784", MSP_ISA_430},
- {"msp430f479", MSP_ISA_430},
- {"msp430f4793", MSP_ISA_430},
- {"msp430f4794", MSP_ISA_430},
- {"msp430fe423", MSP_ISA_430},
- {"msp430fe4232", MSP_ISA_430},
- {"msp430fe423a", MSP_ISA_430},
- {"msp430fe4242", MSP_ISA_430},
- {"msp430fe425", MSP_ISA_430},
- {"msp430fe4252", MSP_ISA_430},
- {"msp430fe425a", MSP_ISA_430},
- {"msp430fe427", MSP_ISA_430},
- {"msp430fe4272", MSP_ISA_430},
- {"msp430fe427a", MSP_ISA_430},
- {"msp430fg4250", MSP_ISA_430},
- {"msp430fg4260", MSP_ISA_430},
- {"msp430fg4270", MSP_ISA_430},
- {"msp430fg437", MSP_ISA_430},
- {"msp430fg438", MSP_ISA_430},
- {"msp430fg439", MSP_ISA_430},
- {"msp430fg477", MSP_ISA_430},
- {"msp430fg478", MSP_ISA_430},
- {"msp430fg479", MSP_ISA_430},
- {"msp430fw423", MSP_ISA_430},
- {"msp430fw425", MSP_ISA_430},
- {"msp430fw427", MSP_ISA_430},
- {"msp430fw428", MSP_ISA_430},
- {"msp430fw429", MSP_ISA_430},
- {"msp430g2001", MSP_ISA_430},
- {"msp430g2101", MSP_ISA_430},
- {"msp430g2102", MSP_ISA_430},
- {"msp430g2111", MSP_ISA_430},
- {"msp430g2112", MSP_ISA_430},
- {"msp430g2113", MSP_ISA_430},
- {"msp430g2121", MSP_ISA_430},
- {"msp430g2131", MSP_ISA_430},
- {"msp430g2132", MSP_ISA_430},
- {"msp430g2152", MSP_ISA_430},
- {"msp430g2153", MSP_ISA_430},
- {"msp430g2201", MSP_ISA_430},
- {"msp430g2202", MSP_ISA_430},
- {"msp430g2203", MSP_ISA_430},
- {"msp430g2210", MSP_ISA_430},
- {"msp430g2211", MSP_ISA_430},
- {"msp430g2212", MSP_ISA_430},
- {"msp430g2213", MSP_ISA_430},
- {"msp430g2221", MSP_ISA_430},
- {"msp430g2230", MSP_ISA_430},
- {"msp430g2231", MSP_ISA_430},
- {"msp430g2232", MSP_ISA_430},
- {"msp430g2233", MSP_ISA_430},
- {"msp430g2252", MSP_ISA_430},
- {"msp430g2253", MSP_ISA_430},
- {"msp430g2302", MSP_ISA_430},
- {"msp430g2303", MSP_ISA_430},
- {"msp430g2312", MSP_ISA_430},
- {"msp430g2313", MSP_ISA_430},
- {"msp430g2332", MSP_ISA_430},
- {"msp430g2333", MSP_ISA_430},
- {"msp430g2352", MSP_ISA_430},
- {"msp430g2353", MSP_ISA_430},
- {"msp430g2402", MSP_ISA_430},
- {"msp430g2403", MSP_ISA_430},
- {"msp430g2412", MSP_ISA_430},
- {"msp430g2413", MSP_ISA_430},
- {"msp430g2432", MSP_ISA_430},
- {"msp430g2433", MSP_ISA_430},
- {"msp430g2444", MSP_ISA_430},
- {"msp430g2452", MSP_ISA_430},
- {"msp430g2453", MSP_ISA_430},
- {"msp430g2513", MSP_ISA_430},
- {"msp430g2533", MSP_ISA_430},
- {"msp430g2544", MSP_ISA_430},
- {"msp430g2553", MSP_ISA_430},
- {"msp430g2744", MSP_ISA_430},
- {"msp430g2755", MSP_ISA_430},
- {"msp430g2855", MSP_ISA_430},
- {"msp430g2955", MSP_ISA_430},
- {"msp430l092", MSP_ISA_430},
- {"msp430p112", MSP_ISA_430},
- {"msp430p313", MSP_ISA_430},
- {"msp430p315", MSP_ISA_430},
- {"msp430p315s", MSP_ISA_430},
- {"msp430p325", MSP_ISA_430},
- {"msp430p337", MSP_ISA_430},
- {"msp430tch5e", MSP_ISA_430},
-
- /* NB/ This section of the list should be kept in sync with the ones in:
- gcc/config/msp430/t-msp430
- gcc/config/msp430/msp430.c */
-
- {"msp430cg4616", MSP_ISA_430X},
- {"msp430cg4617", MSP_ISA_430X},
- {"msp430cg4618", MSP_ISA_430X},
- {"msp430cg4619", MSP_ISA_430X},
- {"msp430f2416", MSP_ISA_430X},
- {"msp430f2417", MSP_ISA_430X},
- {"msp430f2418", MSP_ISA_430X},
- {"msp430f2419", MSP_ISA_430X},
- {"msp430f2616", MSP_ISA_430X},
- {"msp430f2617", MSP_ISA_430X},
- {"msp430f2618", MSP_ISA_430X},
- {"msp430f2619", MSP_ISA_430X},
- {"msp430f47126", MSP_ISA_430X},
- {"msp430f47127", MSP_ISA_430X},
- {"msp430f47163", MSP_ISA_430X},
- {"msp430f47173", MSP_ISA_430X},
- {"msp430f47183", MSP_ISA_430X},
- {"msp430f47193", MSP_ISA_430X},
- {"msp430f47166", MSP_ISA_430X},
- {"msp430f47176", MSP_ISA_430X},
- {"msp430f47186", MSP_ISA_430X},
- {"msp430f47196", MSP_ISA_430X},
- {"msp430f47167", MSP_ISA_430X},
- {"msp430f47177", MSP_ISA_430X},
- {"msp430f47187", MSP_ISA_430X},
- {"msp430f47197", MSP_ISA_430X},
- {"msp430f46161", MSP_ISA_430X},
- {"msp430f46171", MSP_ISA_430X},
- {"msp430f46181", MSP_ISA_430X},
- {"msp430f46191", MSP_ISA_430X},
- {"msp430f4616", MSP_ISA_430X},
- {"msp430f4617", MSP_ISA_430X},
- {"msp430f4618", MSP_ISA_430X},
- {"msp430f4619", MSP_ISA_430X},
- {"msp430fg4616", MSP_ISA_430X},
- {"msp430fg4617", MSP_ISA_430X},
- {"msp430fg4618", MSP_ISA_430X},
- {"msp430fg4619", MSP_ISA_430X},
-
- {"msp430f5418", MSP_ISA_430Xv2},
- {"msp430f5419", MSP_ISA_430Xv2},
- {"msp430f5435", MSP_ISA_430Xv2},
- {"msp430f5436", MSP_ISA_430Xv2},
- {"msp430f5437", MSP_ISA_430Xv2},
- {"msp430f5438", MSP_ISA_430Xv2},
- {"msp430f5418a", MSP_ISA_430Xv2},
- {"msp430f5419a", MSP_ISA_430Xv2},
- {"msp430f5435a", MSP_ISA_430Xv2},
- {"msp430f5436a", MSP_ISA_430Xv2},
- {"msp430f5437a", MSP_ISA_430Xv2},
- {"msp430f5438a", MSP_ISA_430Xv2},
- {"msp430f5212", MSP_ISA_430Xv2},
- {"msp430f5213", MSP_ISA_430Xv2},
- {"msp430f5214", MSP_ISA_430Xv2},
- {"msp430f5217", MSP_ISA_430Xv2},
- {"msp430f5218", MSP_ISA_430Xv2},
- {"msp430f5219", MSP_ISA_430Xv2},
- {"msp430f5222", MSP_ISA_430Xv2},
- {"msp430f5223", MSP_ISA_430Xv2},
- {"msp430f5224", MSP_ISA_430Xv2},
- {"msp430f5227", MSP_ISA_430Xv2},
- {"msp430f5228", MSP_ISA_430Xv2},
- {"msp430f5229", MSP_ISA_430Xv2},
- {"msp430f5304", MSP_ISA_430Xv2},
- {"msp430f5308", MSP_ISA_430Xv2},
- {"msp430f5309", MSP_ISA_430Xv2},
- {"msp430f5310", MSP_ISA_430Xv2},
- {"msp430f5340", MSP_ISA_430Xv2},
- {"msp430f5341", MSP_ISA_430Xv2},
- {"msp430f5342", MSP_ISA_430Xv2},
- {"msp430f5324", MSP_ISA_430Xv2},
- {"msp430f5325", MSP_ISA_430Xv2},
- {"msp430f5326", MSP_ISA_430Xv2},
- {"msp430f5327", MSP_ISA_430Xv2},
- {"msp430f5328", MSP_ISA_430Xv2},
- {"msp430f5329", MSP_ISA_430Xv2},
- {"msp430f5500", MSP_ISA_430Xv2},
- {"msp430f5501", MSP_ISA_430Xv2},
- {"msp430f5502", MSP_ISA_430Xv2},
- {"msp430f5503", MSP_ISA_430Xv2},
- {"msp430f5504", MSP_ISA_430Xv2},
- {"msp430f5505", MSP_ISA_430Xv2},
- {"msp430f5506", MSP_ISA_430Xv2},
- {"msp430f5507", MSP_ISA_430Xv2},
- {"msp430f5508", MSP_ISA_430Xv2},
- {"msp430f5509", MSP_ISA_430Xv2},
- {"msp430f5510", MSP_ISA_430Xv2},
- {"msp430f5513", MSP_ISA_430Xv2},
- {"msp430f5514", MSP_ISA_430Xv2},
- {"msp430f5515", MSP_ISA_430Xv2},
- {"msp430f5517", MSP_ISA_430Xv2},
- {"msp430f5519", MSP_ISA_430Xv2},
- {"msp430f5521", MSP_ISA_430Xv2},
- {"msp430f5522", MSP_ISA_430Xv2},
- {"msp430f5524", MSP_ISA_430Xv2},
- {"msp430f5525", MSP_ISA_430Xv2},
- {"msp430f5526", MSP_ISA_430Xv2},
- {"msp430f5527", MSP_ISA_430Xv2},
- {"msp430f5528", MSP_ISA_430Xv2},
- {"msp430f5529", MSP_ISA_430Xv2},
- {"cc430f5133", MSP_ISA_430Xv2},
- {"cc430f5135", MSP_ISA_430Xv2},
- {"cc430f5137", MSP_ISA_430Xv2},
- {"cc430f6125", MSP_ISA_430Xv2},
- {"cc430f6126", MSP_ISA_430Xv2},
- {"cc430f6127", MSP_ISA_430Xv2},
- {"cc430f6135", MSP_ISA_430Xv2},
- {"cc430f6137", MSP_ISA_430Xv2},
- {"cc430f5123", MSP_ISA_430Xv2},
- {"cc430f5125", MSP_ISA_430Xv2},
- {"cc430f5143", MSP_ISA_430Xv2},
- {"cc430f5145", MSP_ISA_430Xv2},
- {"cc430f5147", MSP_ISA_430Xv2},
- {"cc430f6143", MSP_ISA_430Xv2},
- {"cc430f6145", MSP_ISA_430Xv2},
- {"cc430f6147", MSP_ISA_430Xv2},
- {"msp430f5333", MSP_ISA_430Xv2},
- {"msp430f5335", MSP_ISA_430Xv2},
- {"msp430f5336", MSP_ISA_430Xv2},
- {"msp430f5338", MSP_ISA_430Xv2},
- {"msp430f5630", MSP_ISA_430Xv2},
- {"msp430f5631", MSP_ISA_430Xv2},
- {"msp430f5632", MSP_ISA_430Xv2},
- {"msp430f5633", MSP_ISA_430Xv2},
- {"msp430f5634", MSP_ISA_430Xv2},
- {"msp430f5635", MSP_ISA_430Xv2},
- {"msp430f5636", MSP_ISA_430Xv2},
- {"msp430f5637", MSP_ISA_430Xv2},
- {"msp430f5638", MSP_ISA_430Xv2},
- {"msp430f6433", MSP_ISA_430Xv2},
- {"msp430f6435", MSP_ISA_430Xv2},
- {"msp430f6436", MSP_ISA_430Xv2},
- {"msp430f6438", MSP_ISA_430Xv2},
- {"msp430f6630", MSP_ISA_430Xv2},
- {"msp430f6631", MSP_ISA_430Xv2},
- {"msp430f6632", MSP_ISA_430Xv2},
- {"msp430f6633", MSP_ISA_430Xv2},
- {"msp430f6634", MSP_ISA_430Xv2},
- {"msp430f6635", MSP_ISA_430Xv2},
- {"msp430f6636", MSP_ISA_430Xv2},
- {"msp430f6637", MSP_ISA_430Xv2},
- {"msp430f6638", MSP_ISA_430Xv2},
- {"msp430f5358", MSP_ISA_430Xv2},
- {"msp430f5359", MSP_ISA_430Xv2},
- {"msp430f5658", MSP_ISA_430Xv2},
- {"msp430f5659", MSP_ISA_430Xv2},
- {"msp430f6458", MSP_ISA_430Xv2},
- {"msp430f6459", MSP_ISA_430Xv2},
- {"msp430f6658", MSP_ISA_430Xv2},
- {"msp430f6659", MSP_ISA_430Xv2},
- {"msp430f5131", MSP_ISA_430Xv2},
- {"msp430f5151", MSP_ISA_430Xv2},
- {"msp430f5171", MSP_ISA_430Xv2},
- {"msp430f5132", MSP_ISA_430Xv2},
- {"msp430f5152", MSP_ISA_430Xv2},
- {"msp430f5172", MSP_ISA_430Xv2},
- {"msp430f6720", MSP_ISA_430Xv2},
- {"msp430f6721", MSP_ISA_430Xv2},
- {"msp430f6723", MSP_ISA_430Xv2},
- {"msp430f6724", MSP_ISA_430Xv2},
- {"msp430f6725", MSP_ISA_430Xv2},
- {"msp430f6726", MSP_ISA_430Xv2},
- {"msp430f6730", MSP_ISA_430Xv2},
- {"msp430f6731", MSP_ISA_430Xv2},
- {"msp430f6733", MSP_ISA_430Xv2},
- {"msp430f6734", MSP_ISA_430Xv2},
- {"msp430f6735", MSP_ISA_430Xv2},
- {"msp430f6736", MSP_ISA_430Xv2},
- {"msp430f67451", MSP_ISA_430Xv2},
- {"msp430f67651", MSP_ISA_430Xv2},
- {"msp430f67751", MSP_ISA_430Xv2},
- {"msp430f67461", MSP_ISA_430Xv2},
- {"msp430f67661", MSP_ISA_430Xv2},
- {"msp430f67761", MSP_ISA_430Xv2},
- {"msp430f67471", MSP_ISA_430Xv2},
- {"msp430f67671", MSP_ISA_430Xv2},
- {"msp430f67771", MSP_ISA_430Xv2},
- {"msp430f67481", MSP_ISA_430Xv2},
- {"msp430f67681", MSP_ISA_430Xv2},
- {"msp430f67781", MSP_ISA_430Xv2},
- {"msp430f67491", MSP_ISA_430Xv2},
- {"msp430f67691", MSP_ISA_430Xv2},
- {"msp430f67791", MSP_ISA_430Xv2},
- {"msp430f6745", MSP_ISA_430Xv2},
- {"msp430f6765", MSP_ISA_430Xv2},
- {"msp430f6775", MSP_ISA_430Xv2},
- {"msp430f6746", MSP_ISA_430Xv2},
- {"msp430f6766", MSP_ISA_430Xv2},
- {"msp430f6776", MSP_ISA_430Xv2},
- {"msp430f6747", MSP_ISA_430Xv2},
- {"msp430f6767", MSP_ISA_430Xv2},
- {"msp430f6777", MSP_ISA_430Xv2},
- {"msp430f6748", MSP_ISA_430Xv2},
- {"msp430f6768", MSP_ISA_430Xv2},
- {"msp430f6778", MSP_ISA_430Xv2},
- {"msp430f6749", MSP_ISA_430Xv2},
- {"msp430f6769", MSP_ISA_430Xv2},
- {"msp430f6779", MSP_ISA_430Xv2},
- {"msp430fr5720", MSP_ISA_430Xv2},
- {"msp430fr5721", MSP_ISA_430Xv2},
- {"msp430fr5722", MSP_ISA_430Xv2},
- {"msp430fr5723", MSP_ISA_430Xv2},
- {"msp430fr5724", MSP_ISA_430Xv2},
- {"msp430fr5725", MSP_ISA_430Xv2},
- {"msp430fr5726", MSP_ISA_430Xv2},
- {"msp430fr5727", MSP_ISA_430Xv2},
- {"msp430fr5728", MSP_ISA_430Xv2},
- {"msp430fr5729", MSP_ISA_430Xv2},
- {"msp430fr5730", MSP_ISA_430Xv2},
- {"msp430fr5731", MSP_ISA_430Xv2},
- {"msp430fr5732", MSP_ISA_430Xv2},
- {"msp430fr5733", MSP_ISA_430Xv2},
- {"msp430fr5734", MSP_ISA_430Xv2},
- {"msp430fr5735", MSP_ISA_430Xv2},
- {"msp430fr5736", MSP_ISA_430Xv2},
- {"msp430fr5737", MSP_ISA_430Xv2},
- {"msp430fr5738", MSP_ISA_430Xv2},
- {"msp430fr5739", MSP_ISA_430Xv2},
- {"msp430bt5190", MSP_ISA_430Xv2},
- {"msp430fr5949", MSP_ISA_430Xv2},
- {"msp430fr5969", MSP_ISA_430Xv2},
- {"msp430sl5438a", MSP_ISA_430Xv2},
-
- /* Generic names. */
- {"msp430", MSP_ISA_430},
- {"msp430X", MSP_ISA_430X},
- {"msp430Xv2", MSP_ISA_430Xv2},
-
- {NULL, 0}
-};
-
-static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
-static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
-static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
-
-static struct mcu_type_s * msp430_mcu = & default_mcu;
+static enum msp_isa selected_isa = MSP_ISA_430Xv2;
static inline bfd_boolean
target_is_430x (void)
{
- return msp430_mcu->isa >= MSP_ISA_430X;
+ return selected_isa >= MSP_ISA_430X;
}
static inline bfd_boolean
target_is_430xv2 (void)
{
- return msp430_mcu->isa == MSP_ISA_430Xv2;
+ return selected_isa == MSP_ISA_430Xv2;
}
-/* Generate a 16-bit relocation.
- For the 430X we generate a relocation without linkwer range checking
- if the value is being used in an extended (ie 20-bit) instruction.
+/* Generate an absolute 16-bit relocation.
+ For the 430X we generate a relocation without linker range checking
+ if the value is being used in an extended (ie 20-bit) instruction,
+ otherwise if have a shifted expression we use a HI reloc.
For the 430 we generate a relocation without assembler range checking
- if we are handling an immediate value or a byte-width instruction. */
+ if we are handling an immediate value or a byte-width instruction. */
+
#undef CHECK_RELOC_MSP430
-#define CHECK_RELOC_MSP430 \
- (target_is_430x () \
- ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
- : ((imm_op || byte_op) \
+#define CHECK_RELOC_MSP430(OP) \
+ (target_is_430x () \
+ ? (extended_op \
+ ? BFD_RELOC_16 \
+ : ((OP).vshift == 1) \
+ ? BFD_RELOC_MSP430_ABS_HI16 \
+ : BFD_RELOC_MSP430X_ABS16) \
+ : ((imm_op || byte_op) \
? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
/* Generate a 16-bit pc-relative relocation.
@@ -1125,7 +671,11 @@ extract_word (char * from, char * to, int limit)
#define OPTION_LARGE 'l'
static bfd_boolean large_model = FALSE;
#define OPTION_NO_INTR_NOPS 'N'
-static bfd_boolean gen_interrupt_nops = TRUE;
+#define OPTION_INTR_NOPS 'n'
+static bfd_boolean gen_interrupt_nops = FALSE;
+#define OPTION_WARN_INTR_NOPS 'y'
+#define OPTION_NO_WARN_INTR_NOPS 'Y'
+static bfd_boolean warn_interrupt_nops = TRUE;
#define OPTION_MCPU 'c'
#define OPTION_MOVE_DATA 'd'
static bfd_boolean move_data = FALSE;
@@ -1142,63 +692,108 @@ msp430_set_arch (int option)
target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
}
-static void
-show_mcu_list (FILE * stream)
+/* This is the full list of MCU names that are known to only
+ support the 430 ISA. */
+static const char * msp430_mcu_names [] =
{
- int i;
-
- fprintf (stream, _("Known MCU names:\n"));
-
- for (i = 0; mcu_types[i].name; i++)
- {
- fprintf (stream, "%14.14s", mcu_types[i].name);
- if ((i % 6) == 5)
- fprintf (stream, "\n");
- }
-
- fprintf (stream, "\n");
-}
+"msp430afe221", "msp430afe222", "msp430afe223", "msp430afe231",
+"msp430afe232", "msp430afe233", "msp430afe251", "msp430afe252",
+"msp430afe253", "msp430c091", "msp430c092", "msp430c111",
+"msp430c1111", "msp430c112", "msp430c1121", "msp430c1331",
+"msp430c1351", "msp430c311s", "msp430c312", "msp430c313",
+"msp430c314", "msp430c315", "msp430c323", "msp430c325",
+"msp430c336", "msp430c337", "msp430c412", "msp430c413",
+"msp430e112", "msp430e313", "msp430e315", "msp430e325",
+"msp430e337", "msp430f110", "msp430f1101", "msp430f1101a",
+"msp430f1111", "msp430f1111a", "msp430f112", "msp430f1121",
+"msp430f1121a", "msp430f1122", "msp430f1132", "msp430f122",
+"msp430f1222", "msp430f123", "msp430f1232", "msp430f133",
+"msp430f135", "msp430f147", "msp430f1471", "msp430f148",
+"msp430f1481", "msp430f149", "msp430f1491", "msp430f155",
+"msp430f156", "msp430f157", "msp430f1610", "msp430f1611",
+"msp430f1612", "msp430f167", "msp430f168", "msp430f169",
+"msp430f2001", "msp430f2002", "msp430f2003", "msp430f2011",
+"msp430f2012", "msp430f2013", "msp430f2101", "msp430f2111",
+"msp430f2112", "msp430f2121", "msp430f2122", "msp430f2131",
+"msp430f2132", "msp430f2232", "msp430f2234", "msp430f2252",
+"msp430f2254", "msp430f2272", "msp430f2274", "msp430f233",
+"msp430f2330", "msp430f235", "msp430f2350", "msp430f2370",
+"msp430f2410", "msp430f247", "msp430f2471", "msp430f248",
+"msp430f2481", "msp430f249", "msp430f2491", "msp430f412",
+"msp430f413", "msp430f4132", "msp430f415", "msp430f4152",
+"msp430f417", "msp430f423", "msp430f423a", "msp430f425",
+"msp430f4250", "msp430f425a", "msp430f4260", "msp430f427",
+"msp430f4270", "msp430f427a", "msp430f435", "msp430f4351",
+"msp430f436", "msp430f4361", "msp430f437", "msp430f4371",
+"msp430f438", "msp430f439", "msp430f447", "msp430f448",
+"msp430f4481", "msp430f449", "msp430f4491", "msp430f477",
+"msp430f478", "msp430f4783", "msp430f4784", "msp430f479",
+"msp430f4793", "msp430f4794", "msp430fe423", "msp430fe4232",
+"msp430fe423a", "msp430fe4242", "msp430fe425", "msp430fe4252",
+"msp430fe425a", "msp430fe427", "msp430fe4272", "msp430fe427a",
+"msp430fg4250", "msp430fg4260", "msp430fg4270", "msp430fg437",
+"msp430fg438", "msp430fg439", "msp430fg477", "msp430fg478",
+"msp430fg479", "msp430fw423", "msp430fw425", "msp430fw427",
+"msp430fw428", "msp430fw429", "msp430g2001", "msp430g2101",
+"msp430g2102", "msp430g2111", "msp430g2112", "msp430g2113",
+"msp430g2121", "msp430g2131", "msp430g2132", "msp430g2152",
+"msp430g2153", "msp430g2201", "msp430g2202", "msp430g2203",
+"msp430g2210", "msp430g2211", "msp430g2212", "msp430g2213",
+"msp430g2221", "msp430g2230", "msp430g2231", "msp430g2232",
+"msp430g2233", "msp430g2252", "msp430g2253", "msp430g2302",
+"msp430g2303", "msp430g2312", "msp430g2313", "msp430g2332",
+"msp430g2333", "msp430g2352", "msp430g2353", "msp430g2402",
+"msp430g2403", "msp430g2412", "msp430g2413", "msp430g2432",
+"msp430g2433", "msp430g2444", "msp430g2452", "msp430g2453",
+"msp430g2513", "msp430g2533", "msp430g2544", "msp430g2553",
+"msp430g2744", "msp430g2755", "msp430g2855", "msp430g2955",
+"msp430i2020", "msp430i2021", "msp430i2030", "msp430i2031",
+"msp430i2040", "msp430i2041", "msp430l092", "msp430p112",
+"msp430p313", "msp430p315", "msp430p315s", "msp430p325",
+"msp430p337", "msp430tch5e"
+};
int
md_parse_option (int c, char * arg)
{
- int i;
-
switch (c)
{
case OPTION_MMCU:
if (arg == NULL)
as_fatal (_("MCU option requires a name\n"));
- for (i = 0; mcu_types[i].name; ++i)
- if (strcasecmp (mcu_types[i].name, arg) == 0)
- break;
-
- if (mcu_types[i].name == NULL)
+ if (strcasecmp ("msp430", arg) == 0)
+ selected_isa = MSP_ISA_430;
+ else if (strcasecmp ("msp430xv2", arg) == 0)
+ selected_isa = MSP_ISA_430Xv2;
+ else if (strcasecmp ("msp430x", arg) == 0)
+ selected_isa = MSP_ISA_430X;
+ else
{
- show_mcu_list (stderr);
- as_fatal (_("unknown MCU: %s\n"), arg);
- }
+ int i;
- /* Allow switching to the same or a lesser architecture. */
- if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
- msp430_mcu = mcu_types + i;
- else
- as_fatal (_("redefinition of mcu type '%s' to '%s'"),
- msp430_mcu->name, mcu_types[i].name);
+ for (i = sizeof msp430_mcu_names / sizeof msp430_mcu_names[0]; i--;)
+ if (strcasecmp (msp430_mcu_names[i], arg) == 0)
+ {
+ selected_isa = MSP_ISA_430;
+ break;
+ }
+ }
+ /* It is not an error if we do not match the MCU name. */
return 1;
case OPTION_MCPU:
- if (strcmp (arg, "430") == 0)
- msp430_mcu = & default_mcu;
- else if (strcmp (arg, "430x") == 0
- || strcmp (arg, "430X") == 0)
- msp430_mcu = & msp430x_mcu;
- else if (strcasecmp (arg, "430xv2") == 0)
- msp430_mcu = & msp430xv2_mcu;
+ if (strcmp (arg, "430") == 0
+ || strcasecmp (arg, "msp430") == 0)
+ selected_isa = MSP_ISA_430;
+ else if (strcasecmp (arg, "430x") == 0
+ || strcasecmp (arg, "msp430x") == 0)
+ selected_isa = MSP_ISA_430X;
+ else if (strcasecmp (arg, "430xv2") == 0
+ || strcasecmp (arg, "msp430xv2") == 0)
+ selected_isa = MSP_ISA_430Xv2;
else
as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
-
return 1;
case OPTION_RELAX:
@@ -1216,6 +811,16 @@ md_parse_option (int c, char * arg)
case OPTION_NO_INTR_NOPS:
gen_interrupt_nops = FALSE;
return 1;
+ case OPTION_INTR_NOPS:
+ gen_interrupt_nops = TRUE;
+ return 1;
+
+ case OPTION_WARN_INTR_NOPS:
+ warn_interrupt_nops = TRUE;
+ return 1;
+ case OPTION_NO_WARN_INTR_NOPS:
+ warn_interrupt_nops = FALSE;
+ return 1;
case OPTION_MOVE_DATA:
move_data = TRUE;
@@ -1225,6 +830,18 @@ md_parse_option (int c, char * arg)
return 0;
}
+/* The intention here is to have the mere presence of these sections
+ cause the object to have a reference to a well-known symbol. This
+ reference pulls in the bits of the runtime (crt0) that initialize
+ these sections. Thus, for example, the startup code to call
+ memset() to initialize .bss will only be linked in when there is a
+ non-empty .bss section. Otherwise, the call would exist but have a
+ zero length parameter, which is a waste of memory and cycles.
+
+ The code which initializes these sections should have a global
+ label for these symbols, and should be marked with KEEP() in the
+ linker script.
+ */
static void
msp430_section (int arg)
{
@@ -1235,15 +852,57 @@ msp430_section (int arg)
|| strncmp (name, ".gnu.linkonce.b.", 16) == 0)
(void) symbol_find_or_make ("__crt0_init_bss");
- if (move_data
- && (strncmp (name, ".data", 5) == 0
- || strncmp (name, ".gnu.linkonce.d.", 16) == 0))
+ if (strncmp (name, ".data", 5) == 0
+ || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
(void) symbol_find_or_make ("__crt0_movedata");
input_line_pointer = saved_ilp;
obj_elf_section (arg);
}
+void
+msp430_frob_section (asection *sec)
+{
+ const char *name = sec->name;
+
+ if (sec->size == 0)
+ return;
+
+ if (strncmp (name, ".bss", 4) == 0
+ || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
+ (void) symbol_find_or_make ("__crt0_init_bss");
+
+ if (strncmp (name, ".data", 5) == 0
+ || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
+ (void) symbol_find_or_make ("__crt0_movedata");
+}
+
+static void
+msp430_lcomm (int ignore ATTRIBUTE_UNUSED)
+{
+ symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
+
+ if (symbolP)
+ symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+ (void) symbol_find_or_make ("__crt0_init_bss");
+}
+
+static void
+msp430_comm (int needs_align)
+{
+ s_comm_internal (needs_align, elf_common_parse);
+ (void) symbol_find_or_make ("__crt0_init_bss");
+}
+
+static void
+msp430_refsym (int arg ATTRIBUTE_UNUSED)
+{
+ char sym_name[1024];
+ input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
+
+ (void) symbol_find_or_make (sym_name);
+}
+
const pseudo_typeS md_pseudo_table[] =
{
{"arch", msp430_set_arch, OPTION_MMCU},
@@ -1254,10 +913,13 @@ const pseudo_typeS md_pseudo_table[] =
{"sect", msp430_section, 0},
{"sect.s", msp430_section, 0},
{"pushsection", msp430_section, 1},
+ {"refsym", msp430_refsym, 0},
+ {"comm", msp430_comm, 0},
+ {"lcomm", msp430_lcomm, 0},
{NULL, NULL, 0}
};
-const char *md_shortopts = "mm:,mP,mQ,ml,mN";
+const char *md_shortopts = "mm:,mP,mQ,ml,mN,mn,my,mY";
struct option md_longopts[] =
{
@@ -1267,6 +929,9 @@ struct option md_longopts[] =
{"mQ", no_argument, NULL, OPTION_RELAX},
{"ml", no_argument, NULL, OPTION_LARGE},
{"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
+ {"mn", no_argument, NULL, OPTION_INTR_NOPS},
+ {"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
+ {"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
{"md", no_argument, NULL, OPTION_MOVE_DATA},
{NULL, no_argument, NULL, 0}
};
@@ -1286,11 +951,15 @@ md_show_usage (FILE * stream)
fprintf (stream,
_(" -ml - enable large code model\n"));
fprintf (stream,
- _(" -mN - disable generation of NOP after changing interrupts\n"));
+ _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
+ fprintf (stream,
+ _(" -mn - insert a NOP after changing interrupts\n"));
+ fprintf (stream,
+ _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
+ fprintf (stream,
+ _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
fprintf (stream,
_(" -md - Force copying of data from ROM to RAM at startup\n"));
-
- show_mcu_list (stream);
}
symbolS *
@@ -1375,7 +1044,7 @@ static int
msp430_srcoperand (struct msp430_operand_s * op,
char * l,
int bin,
- int * imm_op,
+ bfd_boolean * imm_op,
bfd_boolean allow_20bit_values,
bfd_boolean constants_allowed)
{
@@ -1395,7 +1064,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
hhi(x) - x = (x >> 48) & 0xffff
The value _MUST_ be constant expression: #hlo(1231231231). */
- *imm_op = 1;
+ *imm_op = TRUE;
if (strncasecmp (h, "#llo(", 5) == 0)
{
@@ -1430,9 +1099,10 @@ msp430_srcoperand (struct msp430_operand_s * op,
op->reg = 0; /* Reg PC. */
op->am = 3;
- op->ol = 1; /* Immediate will follow an instruction. */
+ op->ol = 1; /* Immediate will follow an instruction. */
__tl = h + 1 + rval;
op->mode = OP_EXP;
+ op->vshift = vshift;
parse_exp (__tl, &(op->exp));
if (op->exp.X_op == O_constant)
@@ -1448,6 +1118,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
{
x = (x >> 16) & 0xffff;
op->exp.X_add_number = x;
+ op->vshift = 0;
}
else if (vshift > 1)
{
@@ -1456,11 +1127,12 @@ msp430_srcoperand (struct msp430_operand_s * op,
else
op->exp.X_add_number = 0; /* Nothing left. */
x = op->exp.X_add_number;
+ op->vshift = 0;
}
if (allow_20bit_values)
{
- if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
+ if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288)
{
as_bad (_("value 0x%x out of extended range."), x);
return 1;
@@ -1545,16 +1217,20 @@ msp430_srcoperand (struct msp430_operand_s * op,
}
else if (op->exp.X_op == O_symbol)
{
+ if (vshift > 1)
+ as_bad (_("error: unsupported #foo() directive used on symbol"));
op->mode = OP_EXP;
}
else if (op->exp.X_op == O_big)
{
short x;
+
if (vshift != -1)
{
op->exp.X_op = O_constant;
op->exp.X_add_number = 0xffff & generic_bignum[vshift];
x = op->exp.X_add_number;
+ op->vshift = 0;
}
else
{
@@ -1628,6 +1304,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
__tl = h + 1;
parse_exp (__tl, &(op->exp));
op->mode = OP_EXP;
+ op->vshift = 0;
if (op->exp.X_op == O_constant)
{
int x = op->exp.X_add_number;
@@ -1691,6 +1368,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
as_bad (_("cannot use indirect addressing with the PC"));
return 1;
}
+
return 0;
}
@@ -1701,7 +1379,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
char *m = strrchr (l, ')');
char *t;
- *imm_op = 1;
+ *imm_op = TRUE;
if (!h)
break;
@@ -1734,6 +1412,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
__tl = l;
*h = 0;
op->mode = OP_EXP;
+ op->vshift = 0;
parse_exp (__tl, &(op->exp));
if (op->exp.X_op == O_constant)
{
@@ -1795,6 +1474,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
/* An expression starting with a minus sign is a constant, not an address. */
op->am = (*l == '-' ? 3 : 1);
op->ol = 1;
+ op->vshift = 0;
__tl = l;
parse_exp (__tl, &(op->exp));
return 0;
@@ -1829,6 +1509,7 @@ msp430_dstoperand (struct msp430_operand_s * op,
op->mode = OP_EXP;
op->am = 1;
op->ol = 1;
+ op->vshift = 0;
parse_exp (__tl, &(op->exp));
if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
@@ -1849,7 +1530,6 @@ msp430_dstoperand (struct msp430_operand_s * op,
return 0;
}
-
/* Attempt to encode a MOVA instruction with the given operands.
Returns the length of the encoded instruction if successful
or 0 upon failure. If the encoding fails, an error message
@@ -2109,6 +1789,8 @@ try_encode_mova (bfd_boolean imm_op,
return 0;
}
+static bfd_boolean check_for_nop = FALSE;
+
#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
/* Parse instruction operands.
@@ -2125,7 +1807,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
struct msp430_operand_s op1, op2;
int res = 0;
static short ZEROS = 0;
- int byte_op, imm_op;
+ bfd_boolean byte_op, imm_op;
int op_length = 0;
int fmt;
int extended = 0x1800;
@@ -2134,6 +1816,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
const char * error_message;
static signed int repeat_count = 0;
bfd_boolean fix_emitted;
+ bfd_boolean nop_check_needed = FALSE;
/* Opcode is the one from opcodes table
line contains something like
@@ -2141,7 +1824,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
or
.b @r2+, 5(R1). */
- byte_op = 0;
+ byte_op = FALSE;
addr_op = FALSE;
if (*line == '.')
{
@@ -2153,7 +1836,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
case 'b':
/* Byte operation. */
bin |= BYTE_OPERATION;
- byte_op = 1;
+ byte_op = TRUE;
check = TRUE;
break;
@@ -2235,7 +1918,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
memset (&op1, 0, sizeof (op1));
memset (&op2, 0, sizeof (op2));
- imm_op = 0;
+ imm_op = FALSE;
if ((fmt = opcode->fmt) < 0)
{
@@ -2266,12 +1949,40 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
repeat_count = 0;
}
+ if (check_for_nop && is_opcode ("nop"))
+ check_for_nop = FALSE;
+
switch (fmt)
{
case 0: /* Emulated. */
switch (opcode->insn_opnumb)
{
case 0:
+ if (is_opcode ("eint") || is_opcode ("dint"))
+ {
+ if (check_for_nop)
+ {
+ if (warn_interrupt_nops)
+ {
+ if (gen_interrupt_nops)
+ as_warn (_("NOP inserted between two instructions that change interrupt state"));
+ else
+ as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
+ }
+
+ if (gen_interrupt_nops)
+ {
+ /* Emit a NOP between interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ }
+
+ nop_check_needed = TRUE;
+ }
+
/* Set/clear bits instructions. */
if (extended_op)
{
@@ -2280,26 +1991,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
/* Emit the extension word. */
insn_length += 2;
- frag = frag_more (insn_length);
+ frag = frag_more (2);
bfd_putl16 (extended, frag);
}
insn_length += 2;
- frag = frag_more (insn_length);
+ frag = frag_more (2);
bfd_putl16 ((bfd_vma) bin, frag);
-
- if (gen_interrupt_nops
- && target_is_430xv2 ()
- && (is_opcode ("eint") || is_opcode ("dint")))
- {
- /* Emit a NOP following interrupt enable/disable.
- See 1.3.4.1 of the MSP430x5xx User Guide. */
- insn_length += 2;
- frag = frag_more (2);
- as_warn (_("a NOP instruction has been inserted after %s"),
- opcode->name);
- bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
- }
dwarf2_emit_insn (insn_length);
break;
@@ -2310,9 +2008,37 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (res)
break;
+ bin |= (op1.reg | (op1.am << 7));
+
+ if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/)
+ {
+ if (check_for_nop)
+ {
+ if (warn_interrupt_nops)
+ {
+ if (gen_interrupt_nops)
+ as_warn (_("NOP inserted between two instructions that change interrupt state"));
+ else
+ as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
+ }
+
+ if (gen_interrupt_nops)
+ {
+ /* Emit a NOP between interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ }
+
+ nop_check_needed = TRUE;
+ }
+
/* Compute the entire instruction length, in bytes. */
- insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
- frag = frag_more (insn_length);
+ op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
+ insn_length += op_length;
+ frag = frag_more (op_length);
where = frag - frag_now->fr_literal;
if (extended_op)
@@ -2345,7 +2071,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
where += 2;
}
- bin |= (op1.reg | (op1.am << 7));
bfd_putl16 ((bfd_vma) bin, frag);
frag += 2;
where += 2;
@@ -2364,7 +2089,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
if (op1.reg)
fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
else
fix_new_exp (frag_now, where, 2,
&(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -2372,20 +2097,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
}
- if (gen_interrupt_nops
- && target_is_430xv2 ()
- && is_opcode ("clr")
- && bin == 0x4302 /* CLR R2*/)
- {
- /* Emit a NOP following interrupt enable/disable.
- See 1.3.4.1 of the MSP430x5xx User Guide. */
- insn_length += 2;
- frag = frag_more (2);
- bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
- as_warn (_("a NOP instruction has been inserted after %s"),
- opcode->name);
- }
-
dwarf2_emit_insn (insn_length);
break;
@@ -2413,7 +2124,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
|| is_opcode ("rlc")))
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
if (extended_op)
@@ -2480,7 +2191,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
else
fix_new_exp (frag_now, where, 2,
&(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -2504,7 +2215,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
if (op2.reg) /* Not PC relative. */
fix_new_exp (frag_now, where, 2,
- &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
else
fix_new_exp (frag_now, where, 2,
&(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -2520,7 +2231,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended_op)
{
as_bad ("Internal error: state 0/3 not coded for extended instructions");
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2528,8 +2239,8 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (res)
break;
- byte_op = 0;
- imm_op = 0;
+ byte_op = FALSE;
+ imm_op = FALSE;
bin |= ((op1.reg << 8) | (op1.am << 4));
op_length = 2 + 2 * op1.ol;
frag = frag_more (op_length);
@@ -2550,7 +2261,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (op1.reg || (op1.reg == 0 && op1.am == 3))
fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
else
fix_new_exp (frag_now, where, 2,
&(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -2565,14 +2276,14 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
fix_emitted = FALSE;
line = extract_operand (line, l1, sizeof (l1));
- imm_op = 0;
+ imm_op = FALSE;
res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
extended_op, FALSE);
if (res)
break;
- byte_op = 0;
+ byte_op = FALSE;
op_length = 2 + 2 * op1.ol;
frag = frag_more (op_length);
@@ -2624,7 +2335,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (op1.ol != 1)
{
as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
- return 0;
+ break;
}
bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
@@ -2649,21 +2360,21 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (*l1 != '#')
{
as_bad (_("expected #n as first argument of %s"), opcode->name);
- return 0;
+ break;
}
parse_exp (l1 + 1, &(op1.exp));
if (op1.exp.X_op != O_constant)
{
as_bad (_("expected constant expression for first argument of %s"),
opcode->name);
- return 0;
+ break;
}
if ((reg = check_reg (l2)) == -1)
{
as_bad (_("expected register as second argument of %s"),
opcode->name);
- return 0;
+ break;
}
op_length = 2;
@@ -2681,17 +2392,17 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (reg - n + 1 < 0)
{
as_bad (_("Too many registers popped"));
- return 0;
+ break;
}
- /* CPU21 parts cannot use POPM to restore the SR register. */
+ /* CPU21 errata: cannot use POPM to restore the SR register. */
if (target_is_430xv2 ()
&& (reg - n + 1 < 3)
&& reg >= 2
&& is_opcode ("popm"))
{
as_bad (_("Cannot use POPM to restore the SR register"));
- return 0;
+ break;
}
bin |= (reg - n + 1);
@@ -2711,7 +2422,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended & 0xff)
{
as_bad (_("repeat count cannot be used with %s"), opcode->name);
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2720,34 +2431,34 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (*l1 != '#')
{
as_bad (_("expected #n as first argument of %s"), opcode->name);
- return 0;
+ break;
}
parse_exp (l1 + 1, &(op1.exp));
if (op1.exp.X_op != O_constant)
{
as_bad (_("expected constant expression for first argument of %s"),
opcode->name);
- return 0;
+ break;
}
n = op1.exp.X_add_number;
if (n > 4 || n < 1)
{
as_bad (_("expected first argument of %s to be in the range 1-4"),
opcode->name);
- return 0;
+ break;
}
if ((reg = check_reg (l2)) == -1)
{
as_bad (_("expected register as second argument of %s"),
opcode->name);
- return 0;
+ break;
}
if (target_is_430xv2 () && reg == 0)
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
op_length = 2;
@@ -2773,7 +2484,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended & 0xff)
{
as_bad (_("repeat count cannot be used with %s"), opcode->name);
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2781,13 +2492,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected register as argument of %s"),
opcode->name);
- return 0;
+ break;
}
if (target_is_430xv2 () && reg == 0)
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
if (byte_op)
@@ -2832,7 +2543,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended & 0xff)
{
as_bad (_("repeat count cannot be used with %s"), opcode->name);
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2851,7 +2562,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected value of first argument of %s to fit into 20-bits"),
opcode->name);
- return 0;
+ break;
}
bin |= ((n >> 16) & 0xf) << 8;
@@ -2870,7 +2581,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected register name or constant as first argument of %s"),
opcode->name);
- return 0;
+ break;
}
bin |= (n << 8) | (1 << 6);
@@ -2881,7 +2592,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected register as second argument of %s"),
opcode->name);
- return 0;
+ break;
}
frag = frag_more (op_length);
@@ -2899,7 +2610,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
case 9: /* MOVA, BRA, RETA. */
- imm_op = 0;
+ imm_op = FALSE;
bin = opcode->bin_opcode;
if (is_opcode ("reta"))
@@ -2944,7 +2655,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
& error_message)) == 0)
{
as_bad (error_message, opcode->name);
- return 0;
+ break;
}
dwarf2_emit_insn (op_length);
break;
@@ -2958,13 +2669,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (op1.exp.X_op != O_constant)
{
as_bad (_("expected constant value as argument to RPT"));
- return 0;
+ break;
}
if (op1.exp.X_add_number < 1
|| op1.exp.X_add_number > (1 << 4))
{
as_bad (_("expected constant in the range 2..16"));
- return 0;
+ break;
}
/* We silently accept and ignore a repeat count of 1. */
@@ -2985,7 +2696,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
else
{
as_bad (_("expected constant or register name as argument to RPT insn"));
- return 0;
+ break;
}
}
break;
@@ -3020,14 +2731,43 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
}
+ bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+
+ if ( (is_opcode ("bic") && bin == 0xc232)
+ || (is_opcode ("bis") && bin == 0xd232)
+ || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
+ {
+ if (check_for_nop)
+ {
+ if (warn_interrupt_nops)
+ {
+ if (gen_interrupt_nops)
+ as_warn (_("NOP inserted between two instructions that change interrupt state"));
+ else
+ as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
+ }
+
+ if (gen_interrupt_nops)
+ {
+ /* Emit a NOP between interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ }
+
+ nop_check_needed = TRUE;
+ }
+
/* Compute the entire length of the instruction in bytes. */
- insn_length =
- (extended_op ? 2 : 0) /* The extension word. */
+ op_length = (extended_op ? 2 : 0) /* The extension word. */
+ 2 /* The opcode */
+ (2 * op1.ol) /* The first operand. */
+ (2 * op2.ol); /* The second operand. */
- frag = frag_more (insn_length);
+ insn_length += op_length;
+ frag = frag_more (op_length);
where = frag - frag_now->fr_literal;
if (extended_op)
@@ -3077,7 +2817,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
frag += 2;
}
- bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
bfd_putl16 ((bfd_vma) bin, frag);
where += 2;
frag += 2;
@@ -3096,7 +2835,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
else
fix_new_exp (frag_now, where, 2,
&(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -3121,7 +2860,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
if (op2.reg) /* Not PC relative. */
fix_new_exp (frag_now, where, 2,
- &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
else
fix_new_exp (frag_now, where, 2,
&(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -3129,21 +2868,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
}
- if (gen_interrupt_nops
- && target_is_430xv2 ()
- && ( (is_opcode ("bic") && bin == 0xc232)
- || (is_opcode ("bis") && bin == 0xd232)
- || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
- {
- /* Emit a NOP following interrupt enable/disable.
- See 1.3.4.1 of the MSP430x5xx User Guide. */
- insn_length += 2;
- frag = frag_more (2);
- bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
- as_warn (_("a NOP instruction has been inserted after %s"),
- opcode->name);
- }
-
dwarf2_emit_insn (insn_length);
break;
@@ -3173,7 +2897,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
|| is_opcode ("rrc")))
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
@@ -3192,7 +2916,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("%s instruction does not accept a .b suffix"),
opcode->name);
- return 0;
+ break;
}
else if (! addr_op)
extended |= BYTE_OPERATION;
@@ -3244,7 +2968,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
else
fix_new_exp (frag_now, where, 2,
&(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
@@ -3438,6 +3162,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
input_line_pointer = line;
+ check_for_nop = nop_check_needed;
return 0;
}
@@ -3643,6 +3368,12 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
bfd_putl16 ((bfd_vma) value, where);
break;
+ case BFD_RELOC_MSP430_ABS_HI16:
+ value >>= 16;
+ value &= 0xffff; /* Get rid of extended sign. */
+ bfd_putl16 ((bfd_vma) value, where);
+ break;
+
case BFD_RELOC_32:
bfd_putl16 ((bfd_vma) value, where);
break;
@@ -4166,6 +3897,9 @@ msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
void
msp430_md_end (void)
{
+ if (check_for_nop == TRUE && warn_interrupt_nops)
+ as_warn ("assembly finished with the last instruction changing interrupt state - a NOP might be needed");
+
bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
target_is_430x () ? 2 : 1);
diff --git a/binutils-2.25/gas/config/tc-msp430.h b/binutils-2.25/gas/config/tc-msp430.h
index f805f666..72f6dd8a 100644
--- a/binutils-2.25/gas/config/tc-msp430.h
+++ b/binutils-2.25/gas/config/tc-msp430.h
@@ -1,5 +1,5 @@
/* This file is tc-msp430.h
- Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
@@ -120,6 +120,10 @@ extern long msp430_relax_frag (segT, fragS *, long);
msp430_force_relocation_local (FIX)
extern int msp430_force_relocation_local (struct fix *);
+/* We need to add reference symbols for .data/.bss. */
+#define tc_frob_section(sec) msp430_frob_section (sec)
+extern void msp430_frob_section (asection *);
+
extern int msp430_enable_relax;
extern int msp430_enable_polys;
diff --git a/binutils-2.25/gas/config/tc-mt.c b/binutils-2.25/gas/config/tc-mt.c
index 6e547827..d8322979 100644
--- a/binutils-2.25/gas/config/tc-mt.c
+++ b/binutils-2.25/gas/config/tc-mt.c
@@ -1,5 +1,5 @@
/* tc-mt.c -- Assembler for the Morpho Technologies mt .
- Copyright (C) 2005, 2006, 2007, 2010 Free Software Foundation.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-mt.h b/binutils-2.25/gas/config/tc-mt.h
index 27c0fa66..1d3a8275 100644
--- a/binutils-2.25/gas/config/tc-mt.h
+++ b/binutils-2.25/gas/config/tc-mt.h
@@ -1,5 +1,5 @@
/* tc-mt.h -- Header file for tc-mt.c.
- Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-nds32.c b/binutils-2.25/gas/config/tc-nds32.c
new file mode 100644
index 00000000..353a1657
--- /dev/null
+++ b/binutils-2.25/gas/config/tc-nds32.c
@@ -0,0 +1,6600 @@
+/* tc-nds32.c -- Assemble for the nds32
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "symcat.h"
+#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
+#include "opcodes/nds32-asm.h"
+#include "elf/nds32.h"
+#include "bfd/elf32-nds32.h"
+#include "hash.h"
+#include "sb.h"
+#include "macro.h"
+#include "struc-symbol.h"
+#include "opcode/nds32.h"
+
+#include <stdio.h>
+
+/* GAS definitions. */
+
+/* Characters which start a comment. */
+const char comment_chars[] = "!";
+/* Characters which start a comment when they appear at the start of a line. */
+const char line_comment_chars[] = "#!";
+/* Characters which separate lines (null and newline are by default). */
+const char line_separator_chars[] = ";";
+/* Characters which may be used as the exponent character
+ in a floating point number. */
+const char EXP_CHARS[] = "eE";
+/* Characters which may be used to indicate a floating point constant. */
+const char FLT_CHARS[] = "dDfF";
+
+static int enable_16bit = 1;
+/* Save for md_assemble to distinguish if this instruction is
+ expanded from the pseudo instruction. */
+static bfd_boolean pseudo_opcode = FALSE;
+static struct nds32_relocs_pattern *relocs_list = NULL;
+/* Save instruction relation to inserting relaxation relocation. */
+struct nds32_relocs_pattern
+{
+ segT seg;
+ fragS *frag;
+ frchainS *frchain;
+ symbolS *sym;
+ fixS* fixP;
+ struct nds32_opcode *opcode;
+ char *where;
+ struct nds32_relocs_pattern *next;
+};
+
+/* Suffix name and relocation. */
+struct suffix_name
+{
+ char *suffix;
+ short unsigned int reloc;
+ int pic;
+};
+static int vec_size = 0;
+/* If the assembly code is generated by compiler, it is supposed to have
+ ".flag verbatim" at beginning of the content. We have
+ 'nds32_flag' to parse it and set this field to be non-zero. */
+static int verbatim = 0;
+static struct hash_control *nds32_gprs_hash;
+static struct hash_control *nds32_hint_hash;
+#define TLS_REG "$r27"
+#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
+
+/* Generate relocation for relax or not, and the default is true. */
+static int enable_relax_relocs = 1;
+/* The value will be used in RELAX_ENTRY. */
+static int enable_relax_ex9 = 0;
+/* The value will be used in RELAX_ENTRY. */
+static int enable_relax_ifc = 0;
+/* Save option -O for perfomance. */
+static int optimize = 0;
+/* Save option -Os for code size. */
+static int optimize_for_space = 0;
+/* Flag to save label exist. */
+static int label_exist = 0;
+/* Flag to save state in omit_fp region. */
+static int in_omit_fp = 0;
+extern struct nds32_keyword keyword_gpr[];
+/* Tag there is relax relocation having to link. */
+static bfd_boolean relaxing = FALSE;
+
+static struct hash_control *nds32_relax_info_hash;
+static relax_info_t relax_table[] =
+{
+ {
+ "jal", /* opcode */
+ BR_RANGE_S16M, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {
+ {
+ INSN_JAL /* jal label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_JAL /* jal label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_JAL /* jal label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_JAL /* jal label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JRAL_TA
+ }, /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
+ {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 4, 12}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_HI20},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bltzal", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BLTZAL /* bltzal $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BLTZAL /* bltzal $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BLTZAL /* bltzal $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BGEZ, /* bgez $rt, $1 */
+ INSN_JAL /* jal label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BGEZ, /* bgez $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JRAL_TA /* jral $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bgezal", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BGEZAL /* bgezal $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BGEZAL /* bgezal $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BGEZAL /* bgezal $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BLTZ, /* bltz $rt, $1 */
+ INSN_JAL /* jal label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BLTZ, /* bltz $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JRAL_TA /* jral $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "j", /* opcode */
+ BR_RANGE_S16M, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {
+ {
+ (INSN_J8 << 16) /* j8 label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ }, /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
+ {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 4, 4, 12}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_HI20},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "j8", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {
+ {
+ (INSN_J8 << 16) /* j8 label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ }, /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
+ {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 4, 4, 12}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_HI20},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
+ {4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "beqz", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BEQZ /* beqz $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BEQZ /* beqz $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BEQZ /* beqz $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BNEZ, /* bnez $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BNEZ, /* bnez $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bgez", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BGEZ /* bgez $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BGEZ /* bgez $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BGEZ /* bgez $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BLTZ, /* bltz $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BLTZ, /* bltz $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bnez", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BNEZ /* bnez $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BNEZ /* bnez $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BNEZ /* bnez $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BEQZ, /* beqz $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BEQZ, /* beqz $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bgtz", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BGTZ /* bgtz $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BGTZ /* bgtz $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BGTZ /* bgtz $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BLEZ, /* blez $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BLEZ, /* blez $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "blez", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BLEZ /* blez $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BLEZ /* blez $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BLEZ /* blez $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BGTZ, /* bgtz $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BGTZ, /* bgtz $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bltz", /* opcode */
+ BR_RANGE_S64K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BLTZ /* bltz $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BLTZ /* bltz $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BLTZ /* bltz $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BGEZ, /* bgez $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BGEZ, /* bgez $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 4, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "beq", /* opcode */
+ BR_RANGE_S16K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BEQ /* beq $rt, $ra, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BEQ /* beq $rt, $ra, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BNE, /* bne $rt, $ra, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BNE, /* bne $rt, $ra, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BNE, /* bne $rt, $ra, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 8, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_ABS, BFD_RELOC_NDS32_EMPTY},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bne", /* opcode */
+ BR_RANGE_S16K, /* br_range */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BNE /* bne $rt, $ra, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BNE /* bne $rt, $ra, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BEQ, /* beq $rt, $ra, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BEQ, /* beq $rt, $ra, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BEQ, /* beq $rt, $ra, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 15, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 4, 8, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "beqz38", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BEQZ38 << 16 /* beqz $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BEQZ /* beqz $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BEQZ /* beqz $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BNEZ, /* bnez $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BNEZ, /* bnez $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 4, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bnez38", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BNEZ38 << 16 /* bnez $rt, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BNEZ /* bnez $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BNEZ /* bnez $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BEQZ, /* beqz $rt, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BEQZ, /* beqz $rt, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 4, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "beqzs8", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {
+ {
+ INSN_BEQZS8 << 16 /* beqz $r15, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BEQZ_TA /* bnez $rt, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BEQZ_TA /* bnez $rt, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BNEZ_TA, /* bnez $r15, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BNEZ_TA, /* bnez $r15, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
+ {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 4, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bnezs8", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {
+ {
+ INSN_BNEZS8 << 16 /* bnez $r15, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BNEZ_TA /* bnez $r15, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BNEZ_TA /* bnez $r15, label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BEQZ_TA, /* beqz $r15, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BEQZ_TA, /* beqz $r15, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S256 */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S64K */
+ {{0, 0, 0, FALSE}}, /* BR_RANGE_S16M */
+ {{0, 0, 0, FALSE}} /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 4, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_17_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bnes38", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BNES38 << 16 /* bne $rt, $R5, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BNE_R5 /* bne $rt, $R5, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BEQ_R5, /* beq $rt, $R5, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BEQ_R5, /* beq $rt, $R5, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BEQ_R5, /* beq $rt, $R5, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 8, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "beqs38", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BEQS38 << 16 /* beq $rt, $R5, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_BEQ_R5 /* beq $rt, $R5, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BNE_R5, /* bne $rt, $R5, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BNE_R5, /* bne $rt, $R5, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BNE_R5, /* bne $rt, $R5, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 8, 0x7, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {2, 4, 8, 8, 16}, /* relax_code_size */
+ {2, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 2, 0, BFD_RELOC_NDS32_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_15_PCREL},
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
+ {8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
+ {12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
+ {12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
+ {12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "beqc", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {
+ {0, 8, 0x7FF, TRUE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BEQC /* beqc $rt, imm11s, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_MOVI_TA, /* movi $ta, imm11s */
+ INSN_BEQ_TA /* beq $rt, $ta, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BNEC, /* bnec $rt, imm11s, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 8, 0x7FF, TRUE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 0, 0xFFFFF, FALSE},
+ {4, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 8, 8, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
+ {4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
+ {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ "bnec", /* opcode */
+ BR_RANGE_S256, /* br_range */
+ {
+ {0, 8, 0x7FF, TRUE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* cond_field */
+ {
+ {
+ INSN_BNEC /* bnec $rt, imm11s, label */
+ }, /* BR_RANGE_S256 */
+ {
+ INSN_MOVI_TA, /* movi $ta, imm11s */
+ INSN_BNE_TA /* bne $rt, $ta, label */
+ }, /* BR_RANGE_S16K */
+ {
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S64K */
+ {
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
+ INSN_J /* j label */
+ }, /* BR_RANGE_S16M */
+ {
+ INSN_BEQC, /* beqc $rt, imm11s, $1 */
+ INSN_SETHI_TA, /* sethi $ta, label */
+ INSN_ORI_TA, /* ori $ta, $ta, label */
+ INSN_JR_TA /* jr $ta */
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_seq */
+ {
+ {
+ {0, 8, 0x7FF, TRUE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 0, 0xFFFFF, FALSE},
+ {4, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 8, 0x7FF, FALSE},
+ {0, 20, 0x1F, FALSE},
+ {0, 0, 0, FALSE}
+ } /* BR_RANGE_U4G */
+ }, /* relax_code_condition */
+ {4, 8, 8, 8, 16}, /* relax_code_size */
+ {4, 4, 4, 4, 4}, /* relax_branch_isize */
+ {
+ {
+ {0, 4, 0, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S256 */
+ {
+ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
+ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
+ {4, 4, 0, BFD_RELOC_NDS32_15_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S64K */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_25_PCREL},
+ {0, 0, 0, 0}
+ }, /* BR_RANGE_S16M */
+ {
+ {0, 4, NDS32_CREATE_LABEL, BFD_RELOC_NDS32_WORD_9_PCREL},
+ {4, 4, 0, BFD_RELOC_NDS32_HI20},
+ {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
+ {12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
+ {0, 0, 0, 0}
+ } /* BR_RANGE_U4G */
+ } /* relax_fixup */
+ },
+ {
+ NULL, /* opcode */
+ 0, /* br_range */
+ {{0, 0, 0, FALSE}}, /* cond_field */
+ {{0}}, /* relax_code_seq */
+ {{{0, 0, 0, FALSE}}}, /* relax_code_condition */
+ {0}, /* relax_code_size */
+ {0}, /* relax_branch_isize */
+ {{{0, 0, 0, 0}}}, /* relax_fixup */
+ },
+};
+
+/* GAS definitions for command-line options. */
+enum options
+{
+ OPTION_BIG = OPTION_MD_BASE,
+ OPTION_LITTLE,
+ OPTION_TURBO,
+ OPTION_PIC,
+ OPTION_RELAX_FP_AS_GP_OFF,
+ OPTION_RELAX_B2BB_ON,
+ OPTION_RELAX_ALL_OFF,
+ OPTION_OPTIMIZE,
+ OPTION_OPTIMIZE_SPACE
+};
+
+const char *md_shortopts = "m:O:";
+struct option md_longopts[] =
+{
+ {"O1", no_argument, NULL, OPTION_OPTIMIZE},
+ {"Os", no_argument, NULL, OPTION_OPTIMIZE_SPACE},
+ {"big", no_argument, NULL, OPTION_BIG},
+ {"little", no_argument, NULL, OPTION_LITTLE},
+ {"EB", no_argument, NULL, OPTION_BIG},
+ {"EL", no_argument, NULL, OPTION_LITTLE},
+ {"meb", no_argument, NULL, OPTION_BIG},
+ {"mel", no_argument, NULL, OPTION_LITTLE},
+ {"mall-ext", no_argument, NULL, OPTION_TURBO},
+ {"mext-all", no_argument, NULL, OPTION_TURBO},
+ {"mpic", no_argument, NULL, OPTION_PIC},
+ /* Relaxation related options. */
+ {"mno-fp-as-gp-relax", no_argument, NULL, OPTION_RELAX_FP_AS_GP_OFF},
+ {"mb2bb", no_argument, NULL, OPTION_RELAX_B2BB_ON},
+ {"mno-all-relax", no_argument, NULL, OPTION_RELAX_ALL_OFF},
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+struct nds32_parse_option_table
+{
+ const char *name; /* Option string. */
+ char *help; /* Help description. */
+ int (*func) (char *arg); /* How to parse it. */
+};
+
+
+/* The value `-1' represents this option has *NOT* been set. */
+#ifdef NDS32_DEFAULT_ARCH_NAME
+static char* nds32_arch_name = NDS32_DEFAULT_ARCH_NAME;
+#else
+static char* nds32_arch_name = "v3";
+#endif
+static int nds32_baseline = -1;
+static int nds32_gpr16 = -1;
+static int nds32_fpu_sp_ext = -1;
+static int nds32_fpu_dp_ext = -1;
+static int nds32_freg = -1;
+static int nds32_abi = -1;
+
+/* Record ELF flags */
+static int nds32_elf_flags = 0;
+static int nds32_fpu_com = 0;
+
+static int nds32_parse_arch (char *str);
+static int nds32_parse_baseline (char *str);
+static int nds32_parse_freg (char *str);
+static int nds32_parse_abi (char *str);
+
+static struct nds32_parse_option_table parse_opts [] =
+{
+ {"arch=", N_("<arch name>\t Assemble for architecture <arch name>\n\
+ <arch name> could be\n\
+ v3, v3j, v3m, v3f, v3s, "\
+ "v2, v2j, v2f, v2s"), nds32_parse_arch},
+ {"baseline=", N_("<baseline>\t Assemble for baseline <baseline>\n\
+ <baseline> could be v2, v3, v3m"),
+ nds32_parse_baseline},
+ {"fpu-freg=", N_("<freg>\t Specify a FPU configuration\n\
+ <freg>\n\
+ 0: 8 SP / 4 DP registers\n\
+ 1: 16 SP / 8 DP registers\n\
+ 2: 32 SP / 16 DP registers\n\
+ 3: 32 SP / 32 DP registers"), nds32_parse_freg},
+ {"abi=", N_("<abi>\t Specify a abi version\n\
+ <abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi},
+ {NULL, NULL, NULL}
+};
+
+static int nds32_mac = 1;
+static int nds32_div = 1;
+static int nds32_16bit_ext = 1;
+static int nds32_dx_regs = 1;
+static int nds32_perf_ext = 1;
+static int nds32_perf_ext2 = 1;
+static int nds32_string_ext = 1;
+static int nds32_audio_ext = 1;
+static int nds32_fpu_fma = 0;
+static int nds32_pic = 0;
+static int nds32_relax_fp_as_gp = 1;
+static int nds32_relax_b2bb = 0;
+static int nds32_relax_all = 1;
+struct nds32_set_option_table
+{
+ const char *name; /* Option string. */
+ char *help; /* Help description. */
+ int *var; /* Variable to be set. */
+ int value; /* Value to set. */
+};
+
+/* The option in this group has both Enable/Disable settings.
+ Just list on here. */
+
+static struct nds32_set_option_table toggle_opts [] =
+{
+ {"mac", N_("Multiply instructions support"), &nds32_mac, 1},
+ {"div", N_("Divide instructions support"), &nds32_div, 1},
+ {"16bit-ext", N_("16-bit extension"), &nds32_16bit_ext, 1},
+ {"dx-regs", N_("d0/d1 registers"), &nds32_dx_regs, 1},
+ {"perf-ext", N_("Performance extension"), &nds32_perf_ext, 1},
+ {"perf2-ext", N_("Performance extension 2"), &nds32_perf_ext2, 1},
+ {"string-ext", N_("String extension"), &nds32_string_ext, 1},
+ {"reduced-regs", N_("Reduced Register configuration (GPR16) option"), &nds32_gpr16, 1},
+ {"audio-isa-ext", N_("AUDIO ISA extension"), &nds32_audio_ext, 1},
+ {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
+ {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
+ {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
+ {NULL, NULL, NULL, 0}
+};
+
+
+/* GAS declarations. */
+
+/* This is the callback for nds32-asm.c to parse operands. */
+int
+nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
+ struct nds32_asm_insn *pinsn,
+ char **pstr, int64_t *value);
+
+
+struct nds32_asm_desc asm_desc;
+
+/* md_after_parse_args ()
+
+ GAS will call md_after_parse_args whenever it is defined.
+ This function checks any conflicting options specified. */
+
+void
+nds32_after_parse_args (void)
+{
+ /* If -march option is not used in command-line, set the value of option
+ variable according to NDS32_DEFAULT_ARCH_NAME. */
+ nds32_parse_arch (nds32_arch_name);
+}
+
+/* This function is called when printing usage message (--help). */
+
+void
+md_show_usage (FILE *stream)
+{
+ struct nds32_parse_option_table *coarse_tune;
+ struct nds32_set_option_table *fine_tune;
+
+ fprintf (stream, _("\n NDS32-specific assembler options:\n"));
+ fprintf (stream, _("\
+ -O1, Optimize for performance\n\
+ -Os Optimize for space\n"));
+ fprintf (stream, _("\
+ -EL, -mel or -little Produce little endian output\n\
+ -EB, -meb or -big Produce big endian output\n\
+ -mpic Generate PIC\n\
+ -mno-fp-as-gp-relax Suppress fp-as-gp relaxation for this file\n\
+ -mb2bb-relax Back-to-back branch optimization\n\
+ -mno-all-relax Suppress all relaxation for this file\n"));
+
+ for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
+ {
+ if (coarse_tune->help != NULL)
+ fprintf (stream, _(" -m%s%s\n"),
+ coarse_tune->name, _(coarse_tune->help));
+ }
+
+ for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
+ {
+ if (fine_tune->help != NULL)
+ fprintf (stream, _(" -m[no-]%-17sEnable/Disable %s\n"),
+ fine_tune->name, _(fine_tune->help));
+ }
+
+ fprintf (stream, _("\
+ -mall-ext Turn on all extensions and instructions support\n"));
+}
+
+void
+nds32_frag_init (fragS *fragp)
+{
+ fragp->tc_frag_data.flag = 0;
+ fragp->tc_frag_data.opcode = NULL;
+ fragp->tc_frag_data.fixup = NULL;
+}
+
+
+
+/* This function reads an expression from a C string and returns a pointer past
+ the end of the expression. */
+
+static char *
+parse_expression (char *str, expressionS *exp)
+{
+ char *s;
+ char *tmp;
+
+ tmp = input_line_pointer; /* Save line pointer. */
+ input_line_pointer = str;
+ expression (exp);
+ s = input_line_pointer;
+ input_line_pointer = tmp; /* Restore line pointer. */
+
+ return s; /* Return pointer to where parsing stopped. */
+}
+
+void
+nds32_start_line_hook (void)
+{
+}
+
+/*
+ * Pseudo opcodes
+ */
+
+typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], int pv);
+struct nds32_pseudo_opcode
+{
+ const char *opcode;
+ int argc;
+ nds32_pseudo_opcode_func proc;
+ int pseudo_val;
+
+ /* Some instructions are not pseudo opcode, but they might still be
+ expanded or changed with other instruction combination for some
+ conditions. We also apply this structure to assist such work.
+
+ For example, if the distance of branch target '.L0' is larger than
+ imm8s<<1 range,
+
+ the instruction:
+
+ beqzs8 .L0
+
+ will be transformed into:
+
+ bnezs8 .LCB0
+ j .L0
+ .LCB0:
+
+ However, sometimes we do not want assembler to do such changes
+ because compiler knows how to generate corresponding instruction sequence.
+ Use this field to indicate that this opcode is also a physical instruction.
+ If the flag 'verbatim' is nozero and this opcode
+ is a physical instruction, we should not expand it. */
+ int physical_op;
+};
+#define PV_DONT_CARE 0
+
+static struct hash_control *nds32_pseudo_opcode_hash = NULL;
+
+static int
+builtin_isreg (const char *s, const char *x ATTRIBUTE_UNUSED)
+{
+ return s[0] == '$';
+}
+
+static int
+builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
+{
+ struct nds32_keyword *k;
+ if (*s != '$')
+ return -1;
+ s++;
+ k = hash_find (nds32_gprs_hash, s);
+
+ if (k == NULL)
+ return -1;
+
+ return k->value;
+}
+
+static int
+builtin_addend (const char *s, char *x ATTRIBUTE_UNUSED)
+{
+ const char *ptr = s;
+
+ while (*ptr != '+' && *ptr != '-' && *ptr)
+ ++ptr;
+
+ if (*ptr == 0)
+ return 0;
+ else
+ return strtol (ptr, NULL, 0);
+}
+
+static void
+md_assemblef (char *format, ...)
+{
+ /* FIXME: hope this is long enough. */
+ char line[1024];
+ va_list ap;
+ unsigned int r;
+
+ va_start (ap, format);
+ r = vsnprintf (line, sizeof (line), format, ap);
+ md_assemble (line);
+
+ gas_assert (r < sizeof (line));
+}
+
+/* Some prototypes here, since some op may use another op. */
+static void do_pseudo_li_internal (char *rt, int imm32s);
+static void do_pseudo_move_reg_internal (char *dst, char *src);
+
+static void
+do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ char *arg_label = argv[0];
+ relaxing = TRUE;
+ /* b label */
+ if (nds32_pic && strstr (arg_label, "@PLT"))
+ {
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
+ md_assemble ("add $ta,$ta,$gp");
+ md_assemble ("jr $ta");
+ }
+ else
+ {
+ md_assemblef ("j %s", arg_label);
+ }
+ relaxing = FALSE;
+}
+
+static void
+do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ char *arg_label = argv[0];
+ relaxing = TRUE;
+ /* bal|call label */
+ if (nds32_pic
+ && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
+ {
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
+ md_assemble ("add $ta,$ta,$gp");
+ md_assemble ("jral $ta");
+ }
+ else
+ {
+ md_assemblef ("jal %s", arg_label);
+ }
+ relaxing = FALSE;
+}
+
+static void
+do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* rt5, ra5, label */
+ md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
+ md_assemblef ("beqz $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* rt5, ra5, label */
+ md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
+ md_assemblef ("beqz $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* bgt rt5, ra5, label */
+ md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
+ md_assemblef ("bnez $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* bgt rt5, ra5, label */
+ md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
+ md_assemblef ("bnez $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* bgt rt5, ra5, label */
+ md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
+ md_assemblef ("beqz $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* bgt rt5, ra5, label */
+ md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
+ md_assemblef ("beqz $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* rt5, ra5, label */
+ md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
+ md_assemblef ("bnez $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* rt5, ra5, label */
+ md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
+ md_assemblef ("bnez $ta,%s", argv[2]);
+}
+
+static void
+do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ md_assemblef ("jr %s", argv[0]);
+}
+
+static void
+do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ if (argc == 1)
+ md_assemblef ("jral $lp,%s", argv[0]);
+ else
+ md_assemblef ("jral %s,%s", argv[0], argv[1]);
+}
+
+static void
+do_pseudo_la_internal (const char *arg_reg, const char *arg_label,
+ const char *line)
+{
+ relaxing = TRUE;
+ /* rt, label */
+ if (!nds32_pic && !strstr(arg_label, "@"))
+ {
+ md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
+ md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
+ }
+ else if (strstr (arg_label, "@TPOFF"))
+ {
+ /* la $rt, sym@TPOFF */
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
+ md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
+ }
+ else if (strstr(arg_label, "@GOTTPOFF"))
+ {
+ /* la $rt, sym@GOTTPOFF*/
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
+ md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
+ }
+ else if (nds32_pic && ((strstr (arg_label, "@PLT")
+ || strstr (arg_label, "@GOTOFF"))))
+ {
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
+ md_assemblef ("add %s,$ta,$gp", arg_reg);
+ }
+ else if (nds32_pic && strstr (arg_label, "@GOT"))
+ {
+ long addend = builtin_addend (arg_label, NULL);
+
+ md_assemblef ("sethi $ta,hi20(%s)", arg_label);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
+ md_assemblef ("lw %s,[$gp+$ta]", arg_reg);
+ if (addend != 0)
+ {
+ if (addend < 0x4000 && addend >= -0x4000)
+ {
+ md_assemblef ("addi %s,%s,%d", arg_reg, arg_reg, addend);
+ }
+ else
+ {
+ do_pseudo_li_internal ("$ta", addend);
+ md_assemblef ("add %s,$ta,%s", arg_reg, arg_reg);
+ }
+ }
+ }
+ else
+ as_bad (_("need PIC qualifier with symbol. '%s'"), line);
+ relaxing = FALSE;
+}
+
+static void
+do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
+}
+
+static void
+do_pseudo_li_internal (char *rt, int imm32s)
+{
+ if (enable_16bit && imm32s <= 0xf && imm32s >= -0x10)
+ md_assemblef ("movi55 %s,%d", rt, imm32s);
+ else if (imm32s <= 0x7ffff && imm32s >= -0x80000)
+ md_assemblef ("movi %s,%d", rt, imm32s);
+ else if ((imm32s & 0xfff) == 0)
+ md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
+ else
+ {
+ md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
+ md_assemblef ("ori %s,%s,lo12(%d)", rt, rt, imm32s);
+ }
+}
+
+static void
+do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* Validate argv[1] for constant expression. */
+ expressionS exp;
+
+ parse_expression (argv[1], &exp);
+ if (exp.X_op != O_constant)
+ {
+ as_bad (_("Operand is not a constant. `%s'"), argv[argc]);
+ return;
+ }
+
+ do_pseudo_li_internal (argv[0], exp.X_add_number);
+}
+
+static void
+do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
+{
+ char ls = 'r';
+ char size = 'x';
+ const char *sign = "";
+
+ /* Prepare arguments for various load/store. */
+ sign = (pv & 0x10) ? "s" : "";
+ ls = (pv & 0x80000000) ? 's' : 'l';
+ switch (pv & 0x3)
+ {
+ case 0: size = 'b'; break;
+ case 1: size = 'h'; break;
+ case 2: size = 'w'; break;
+ }
+
+ if (ls == 's' || size == 'w')
+ sign = "";
+
+ if (builtin_isreg (argv[1], NULL))
+ {
+ /* lwi */
+ md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
+ }
+ else if (!nds32_pic)
+ {
+ relaxing = TRUE;
+ if (strstr (argv[1], "@TPOFF"))
+ {
+ /* ls.w $rt, sym@TPOFF */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
+ md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
+ }
+ else if (strstr (argv[1], "@GOTTPOFF"))
+ {
+ /* ls.w $rt, sym@GOTTPOFF */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
+ md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
+ }
+ else
+ {
+ /* lwi */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
+ }
+ relaxing = FALSE;
+ }
+ else
+ {
+ relaxing = TRUE;
+ /* PIC code. */
+ if (strstr (argv[1], "@GOTOFF"))
+ {
+ /* lw */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
+ md_assemblef ("%c%c%s %s,[$ta+$gp]", ls, size, sign, argv[0]);
+ }
+ else if (strstr (argv[1], "@GOT"))
+ {
+ long addend = builtin_addend (argv[1], NULL);
+ /* lw */
+ md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
+ md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
+ md_assemble ("lw $ta,[$gp+$ta]"); /* Load address word. */
+ if (addend < 0x10000 && addend >= -0x10000)
+ {
+ md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls, size, sign, argv[0], addend);
+ }
+ else
+ {
+ /* lw */
+ do_pseudo_li_internal (argv[0], addend);
+ md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], argv[0]);
+ }
+ }
+ else
+ {
+ as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
+ }
+ relaxing = FALSE;
+ }
+}
+
+static void
+do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
+{
+ char *arg_rt = argv[0];
+ char *arg_label = argv[1];
+ char *arg_inc = argv[2];
+ char ls = 'r';
+ char size = 'x';
+ const char *sign = "";
+
+ /* Prepare arguments for various load/store. */
+ sign = (pv & 0x10) ? "s" : "";
+ ls = (pv & 0x80000000) ? 's' : 'l';
+ switch (pv & 0x3)
+ {
+ case 0: size = 'b'; break;
+ case 1: size = 'h'; break;
+ case 2: size = 'w'; break;
+ }
+
+ if (ls == 's' || size == 'w')
+ sign = "";
+
+ do_pseudo_la_internal ("$ta", arg_label, argv[argc]);
+ md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
+}
+
+static void
+do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
+{
+ char *arg_rt = argv[0];
+ char *arg_inc = argv[1];
+ char ls = 'r';
+ char size = 'x';
+ const char *sign = "";
+
+ /* Prepare arguments for various load/store. */
+ sign = (pv & 0x10) ? "s" : "";
+ ls = (pv & 0x80000000) ? 's' : 'l';
+ switch (pv & 0x3)
+ {
+ case 0: size = 'b'; break;
+ case 1: size = 'h'; break;
+ case 2: size = 'w'; break;
+ }
+
+ if (ls == 's' || size == 'w')
+ sign = "";
+
+ md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
+}
+
+static void
+do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
+{
+ char ls = 'r';
+ char size = 'x';
+ const char *sign = "";
+
+ /* Prepare arguments for various load/store. */
+ sign = (pv & 0x10) ? "s" : "";
+ ls = (pv & 0x80000000) ? 's' : 'l';
+ switch (pv & 0x3)
+ {
+ case 0: size = 'b'; break;
+ case 1: size = 'h'; break;
+ case 2: size = 'w'; break;
+ }
+
+ if (ls == 's' || size == 'w')
+ sign = "";
+
+ md_assemblef ("%c%c%si.bi %s,%s,%s",
+ ls, size, sign, argv[0], argv[1], argv[2]);
+}
+
+static void
+do_pseudo_move_reg_internal (char *dst, char *src)
+{
+ if (enable_16bit)
+ md_assemblef ("mov55 %s,%s", dst, src);
+ else
+ md_assemblef ("ori %s,%s,0", dst, src);
+}
+
+static void
+do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ expressionS exp;
+
+ parse_expression (argv[1], &exp);
+
+ if (builtin_isreg (argv[1], NULL))
+ do_pseudo_move_reg_internal (argv[0], argv[1]);
+ else if (exp.X_op == O_constant)
+ /* move $rt, imm -> li $rt, imm */
+ do_pseudo_li_internal (argv[0], exp.X_add_number);
+ else
+ /* l.w $rt, var -> l.w $rt, var */
+ do_pseudo_ls_bhw (argc, argv, 2);
+}
+
+static void
+do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* Instead of "subri". */
+ md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
+}
+
+static void
+do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
+}
+
+static void
+do_pseudo_pushpopm (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* posh/pop $ra, $rb */
+ /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
+ int rb, re, ra, en4;
+ int i;
+ char *opc = "pushpopm";
+
+ if (argc == 3)
+ as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated. "
+ "Only 'pushm/popm $ra5' is supported now. %s", argv[argc]);
+ else if (argc == 1)
+ as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv[argc]);
+
+ if (strstr (argv[argc], "pop") == argv[argc])
+ opc = "lmw.bim";
+ else if (strstr (argv[argc], "push") == argv[argc])
+ opc = "smw.adm";
+ else
+ as_fatal ("nds32-as internal error. %s", argv[argc]);
+
+ rb = builtin_regnum (argv[0], NULL);
+ re = builtin_regnum (argv[1], NULL);
+
+ if (re < rb)
+ {
+ as_warn ("$rb should not be smaller than $ra. %s", argv[argc]);
+ /* Swap to right order. */
+ ra = re;
+ re = rb;
+ rb = ra;
+ }
+
+ /* Build enable4 mask. */
+ en4 = 0;
+ if (re >= 28 || rb >= 28)
+ {
+ for (i = (rb >= 28? rb: 28); i <= re; i++)
+ en4 |= 1 << (3 - (i - 28));
+ }
+
+ /* Adjust $re, $rb. */
+ if (rb >= 28)
+ rb = re = 31;
+ else if (nds32_gpr16 != 1 && re >= 28)
+ re = 27;
+
+ /* Reduce register. */
+ if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
+ {
+ if (re >= 15 && strstr(opc, "smw") != NULL)
+ md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
+ if (rb <= 10)
+ md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
+ if (re >= 15 && strstr(opc, "lmw") != NULL)
+ md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
+ }
+ else
+ md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
+}
+
+static void
+do_pseudo_pushpop (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* push/pop $ra5, $label=$sp */
+ char *argvm[3];
+
+ if (argc == 2)
+ as_bad ("'push/pop $ra5, rb5' is deprecated. "
+ "Only 'push/pop $ra5' is supported now. %s", argv[argc]);
+
+ argvm[0] = argv[0];
+ argvm[1] = argv[0];
+ argvm[2] = argv[argc];
+ do_pseudo_pushpopm (2, argvm, PV_DONT_CARE);
+}
+
+static void
+do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ md_assemblef ("push25 %s,%s", argv[0], argv[1]);
+}
+
+static void
+do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
+}
+
+/* pv == 0, parsing "push.s" pseudo instruction operands.
+ pv != 0, parsing "pop.s" pseudo instruction operands. */
+
+static void
+do_pseudo_pushpop_stack (int argc, char *argv[], int pv)
+{
+ /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
+ /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
+
+ int rb, re;
+ int en4;
+ int last_arg_index;
+ char *opc = (pv == 0) ? "smw.adm" : "lmw.bim";
+
+ rb = re = 0;
+
+ if (argc == 1)
+ {
+ /* argc=1, operands pattern: { $fp $gp $lp $sp } */
+
+ /* Set register number Rb = Re = $sp = $r31. */
+ rb = re = 31;
+ }
+ else if (argc == 2 || argc == 3)
+ {
+ /* argc=2, operands pattern: Rb, Re */
+ /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp } */
+
+ /* Get register number in integer. */
+ rb = builtin_regnum (argv[0], NULL);
+ re = builtin_regnum (argv[1], NULL);
+
+ /* Rb should be equal/less than Re. */
+ if (rb > re)
+ as_bad ("The first operand (%s) should be equal to or smaller than "
+ "second operand (%s).", argv[0], argv[1]);
+
+ /* forbid using $fp|$gp|$lp|$sp in Rb or Re
+ r28 r29 r30 r31 */
+ if (rb >= 28)
+ as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
+ if (re >= 28)
+ as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
+ }
+ else
+ {
+ as_bad ("Invalid operands pattern !!");
+ }
+
+ /* Build Enable4 mask. */
+ /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
+ and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
+ which is also valid for code generation. */
+ en4 = 0;
+ last_arg_index = argc - 1;
+ if (strstr (argv[last_arg_index], "$fp"))
+ en4 |= 8;
+ if (strstr (argv[last_arg_index], "$gp"))
+ en4 |= 4;
+ if (strstr (argv[last_arg_index], "$lp"))
+ en4 |= 2;
+ if (strstr (argv[last_arg_index], "$sp"))
+ en4 |= 1;
+
+ md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
+}
+
+static void
+do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ char size = 'x';
+ /* If users omit push location, use $sp as default value. */
+ char location[8] = "$sp"; /* 8 is enough for register name. */
+
+ switch (pv & 0x3)
+ {
+ case 0: size = 'b'; break;
+ case 1: size = 'h'; break;
+ case 2: size = 'w'; break;
+ case 3: size = 'w'; break;
+ }
+
+ if (argc == 2)
+ {
+ strncpy (location, argv[1], 8);
+ location[7] = '\0';
+ }
+
+ md_assemblef ("l.%c $ta,%s", size, argv[0]);
+ md_assemblef ("smw.adm $ta,[%s],$ta", location);
+
+ if ((pv & 0x3) == 0x3) /* double-word */
+ {
+ md_assemblef ("l.w $ta,%s+4", argv[0]);
+ md_assemblef ("smw.adm $ta,[%s],$ta", location);
+ }
+}
+
+static void
+do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ char size = 'x';
+ /* If users omit pop location, use $sp as default value. */
+ char location[8] = "$sp"; /* 8 is enough for register name. */
+
+ switch (pv & 0x3)
+ {
+ case 0: size = 'b'; break;
+ case 1: size = 'h'; break;
+ case 2: size = 'w'; break;
+ case 3: size = 'w'; break;
+ }
+
+ if (argc == 3)
+ {
+ strncpy (location, argv[2], 8);
+ location[7] = '\0';
+ }
+
+ if ((pv & 0x3) == 0x3) /* double-word */
+ {
+ md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
+ md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
+ }
+
+ md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
+ md_assemblef ("s.%c %s,%s", size, argv[1], argv[0]);
+}
+
+static void
+do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* If users omit push location, use $sp as default value. */
+ char location[8] = "$sp"; /* 8 is enough for register name. */
+
+ if (argc == 2)
+ {
+ strncpy (location, argv[1], 8);
+ location[7] = '\0';
+ }
+
+ md_assemblef ("la $ta,%s", argv[0]);
+ md_assemblef ("smw.adm $ta,[%s],$ta", location);
+}
+
+static void
+do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
+{
+ /* If users omit push location, use $sp as default value. */
+ char location[8] = "$sp"; /* 8 is enough for register name. */
+
+ if (argc == 2)
+ {
+ strncpy (location, argv[1], 8);
+ location[7] = '\0';
+ }
+
+ md_assemblef ("li $ta,%s", argv[0]);
+ md_assemblef ("smw.adm $ta,[%s],$ta", location);
+}
+
+struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
+{
+ {"b", 1, do_pseudo_b, 0, 0},
+ {"bal", 1, do_pseudo_bal, 0, 0},
+
+ {"bge", 3, do_pseudo_bge, 0, 0},
+ {"bges", 3, do_pseudo_bges, 0, 0},
+
+ {"bgt", 3, do_pseudo_bgt, 0, 0},
+ {"bgts", 3, do_pseudo_bgts, 0, 0},
+
+ {"ble", 3, do_pseudo_ble, 0, 0},
+ {"bles", 3, do_pseudo_bles, 0, 0},
+
+ {"blt", 3, do_pseudo_blt, 0, 0},
+ {"blts", 3, do_pseudo_blts, 0, 0},
+
+ {"br", 1, do_pseudo_br, 0, 0},
+ {"bral", 1, do_pseudo_bral, 0, 0},
+
+ {"call", 1, do_pseudo_bal, 0, 0},
+
+ {"la", 2, do_pseudo_la, 0, 0},
+ {"li", 2, do_pseudo_li, 0, 0},
+
+ {"l.b", 2, do_pseudo_ls_bhw, 0, 0},
+ {"l.h", 2, do_pseudo_ls_bhw, 1, 0},
+ {"l.w", 2, do_pseudo_ls_bhw, 2, 0},
+ {"l.bs", 2, do_pseudo_ls_bhw, 0 | 0x10, 0},
+ {"l.hs", 2, do_pseudo_ls_bhw, 1 | 0x10, 0},
+ {"s.b", 2, do_pseudo_ls_bhw, 0 | 0x80000000, 0},
+ {"s.h", 2, do_pseudo_ls_bhw, 1 | 0x80000000, 0},
+ {"s.w", 2, do_pseudo_ls_bhw, 2 | 0x80000000, 0},
+
+ {"l.bp", 3, do_pseudo_ls_bhwp, 0, 0},
+ {"l.bpc", 3, do_pseudo_ls_bhwpc, 0, 0},
+ {"l.hp", 3, do_pseudo_ls_bhwp, 1, 0},
+ {"l.hpc", 3, do_pseudo_ls_bhwpc, 1, 0},
+ {"l.wp", 3, do_pseudo_ls_bhwp, 2, 0},
+ {"l.wpc", 3, do_pseudo_ls_bhwpc, 2, 0},
+ {"l.bsp", 3, do_pseudo_ls_bhwp, 0 | 0x10, 0},
+ {"l.bspc", 3, do_pseudo_ls_bhwpc, 0 | 0x10, 0},
+ {"l.hsp", 3, do_pseudo_ls_bhwp, 1 | 0x10, 0},
+ {"l.hspc", 3, do_pseudo_ls_bhwpc, 1 | 0x10, 0},
+ {"s.bp", 3, do_pseudo_ls_bhwp, 0 | 0x80000000, 0},
+ {"s.bpc", 3, do_pseudo_ls_bhwpc, 0 | 0x80000000, 0},
+ {"s.hp", 3, do_pseudo_ls_bhwp, 1 | 0x80000000, 0},
+ {"s.hpc", 3, do_pseudo_ls_bhwpc, 1 | 0x80000000, 0},
+ {"s.wp", 3, do_pseudo_ls_bhwp, 2 | 0x80000000, 0},
+ {"s.wpc", 3, do_pseudo_ls_bhwpc, 2 | 0x80000000, 0},
+ {"s.bsp", 3, do_pseudo_ls_bhwp, 0 | 0x80000000 | 0x10, 0},
+ {"s.hsp", 3, do_pseudo_ls_bhwp, 1 | 0x80000000 | 0x10, 0},
+
+ {"lbi.p", 3, do_pseudo_ls_bhwi, 0, 0},
+ {"lhi.p", 3, do_pseudo_ls_bhwi, 1, 0},
+ {"lwi.p", 3, do_pseudo_ls_bhwi, 2, 0},
+ {"sbi.p", 3, do_pseudo_ls_bhwi, 0 | 0x80000000, 0},
+ {"shi.p", 3, do_pseudo_ls_bhwi, 1 | 0x80000000, 0},
+ {"swi.p", 3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
+ {"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
+ {"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
+ {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
+
+ {"move", 2, do_pseudo_move, 0, 0},
+ {"neg", 2, do_pseudo_neg, 0, 0},
+ {"not", 2, do_pseudo_not, 0, 0},
+
+ {"pop", 2, do_pseudo_pushpop, 0, 0},
+ {"push", 2, do_pseudo_pushpop, 0, 0},
+ {"popm", 2, do_pseudo_pushpopm, 0, 0},
+ {"pushm", 3, do_pseudo_pushpopm, 0, 0},
+
+ {"v3push", 2, do_pseudo_v3push, 0, 0},
+ {"v3pop", 2, do_pseudo_v3pop, 0, 0},
+
+ /* Support pseudo instructions of pushing/poping registers into/from stack
+ push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
+ pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
+ { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
+ { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
+ { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
+ { "push.h", 2, do_pseudo_push_bhwd, 1, 0 },
+ { "push.w", 2, do_pseudo_push_bhwd, 2, 0 },
+ { "push.d", 2, do_pseudo_push_bhwd, 3, 0 },
+ { "pop.b", 3, do_pseudo_pop_bhwd, 0, 0 },
+ { "pop.h", 3, do_pseudo_pop_bhwd, 1, 0 },
+ { "pop.w", 3, do_pseudo_pop_bhwd, 2, 0 },
+ { "pop.d", 3, do_pseudo_pop_bhwd, 3, 0 },
+ { "pusha", 2, do_pseudo_pusha, 0, 0 },
+ { "pushi", 2, do_pseudo_pushi, 0, 0 },
+
+ {NULL, 0, NULL, 0, 0}
+};
+
+static void
+nds32_init_nds32_pseudo_opcodes (void)
+{
+ struct nds32_pseudo_opcode *opcode = nds32_pseudo_opcode_table;
+
+ nds32_pseudo_opcode_hash = hash_new ();
+ for ( ; opcode->opcode; opcode++)
+ {
+ void *op;
+
+ op = hash_find (nds32_pseudo_opcode_hash, opcode->opcode);
+ if (op != NULL)
+ {
+ as_warn (_("Duplicated pseudo-opcode %s."), opcode->opcode);
+ continue;
+ }
+ hash_insert (nds32_pseudo_opcode_hash, opcode->opcode, opcode);
+ }
+}
+
+static struct nds32_pseudo_opcode *
+nds32_lookup_pseudo_opcode (char *str)
+{
+ int i = 0;
+ /* Assume pseudo-opcode are less than 16-char in length. */
+ char op[16] = {0};
+
+ for (i = 0; i < (int)ARRAY_SIZE (op); i++)
+ {
+ if (ISSPACE (op[i] = str[i]))
+ break;
+ }
+
+ if (i >= (int)ARRAY_SIZE (op))
+ return NULL;
+
+ op[i] = '\0';
+
+ return hash_find (nds32_pseudo_opcode_hash, op);
+}
+
+static void
+nds32_pseudo_opcode_wrapper (char *line, struct nds32_pseudo_opcode *opcode)
+{
+ int argc = 0;
+ char *argv[8] = {NULL};
+ char *s;
+ char *str = xstrdup (line);
+
+ /* Parse arguments for opcode. */
+ s = str + strlen (opcode->opcode);
+
+ if (!s[0])
+ goto end;
+
+ /* Dummy comma to ease separate arguments as below. */
+ s[0] = ',';
+ do
+ {
+ if (s[0] == ',')
+ {
+ if (argc >= opcode->argc
+ || (argc >= (int)ARRAY_SIZE (argv) - 1))
+ as_bad (_("Too many argument. `%s'"), line);
+
+ argv[argc] = s + 1;
+ argc ++;
+ s[0] = '\0';
+ }
+ ++s;
+ } while (s[0] != '\0');
+end:
+ /* Put the origin line for debugging. */
+ argv[argc] = line;
+ opcode->proc (argc, argv, opcode->pseudo_val);
+ free (str);
+}
+
+/* This function will be invoked from function `nds32_after_parse_args'.
+ Thus, if the value of option has been set, keep the value the way it is. */
+
+static int
+nds32_parse_arch (char *str)
+{
+ static const struct nds32_arch
+ {
+ const char *name;
+ int baseline;
+ int reduced_reg;
+ int fpu_sp_ext;
+ int fpu_dp_ext;
+ int fpu_freg;
+ int abi;
+ } archs[] =
+ {
+ {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
+ {"v3j", ISA_V3, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
+ {"v3s", ISA_V3, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
+ {"v3f", ISA_V3, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
+ {"v3", ISA_V3, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
+ {"v2j", ISA_V2, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
+ {"v2s", ISA_V2, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
+ {"v2f", ISA_V2, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
+ {"v2", ISA_V2, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (archs); i++)
+ {
+ if (strcmp (str, archs[i].name) != 0)
+ continue;
+
+ /* The value `-1' represents this option has *NOT* been set. */
+ nds32_baseline = (-1 != nds32_baseline) ? nds32_baseline : archs[i].baseline;
+ nds32_gpr16 = (-1 != nds32_gpr16) ? nds32_gpr16 : archs[i].reduced_reg;
+ nds32_fpu_sp_ext = (-1 != nds32_fpu_sp_ext) ? nds32_fpu_sp_ext : archs[i].fpu_sp_ext;
+ nds32_fpu_dp_ext = (-1 != nds32_fpu_dp_ext) ? nds32_fpu_dp_ext : archs[i].fpu_dp_ext;
+ nds32_freg = (-1 != nds32_freg) ? nds32_freg : archs[i].fpu_freg;
+ nds32_abi = (-1 != nds32_abi) ? nds32_abi : archs[i].abi;
+
+ return 1;
+ }
+
+ /* Logic here rejects the input arch name. */
+ as_bad (_("unknown arch name `%s'\n"), str);
+
+ return 1;
+}
+
+/* This function parses "baseline" specified. */
+
+static int
+nds32_parse_baseline (char *str)
+{
+ if (strcmp (str, "v3") == 0)
+ nds32_baseline = ISA_V3;
+ else if (strcmp (str, "v3m") == 0)
+ nds32_baseline = ISA_V3M;
+ else if (strcmp (str, "v2") == 0)
+ nds32_baseline = ISA_V2;
+ else
+ {
+ /* Logic here rejects the input baseline. */
+ as_bad (_("unknown baseline `%s'\n"), str);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* This function parses "fpu-freg" specified. */
+
+static int
+nds32_parse_freg (char *str)
+{
+ if (strcmp (str, "2") == 0)
+ nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
+ else if (strcmp (str, "3") == 0)
+ nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
+ else if (strcmp (str, "1") == 0)
+ nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
+ else if (strcmp (str, "0") == 0)
+ nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
+ else
+ {
+ /* Logic here rejects the input FPU configuration. */
+ as_bad (_("unknown FPU configuration `%s'\n"), str);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* This function parse "abi=" specified. */
+
+static int
+nds32_parse_abi (char *str)
+{
+ if (strcmp (str, "v2") == 0)
+ nds32_abi = E_NDS_ABI_AABI;
+ /* Obsolete. */
+ else if (strcmp (str, "v2fp") == 0)
+ nds32_abi = E_NDS_ABI_V2FP;
+ else if (strcmp (str, "v1") == 0)
+ nds32_abi = E_NDS_ABI_V1;
+ else if (strcmp (str,"v2fpp") == 0)
+ nds32_abi = E_NDS_ABI_V2FP_PLUS;
+ else
+ {
+ /* Logic here rejects the input abi version. */
+ as_bad (_("unknown ABI version`%s'\n"), str);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* This function turn on all extensions and instructions support. */
+
+static int
+nds32_all_ext (void)
+{
+ nds32_mac = 1;
+ nds32_div = 1;
+ nds32_dx_regs = 1;
+ nds32_16bit_ext = 1;
+ nds32_perf_ext = 1;
+ nds32_perf_ext2 = 1;
+ nds32_string_ext = 1;
+ nds32_audio_ext = 1;
+ nds32_fpu_fma = 1;
+ nds32_fpu_sp_ext = 1;
+ nds32_fpu_dp_ext = 1;
+
+ return 1;
+}
+
+/* GAS will call md_parse_option whenever getopt returns an unrecognized code,
+ presumably indicating a special code value which appears in md_longopts.
+ This function should return non-zero if it handled the option and zero
+ otherwise. There is no need to print a message about an option not being
+ recognized. This will be handled by the generic code. */
+
+int
+nds32_parse_option (int c, char *arg)
+{
+ struct nds32_parse_option_table *coarse_tune;
+ struct nds32_set_option_table *fine_tune;
+ char *ptr_arg = NULL;
+
+ switch (c)
+ {
+ case OPTION_OPTIMIZE:
+ optimize = 1;
+ optimize_for_space = 0;
+ break;
+ case OPTION_OPTIMIZE_SPACE:
+ optimize = 0;
+ optimize_for_space = 1;
+ break;
+ case OPTION_BIG:
+ target_big_endian = 1;
+ break;
+ case OPTION_LITTLE:
+ target_big_endian = 0;
+ break;
+ case OPTION_TURBO:
+ nds32_all_ext ();
+ break;
+ case OPTION_PIC:
+ nds32_pic = 1;
+ break;
+ case OPTION_RELAX_FP_AS_GP_OFF:
+ nds32_relax_fp_as_gp = 0;
+ break;
+ case OPTION_RELAX_B2BB_ON:
+ nds32_relax_b2bb = 1;
+ break;
+ case OPTION_RELAX_ALL_OFF:
+ nds32_relax_all = 0;
+ break;
+ default:
+ /* Determination of which option table to search for to save time. */
+ if (!arg)
+ return 0;
+
+ ptr_arg = strchr (arg, '=');
+
+ if (ptr_arg)
+ {
+ /* Find the value after '='. */
+ if (ptr_arg != NULL)
+ ptr_arg++;
+ for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
+ {
+ if (strncmp (arg, coarse_tune->name, (ptr_arg - arg)) == 0)
+ {
+ coarse_tune->func (ptr_arg);
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ int disable = 0;
+
+ /* Filter out the Disable option first. */
+ if (strncmp (arg, "no-", 3) == 0)
+ {
+ disable = 1;
+ arg += 3;
+ }
+
+ for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
+ {
+ if (strcmp (arg, fine_tune->name) == 0)
+ {
+ if (fine_tune->var != NULL)
+ *fine_tune->var = (disable) ? 0 : 1;
+ return 1;
+ }
+ }
+ }
+ /* Nothing match. */
+ return 0;
+ }
+
+ return 1;
+}
+
+/* tc_check_label */
+
+void
+nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
+{
+ /* The code used to create BB is move to frob_label.
+ They should go there. */
+}
+
+static void
+set_endian_little (int on)
+{
+ target_big_endian = !on;
+}
+
+/* These functions toggles the generation of 16-bit. First encounter signals
+ the beginning of not generating 16-bit instructions and next encounter
+ signals the restoring back to default behavior. */
+
+static void
+trigger_16bit (int trigger)
+{
+ enable_16bit = trigger;
+}
+
+static int backup_16bit_mode;
+static void
+restore_16bit (int no_use ATTRIBUTE_UNUSED)
+{
+ enable_16bit = backup_16bit_mode;
+}
+
+static void
+off_16bit (int no_use ATTRIBUTE_UNUSED)
+{
+ backup_16bit_mode = enable_16bit;
+ enable_16bit = 0;
+}
+
+/* Built-in segments for small object. */
+typedef struct nds32_seg_entryT
+{
+ segT s;
+ const char *name;
+ flagword flags;
+} nds32_seg_entry;
+
+nds32_seg_entry nds32_seg_table[] =
+{
+ {NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
+ {NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
+ {NULL, ".sdata_h", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
+ {NULL, ".sdata_w", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
+ {NULL, ".sdata_d", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
+ {NULL, ".sbss_f", SEC_ALLOC | SEC_SMALL_DATA},
+ {NULL, ".sbss_b", SEC_ALLOC | SEC_SMALL_DATA},
+ {NULL, ".sbss_h", SEC_ALLOC | SEC_SMALL_DATA},
+ {NULL, ".sbss_w", SEC_ALLOC | SEC_SMALL_DATA},
+ {NULL, ".sbss_d", SEC_ALLOC | SEC_SMALL_DATA}
+};
+
+/* Indexes to nds32_seg_table[]. */
+enum NDS32_SECTIONS_ENUM
+{
+ SDATA_F_SECTION = 0,
+ SDATA_B_SECTION = 1,
+ SDATA_H_SECTION = 2,
+ SDATA_W_SECTION = 3,
+ SDATA_D_SECTION = 4,
+ SBSS_F_SECTION = 5,
+ SBSS_B_SECTION = 6,
+ SBSS_H_SECTION = 7,
+ SBSS_W_SECTION = 8,
+ SBSS_D_SECTION = 9
+};
+
+/* The following code is borrowed from v850_seg. Revise this is needed. */
+
+static void
+do_nds32_seg (int i, subsegT sub)
+{
+ nds32_seg_entry *seg = nds32_seg_table + i;
+
+ obj_elf_section_change_hook ();
+
+ if (seg->s != NULL)
+ subseg_set (seg->s, sub);
+ else
+ {
+ seg->s = subseg_new (seg->name, sub);
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ bfd_set_section_flags (stdoutput, seg->s, seg->flags);
+ if ((seg->flags & SEC_LOAD) == 0)
+ seg_info (seg->s)->bss = 1;
+ }
+ }
+}
+
+static void
+nds32_seg (int i)
+{
+ subsegT sub = get_absolute_expression ();
+
+ do_nds32_seg (i, sub);
+ demand_empty_rest_of_line ();
+}
+
+/* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
+static symbolS *nds32_last_label; /* Last label for aligment. */
+
+/* This code is referred from D30V for adjust label to be with pedning
+ aligment. For example,
+ LBYTE: .byte 0x12
+ LHALF: .half 0x12
+ LWORD: .word 0x12
+ Without this, the above label will not attatch to incoming data. */
+
+static void
+nds32_adjust_label (int n)
+{
+ /* FIXME: I think adjust lable and alignment is
+ the programmer's obligation. Saddly, VLSI team doesn't
+ properly use .align for their test cases.
+ So I re-implement cons_align and auto adjust labels, again.
+
+ I think d30v's implmentation is simple and good enough. */
+
+ symbolS *label = nds32_last_label;
+ nds32_last_label = NULL;
+
+ /* SEC_ALLOC is used to eliminate .debug_ sections.
+ SEC_CODE is used to include section for ILM. */
+ if (((now_seg->flags & SEC_ALLOC) == 0 && (now_seg->flags & SEC_CODE) == 0)
+ || strcmp (now_seg->name, ".eh_frame") == 0
+ || strcmp (now_seg->name, ".gcc_except_table") == 0)
+ return;
+
+ /* Only frag by alignment when needed.
+ Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
+ See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
+ if (frag_now_fix () & ((1 << n) -1 ))
+ {
+ if (subseg_text_p (now_seg))
+ frag_align_code (n, 0);
+ else
+ frag_align (n, 0, 0);
+
+ /* Record the minimum alignment for this segment. */
+ record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
+ }
+
+ if (label != NULL)
+ {
+ symbolS *sym;
+ int label_seen = FALSE;
+ struct frag *old_frag;
+ valueT old_value, new_value;
+
+ gas_assert (S_GET_SEGMENT (label) == now_seg);
+
+ old_frag = symbol_get_frag (label);
+ old_value = S_GET_VALUE (label);
+ new_value = (valueT) frag_now_fix ();
+
+ /* Multiple labels may be on the same address. And the last symbol
+ may not be a label at all, e.g., register name, external function names,
+ so I have to track the last label in tc_frob_label instead of
+ just using symbol_lastP. */
+ for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
+ {
+ if (symbol_get_frag (sym) == old_frag
+ && S_GET_VALUE (sym) == old_value)
+ {
+ /* Warning HERE! */
+ label_seen = TRUE;
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, new_value);
+ }
+ else if (label_seen && symbol_get_frag (sym) != old_frag)
+ break;
+ }
+ }
+}
+
+void
+nds32_cons_align (int size ATTRIBUTE_UNUSED)
+{
+ /* Do nothing here.
+ This is called before `md_flush_pending_output' is called by `cons'.
+
+ There are two things should be done for auto-adjust-label.
+ 1. Align data/instructions and adjust label to be attached to them.
+ 2. Clear auto-adjust state, so incommng data/instructions will not
+ adjust the label.
+
+ For example,
+ .byte 0x1
+ .L0:
+ .word 0x2
+ .word 0x3
+ in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
+
+ I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
+ but it is also called by `cons' before this function.
+ To simplify the code, instead of overriding .zero, .fill, .space, etc,
+ I think we should just adjust label in `nds32_aligned_X_cons' instead of here. */
+}
+
+static void
+nds32_aligned_cons (int idx)
+{
+ nds32_adjust_label (idx);
+ /* Call default handler. */
+ cons (1 << idx);
+ if (now_seg->flags & SEC_CODE
+ && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
+ {
+ /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data. */
+ expressionS exp;
+
+ exp.X_add_number = 0;
+ exp.X_op = O_constant;
+ fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
+ &exp, 0, BFD_RELOC_NDS32_DATA);
+ }
+}
+
+/* `.double' directive. */
+
+static void
+nds32_aligned_float_cons (int type)
+{
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ nds32_adjust_label (2);
+ break;
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ nds32_adjust_label (4);
+ break;
+ default:
+ as_bad ("Unrecognized float type, %c\n", (char)type);
+ }
+ /* Call default handler. */
+ float_cons (type);
+}
+
+static void
+nds32_enable_pic (int ignore ATTRIBUTE_UNUSED)
+{
+ /* Another way to do -mpic.
+ This is for GCC internal use and should always be first line
+ of code, otherwise, the effect is not determined. */
+ nds32_pic = 1;
+}
+
+static void
+nds32_set_abi (int ver)
+{
+ nds32_abi = ver;
+}
+
+/* Relax directive to set relocation R_NDS32_RELAX_ENTRY value. */
+
+static void
+nds32_relax_relocs (int relax)
+{
+ char saved_char;
+ char *name;
+ int i;
+ char *subtype_relax[] =
+ {"", "", "ex9", "ifc"};
+
+ name = input_line_pointer;
+ while (*input_line_pointer && !ISSPACE (*input_line_pointer))
+ input_line_pointer++;
+ saved_char = *input_line_pointer;
+ *input_line_pointer = 0;
+
+ for (i = 0; i < (int) ARRAY_SIZE (subtype_relax); i++)
+ {
+ if (strcmp (name, subtype_relax[i]) == 0)
+ {
+ switch (i)
+ {
+ case 0:
+ case 1:
+ enable_relax_relocs = relax & enable_relax_relocs;
+ enable_relax_ex9 = relax & enable_relax_ex9;
+ enable_relax_ifc = relax & enable_relax_ifc;
+ break;
+ case 2:
+ enable_relax_ex9 = relax;
+ break;
+ case 3:
+ enable_relax_ifc = relax;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ *input_line_pointer = saved_char;
+ ignore_rest_of_line ();
+}
+
+/* Record which arguments register($r0 ~ $r5) is not used in callee.
+ bit[i] for $ri */
+
+static void
+nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED)
+{
+ ignore_rest_of_line ();
+}
+
+/* Insert relocations to mark the begin and end of a fp-omitted function,
+ for further relaxation use.
+ bit[i] for $ri */
+
+static void
+nds32_omit_fp_begin (int mode)
+{
+ expressionS exp;
+
+ if (nds32_relax_fp_as_gp == 0)
+ return;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ if (mode == 1)
+ {
+ in_omit_fp = 1;
+ exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
+ fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
+ BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
+ }
+ else
+ {
+ in_omit_fp = 0;
+ exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
+ fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
+ BFD_RELOC_NDS32_RELAX_REGION_END);
+ }
+}
+
+/* Insert relocations to mark the begin and end of ex9 region,
+ for further relaxation use.
+ bit[i] for $ri */
+
+static void
+nds32_no_ex9_begin (int mode)
+{
+ expressionS exp;
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ if (mode == 1)
+ {
+ exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
+ fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
+ BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
+ }
+ else
+ {
+ exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
+ fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
+ BFD_RELOC_NDS32_RELAX_REGION_END);
+ }
+}
+
+static void
+nds32_loop_begin (int mode)
+{
+ /* Insert loop region relocation here. */
+ expressionS exp;
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ if (mode == 1)
+ {
+ exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
+ fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
+ BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
+ }
+ else
+ {
+ exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
+ fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
+ BFD_RELOC_NDS32_RELAX_REGION_END);
+ }
+}
+
+struct nds32_relocs_group
+{
+ struct nds32_relocs_pattern *pattern;
+ struct nds32_relocs_group *next;
+};
+
+static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
+
+/* Insert a relax hint. */
+
+static void
+nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char saved_char;
+ struct nds32_relocs_pattern *relocs = NULL;
+ struct nds32_relocs_group *group, *new;
+
+ name = input_line_pointer;
+ while (*input_line_pointer && !ISSPACE (*input_line_pointer))
+ input_line_pointer++;
+ saved_char = *input_line_pointer;
+ *input_line_pointer = 0;
+ name = strdup (name);
+
+ /* Find relax hint entry for next instruction, and all member will be
+ initialized at that time. */
+ relocs = hash_find (nds32_hint_hash, name);
+ if (relocs == NULL)
+ {
+ relocs = malloc (sizeof (struct nds32_relocs_pattern));
+ hash_insert (nds32_hint_hash, name, relocs);
+ }
+ else
+ {
+ while (relocs->next)
+ relocs=relocs->next;
+ relocs->next = malloc (sizeof (struct nds32_relocs_pattern));
+ relocs = relocs->next;
+ }
+
+ relocs->next = NULL;
+ *input_line_pointer = saved_char;
+ ignore_rest_of_line ();
+
+ /* Get the final one of relax hint series. */
+
+ /* It has to build this list because there are maybe more than one
+ instructions relative to the same instruction. It to connect to
+ next instruction after md_assemble. */
+ new = malloc (sizeof (struct nds32_relocs_group));
+ new->pattern = relocs;
+ new->next = NULL;
+ group = nds32_relax_hint_current;
+ if (!group)
+ nds32_relax_hint_current = new;
+ else
+ {
+ while (group->next != NULL)
+ group = group->next;
+ group->next = new;
+ }
+ relaxing = TRUE;
+}
+
+/* Decide the size of vector entries, only accepts 4 or 16 now. */
+
+static void
+nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS exp;
+
+ expression (&exp);
+
+ if (exp.X_op == O_constant)
+ {
+ if (exp.X_add_number == 4 || exp.X_add_number == 16)
+ {
+ if (vec_size == 0)
+ vec_size = exp.X_add_number;
+ else if (vec_size != exp.X_add_number)
+ as_warn (_("Different arguments of .vec_size are found, "
+ "previous %d, current %d"),
+ (int) vec_size, (int) exp.X_add_number);
+ }
+ else
+ as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
+ (int) exp.X_add_number);
+ }
+ else
+ as_warn (_("Argument of .vec_size is not a constant."));
+}
+
+/* The behavior of ".flag" directive varies depending on the target.
+ In nds32 target, we use it to recognize whether this assembly content is
+ generated by compiler. Other features can also be added in this function
+ in the future. */
+
+static void
+nds32_flag (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name;
+ char saved_char;
+ int i;
+ char *possible_flags[] = { "verbatim" };
+
+ /* Skip whitespaces. */
+ name = input_line_pointer;
+ while (*input_line_pointer && !ISSPACE (*input_line_pointer))
+ input_line_pointer++;
+ saved_char = *input_line_pointer;
+ *input_line_pointer = 0;
+
+ for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
+ {
+ if (strcmp (name, possible_flags[i]) == 0)
+ {
+ switch (i)
+ {
+ case 0:
+ /* flag: verbatim */
+ verbatim = 1;
+ break;
+ default:
+ break;
+ }
+ /* Already found the flag, no need to continue next loop. */
+ break;
+ }
+ }
+
+ *input_line_pointer = saved_char;
+ ignore_rest_of_line ();
+}
+
+static void
+nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
+{
+ /* N1213HC core is used. */
+}
+
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ /* Forced alignment if declared these ways. */
+ {"ascii", stringer, 8 + 0},
+ {"asciz", stringer, 8 + 1},
+ {"double", nds32_aligned_float_cons, 'd'},
+ {"dword", nds32_aligned_cons, 3},
+ {"float", nds32_aligned_float_cons, 'f'},
+ {"half", nds32_aligned_cons, 1},
+ {"hword", nds32_aligned_cons, 1},
+ {"int", nds32_aligned_cons, 2},
+ {"long", nds32_aligned_cons, 2},
+ {"octa", nds32_aligned_cons, 4},
+ {"quad", nds32_aligned_cons, 3},
+ {"qword", nds32_aligned_cons, 4},
+ {"short", nds32_aligned_cons, 1},
+ {"byte", nds32_aligned_cons, 0},
+ {"single", nds32_aligned_float_cons, 'f'},
+ {"string", stringer, 8 + 1},
+ {"word", nds32_aligned_cons, 2},
+
+ {"little", set_endian_little, 1},
+ {"big", set_endian_little, 0},
+ {"16bit_on", trigger_16bit, 1},
+ {"16bit_off", trigger_16bit, 0},
+ {"restore_16bit", restore_16bit, 0},
+ {"off_16bit", off_16bit, 0},
+
+ {"sdata_d", nds32_seg, SDATA_D_SECTION},
+ {"sdata_w", nds32_seg, SDATA_W_SECTION},
+ {"sdata_h", nds32_seg, SDATA_H_SECTION},
+ {"sdata_b", nds32_seg, SDATA_B_SECTION},
+ {"sdata_f", nds32_seg, SDATA_F_SECTION},
+
+ {"sbss_d", nds32_seg, SBSS_D_SECTION},
+ {"sbss_w", nds32_seg, SBSS_W_SECTION},
+ {"sbss_h", nds32_seg, SBSS_H_SECTION},
+ {"sbss_b", nds32_seg, SBSS_B_SECTION},
+ {"sbss_f", nds32_seg, SBSS_F_SECTION},
+
+ {"pic", nds32_enable_pic, 0},
+ {"n12_hc", nds32_n12hc, 0},
+ {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
+ {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
+ /* Obsolete. */
+ {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
+ {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
+ {"relax", nds32_relax_relocs, 1},
+ {"no_relax", nds32_relax_relocs, 0},
+ {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon?? */
+ {"omit_fp_begin", nds32_omit_fp_begin, 1},
+ {"omit_fp_end", nds32_omit_fp_begin, 0},
+ {"no_ex9_begin", nds32_no_ex9_begin, 1},
+ {"no_ex9_end", nds32_no_ex9_begin, 0},
+ {"vec_size", nds32_vec_size, 0},
+ {"flag", nds32_flag, 0},
+ {"innermost_loop_begin", nds32_loop_begin, 1},
+ {"innermost_loop_end", nds32_loop_begin, 0},
+ {"relax_hint", nds32_relax_hint, 0},
+ {NULL, NULL, 0}
+};
+
+void
+nds32_pre_do_align (int n, char *fill, int len, int max)
+{
+ /* Only make a frag if we HAVE to... */
+ fragS *fragP;
+ if (n != 0 && !need_pass_2)
+ {
+ if (fill == NULL)
+ {
+ if (subseg_text_p (now_seg))
+ {
+ fragP = frag_now;
+ frag_align_code (n, max);
+
+ /* Tag this alignment when there is a lable before it. */
+ if (label_exist)
+ {
+ fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
+ label_exist = 0;
+ }
+ }
+ else
+ frag_align (n, 0, max);
+ }
+ else if (len <= 1)
+ frag_align (n, *fill, max);
+ else
+ frag_align_pattern (n, fill, len, max);
+ }
+}
+
+void
+nds32_do_align (int n)
+{
+ /* Optimize for space and label exists. */
+ expressionS exp;
+
+ /* FIXME:I think this will break debug info sections and except_table. */
+ if (!enable_relax_relocs || !subseg_text_p (now_seg))
+ return;
+
+ /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
+ the size of instruction may not be correct because
+ it could be relaxable. */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = section_symbol (now_seg);
+ exp.X_add_number = n;
+ fix_new_exp (frag_now,
+ frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
+}
+
+/* Supported Andes machines. */
+struct nds32_machs
+{
+ enum bfd_architecture bfd_mach;
+ int mach_flags;
+};
+
+/* This is the callback for nds32-asm.c to parse operands. */
+
+int
+nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
+ struct nds32_asm_insn *pinsn,
+ char **pstr, int64_t *value)
+{
+ char *hold;
+ expressionS *pexp = pinsn->info;
+
+ hold = input_line_pointer;
+ input_line_pointer = *pstr;
+ expression (pexp);
+ *pstr = input_line_pointer;
+ input_line_pointer = hold;
+
+ switch (pexp->X_op)
+ {
+ case O_symbol:
+ *value = 0;
+ return NASM_R_SYMBOL;
+ case O_constant:
+ *value = pexp->X_add_number;
+ return NASM_R_CONST;
+ case O_illegal:
+ case O_absent:
+ case O_register:
+ default:
+ return NASM_R_ILLEGAL;
+ }
+}
+
+/* GAS will call this function at the start of the assembly, after the command
+ line arguments have been parsed and all the machine independent
+ initializations have been completed. */
+
+void
+md_begin (void)
+{
+ struct nds32_keyword *k;
+ relax_info_t *relax_info;
+
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
+
+ nds32_init_nds32_pseudo_opcodes ();
+ asm_desc.parse_operand = nds32_asm_parse_operand;
+ nds32_asm_init (&asm_desc, 0);
+
+ /* Initial general pupose registers hash table. */
+ nds32_gprs_hash = hash_new ();
+ for (k = keyword_gpr; k->name; k++)
+ hash_insert (nds32_gprs_hash, k->name, k);
+
+ /* Initial branch hash table. */
+ nds32_relax_info_hash = hash_new ();
+ for (relax_info = relax_table; relax_info->opcode; relax_info++)
+ hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info);
+
+ /* Initial relax hint hash table. */
+ nds32_hint_hash = hash_new ();
+ enable_16bit = nds32_16bit_ext;
+}
+
+/* HANDLE_ALIGN in write.c. */
+
+void
+nds32_handle_align (fragS *fragp)
+{
+ static const unsigned char nop16[] = { 0x92, 0x00 };
+ static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
+ int bytes;
+ char *p;
+
+ if (fragp->fr_type != rs_align_code)
+ return;
+
+ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+ p = fragp->fr_literal + fragp->fr_fix;
+
+ if (bytes & 1)
+ {
+ *p++ = 0;
+ bytes--;
+ }
+
+ if (bytes & 2)
+ {
+ expressionS exp_t;
+ exp_t.X_op = O_symbol;
+ exp_t.X_add_symbol = abs_section_sym;
+ exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
+ fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
+ BFD_RELOC_NDS32_INSN16);
+ memcpy (p, nop16, 2);
+ p += 2;
+ bytes -= 2;
+ }
+
+ while (bytes >= 4)
+ {
+ memcpy (p, nop32, 4);
+ p += 4;
+ bytes -= 4;
+ }
+
+ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+ fragp->fr_fix += bytes;
+}
+
+/* md_flush_pending_output */
+
+void
+nds32_flush_pending_output (void)
+{
+ nds32_last_label = NULL;
+}
+
+void
+nds32_frob_label (symbolS *label)
+{
+ dwarf2_emit_label (label);
+}
+
+/* TC_START_LABEL */
+
+int
+nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
+{
+ if (optimize && subseg_text_p (now_seg))
+ label_exist = 1;
+ return 1;
+}
+
+/* TARGET_FORMAT */
+
+const char *
+nds32_target_format (void)
+{
+#ifdef TE_LINUX
+ if (target_big_endian)
+ return "elf32-nds32be-linux";
+ else
+ return "elf32-nds32le-linux";
+#else
+ if (target_big_endian)
+ return "elf32-nds32be";
+ else
+ return "elf32-nds32le";
+#endif
+}
+
+static enum nds32_br_range
+get_range_type (const struct nds32_field *field)
+{
+ gas_assert (field != NULL);
+
+ if (field->bitpos != 0)
+ return BR_RANGE_U4G;
+
+ if (field->bitsize == 24 && field->shift == 1)
+ return BR_RANGE_S16M;
+ else if (field->bitsize == 16 && field->shift == 1)
+ return BR_RANGE_S64K;
+ else if (field->bitsize == 14 && field->shift == 1)
+ return BR_RANGE_S16K;
+ else if (field->bitsize == 8 && field->shift == 1)
+ return BR_RANGE_S256;
+ else
+ return BR_RANGE_U4G;
+}
+
+/* Save pseudo instruction relocation list. */
+
+static struct nds32_relocs_pattern*
+nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
+ char *out, symbolS *sym,
+ struct nds32_relocs_pattern *reloc_ptr,
+ fragS *fragP)
+{
+ if (!reloc_ptr)
+ reloc_ptr = malloc (sizeof (struct nds32_relocs_pattern));
+ reloc_ptr->seg = now_seg;
+ reloc_ptr->sym = sym;
+ reloc_ptr->frag = fragP;
+ reloc_ptr->frchain = frchain_now;
+ reloc_ptr->fixP = fixP;
+ reloc_ptr->opcode = opcode;
+ reloc_ptr->where = out;
+ reloc_ptr->next = NULL;
+ return reloc_ptr;
+}
+
+/* Check X_md to transform relocation. */
+
+static fixS*
+nds32_elf_record_fixup_exp (fragS *fragP, char *str,
+ const struct nds32_field *fld,
+ expressionS *pexp, char* out,
+ struct nds32_asm_insn *insn)
+{
+ int reloc = -1;
+ expressionS exp;
+ fixS *fixP = NULL;
+
+ /* Handle instruction relocation. */
+ if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
+ {
+ /* Relocation for hi20 modifier. */
+ switch (pexp->X_md)
+ {
+ case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
+ reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
+ break;
+ case BFD_RELOC_NDS32_GOT20: /* @GOT */
+ reloc = BFD_RELOC_NDS32_GOT_HI20;
+ break;
+ case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
+ if (!nds32_pic)
+ as_bad (_("Invalid PIC expression."));
+ else
+ reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
+ break;
+ case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
+ reloc = BFD_RELOC_NDS32_GOTPC_HI20;
+ break;
+ case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
+ break;
+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
+ break;
+ default: /* No suffix. */
+ reloc = BFD_RELOC_NDS32_HI20;
+ break;
+ }
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 0 /* pcrel */, reloc);
+ }
+ else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
+ {
+ /* Relocation for lo12 modifier. */
+ if (fld->bitsize == 15 && fld->shift == 0)
+ {
+ /* [ls]bi || ori */
+ switch (pexp->X_md)
+ {
+ case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
+ reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
+ break;
+ case BFD_RELOC_NDS32_GOT20: /* @GOT */
+ reloc = BFD_RELOC_NDS32_GOT_LO12;
+ break;
+ case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
+ if (!nds32_pic)
+ as_bad (_("Invalid PIC expression."));
+ else
+ reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
+ break;
+ case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
+ reloc = BFD_RELOC_NDS32_GOTPC_LO12;
+ break;
+ case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
+ break;
+ default: /* No suffix. */
+ reloc = BFD_RELOC_NDS32_LO12S0;
+ break;
+ }
+ }
+ else if (fld->bitsize == 15 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_LO12S1; /* [ls]hi */
+ else if (fld->bitsize == 15 && fld->shift == 2)
+ {
+ /* [ls]wi */
+ switch (pexp->X_md)
+ {
+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
+ reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
+ break;
+ default: /* No suffix. */
+ reloc = BFD_RELOC_NDS32_LO12S2;
+ break;
+ }
+ }
+ else if (fld->bitsize == 15 && fld->shift == 3)
+ reloc = BFD_RELOC_NDS32_LO12S3; /* [ls]di */
+ else if (fld->bitsize == 12 && fld->shift == 2)
+ reloc = R_NDS32_LO12S2_SP_RELA; /* f[ls][sd]i */
+
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 0 /* pcrel */, reloc);
+ }
+ else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
+ && (insn->attr & NASM_ATTR_PCREL))
+ {
+ /* Relocation for 32-bit branch instructions. */
+ if (fld->bitsize == 24 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_25_PCREL;
+ else if (fld->bitsize == 16 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_17_PCREL;
+ else if (fld->bitsize == 14 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_15_PCREL;
+ else if (fld->bitsize == 8 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
+ else
+ abort ();
+
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 1 /* pcrel */, reloc);
+ }
+ else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
+ && (insn->attr & NASM_ATTR_GPREL))
+ {
+ /* Relocation for 32-bit gp-relative instructions. */
+ if (fld->bitsize == 19 && fld->shift == 0)
+ reloc = BFD_RELOC_NDS32_SDA19S0;
+ else if (fld->bitsize == 18 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_SDA18S1;
+ else if (fld->bitsize == 17 && fld->shift == 2)
+ reloc = BFD_RELOC_NDS32_SDA17S2;
+ else
+ abort ();
+
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 0 /* pcrel */, reloc);
+ /* Insert INSN16 for converting fp_as_gp. */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
+ fix_new_exp (fragP, out - fragP->fr_literal,
+ insn->opcode->isize, &exp, 0 /* pcrel */,
+ BFD_RELOC_NDS32_INSN16);
+ }
+ else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
+ && (insn->attr & NASM_ATTR_PCREL))
+ {
+ /* Relocation for 16-bit branch instructions. */
+ if (fld->bitsize == 8 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_9_PCREL;
+ else
+ abort ();
+
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 1 /* pcrel */, reloc);
+ }
+ else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_IFC_EXT))
+ {
+ /* Relocation for ifcall instruction. */
+ if (insn->opcode->isize == 2 && fld->bitsize == 9 && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_10IFCU_PCREL;
+ else if (insn->opcode->isize == 4 && fld->bitsize == 16
+ && fld->shift == 1)
+ reloc = BFD_RELOC_NDS32_17IFC_PCREL;
+ else
+ abort ();
+
+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
+ insn->info, 1 /* pcrel */, reloc);
+ }
+ else if (fld)
+ as_bad (_("Don't know how to handle this field. %s"), str);
+
+ return fixP;
+}
+
+/* Build instruction pattern to relax. There are two type group pattern
+ including pseudo instruction and relax hint. */
+
+static void
+nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
+ struct nds32_opcode *opcode, fragS *fragP,
+ const struct nds32_field *fld)
+{
+ struct nds32_relocs_pattern *reloc_ptr;
+ struct nds32_relocs_group *group;
+ symbolS *sym = NULL;
+
+ /* The expression may be used uninitialized. */
+ if (fld)
+ sym = pexp->X_add_symbol;
+
+ if (pseudo_opcode)
+ {
+ /* Save instruction relation for pseudo instruction expanding pattern. */
+ reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+ NULL, fragP);
+ if (!relocs_list)
+ relocs_list = reloc_ptr;
+ else
+ {
+ struct nds32_relocs_pattern *temp = relocs_list;
+ while (temp->next)
+ temp = temp->next;
+ temp->next = reloc_ptr;
+ }
+ }
+ else if (nds32_relax_hint_current)
+ {
+ /* Save instruction relation by relax hint. */
+ group = nds32_relax_hint_current;
+ while (group)
+ {
+ nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
+ group->pattern, fragP);
+ group = group->next;
+ free (nds32_relax_hint_current);
+ nds32_relax_hint_current = group;
+ }
+ }
+
+ /* Set relaxing false only for relax_hint trigger it. */
+ if (!pseudo_opcode)
+ relaxing = FALSE;
+}
+
+#define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
+
+/* Relax pattern for link time relaxation. */
+
+static struct nds32_relax_hint_table relax_ls_table[] =
+{
+ {
+ /* Set address: la -> sethi ori. */
+ NDS32_RELAX_HINT_LA, /* main_type */
+ 8, /* relax_code_size */
+ {
+ OP6 (SETHI),
+ OP6 (ORI),
+ }, /* relax_code_seq */
+ {
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+ {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
+ } /* relax_fixup */
+ },
+ {
+ /* Set address: l.w -> sethi ori. */
+ NDS32_RELAX_HINT_LS, /* main_type */
+ 8, /* relax_code_size */
+ {
+ OP6 (SETHI),
+ OP6 (LBI),
+ }, /* relax_code_seq */
+ {
+ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
+ {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
+ } /* relax_fixup */
+ },
+ {
+ 0,
+ 0,
+ {0},
+ {{0, 0 , 0, 0}}
+ }
+};
+
+/* Since sethi loadstore relocation has to using next instruction to determine
+ elimination itself or not, we have to return the next instruction range. */
+
+static int
+nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
+{
+ int range = 0;
+ while (pattern)
+ {
+ switch (pattern->opcode->value)
+ {
+ case INSN_LBI:
+ case INSN_SBI:
+ case INSN_LBSI:
+ case N32_MEM_EXT (N32_MEM_LB):
+ case N32_MEM_EXT (N32_MEM_LBS):
+ case N32_MEM_EXT (N32_MEM_SB):
+ range = NDS32_LOADSTORE_BYTE;
+ break;
+ case INSN_LHI:
+ case INSN_SHI:
+ case INSN_LHSI:
+ case N32_MEM_EXT (N32_MEM_LH):
+ case N32_MEM_EXT (N32_MEM_LHS):
+ case N32_MEM_EXT (N32_MEM_SH):
+ range = NDS32_LOADSTORE_HALF;
+ break;
+ case INSN_LWI:
+ case INSN_SWI:
+ case N32_MEM_EXT (N32_MEM_LW):
+ case N32_MEM_EXT (N32_MEM_SW):
+ range = NDS32_LOADSTORE_WORD;
+ break;
+ case INSN_FLSI:
+ case INSN_FSSI:
+ range = NDS32_LOADSTORE_FLOAT_S;
+ break;
+ case INSN_FLDI:
+ case INSN_FSDI:
+ range = NDS32_LOADSTORE_FLOAT_D;
+ break;
+ case INSN_ORI:
+ range = NDS32_LOADSTORE_IMM;
+ break;
+ default:
+ range = NDS32_LOADSTORE_NONE;
+ break;
+ }
+ if (range != NDS32_LOADSTORE_NONE)
+ break;
+ pattern = pattern->next;
+ }
+ return range;
+}
+
+/* The args means: instruction size, the 1st instruction is converted to 16 or
+ not, optimize option, 16 bit instruction is enable. */
+#define SET_ADDEND(size, convertible, optimize, insn16_on) \
+ (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
+ | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
+
+static void
+nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
+{
+ /* Set E_NDS32_HAS_EXT_INST. */
+ if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
+ {
+ if (nds32_perf_ext)
+ nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
+ else
+ as_bad (_("instruction %s requires enabling performance extension"),
+ insn->opcode->opcode);
+ }
+ else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
+ {
+ if (nds32_perf_ext2)
+ nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
+ else
+ as_bad (_("instruction %s requires enabling performance extension II"),
+ insn->opcode->opcode);
+ }
+ else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
+ {
+ if (nds32_audio_ext)
+ nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
+ else
+ as_bad (_("instruction %s requires enabling AUDIO extension"),
+ insn->opcode->opcode);
+ }
+ else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
+ {
+ if (nds32_string_ext)
+ nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
+ else
+ as_bad (_("instruction %s requires enabling STRING extension"),
+ insn->opcode->opcode);
+ }
+ else if ((insn->opcode->attr & NASM_ATTR_DIV)
+ && (insn->opcode->attr & NASM_ATTR_DXREG))
+ {
+ if (nds32_div && nds32_dx_regs)
+ nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
+ else
+ as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
+ insn->opcode->opcode);
+ }
+ else if (insn->opcode->attr & NASM_ATTR_FPU)
+ {
+ if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
+ {
+ if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
+ nds32_fpu_com = 1;
+ }
+ else
+ as_bad (_("instruction %s requires enabling FPU extension"),
+ insn->opcode->opcode);
+ }
+ else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
+ {
+ if (nds32_fpu_sp_ext)
+ nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
+ else
+ as_bad (_("instruction %s requires enabling FPU_SP extension"),
+ insn->opcode->opcode);
+ }
+ else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
+ && (insn->opcode->attr & NASM_ATTR_MAC))
+ {
+ if (nds32_fpu_sp_ext && nds32_mac)
+ {
+ nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
+ nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
+ }
+ else
+ as_bad (_("instruction %s requires enabling FPU_MAC extension"),
+ insn->opcode->opcode);
+ }
+ else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
+ {
+ if (nds32_fpu_dp_ext)
+ nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
+ else
+ as_bad (_("instruction %s requires enabling FPU_DP extension"),
+ insn->opcode->opcode);
+ }
+ else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
+ && (insn->opcode->attr & NASM_ATTR_MAC))
+ {
+ if (nds32_fpu_dp_ext && nds32_mac)
+ {
+ nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
+ nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
+ }
+ else
+ as_bad (_("instruction %s requires enabling FPU_MAC extension"),
+ insn->opcode->opcode);
+ }
+ /* TODO: FPU_BOTH */
+ else if ((insn->opcode->attr & NASM_ATTR_MAC)
+ && (insn->opcode->attr & NASM_ATTR_DXREG))
+ {
+ if (nds32_mac && nds32_dx_regs)
+ nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
+ else
+ as_bad (_("instruction %s requires enabling DX_REGS extension"),
+ insn->opcode->opcode);
+ }
+ /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
+ else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
+ {
+ nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
+ }
+ /* TODO: E_NDS32_HAS_SATURATION_INST */
+}
+
+/* Flag for analysis relaxation type. */
+
+enum nds32_insn_type
+{
+ N32_RELAX_SETHI = 1,
+ N32_RELAX_BR = (1 << 1),
+ N32_RELAX_LSI = (1 << 2),
+ N32_RELAX_JUMP = (1 << 3),
+ N32_RELAX_CALL = (1 << 4),
+ N32_RELAX_ORI = (1 << 5),
+ N32_RELAX_MEM = (1 << 6),
+ N32_RELAX_MOVI = (1 << 7),
+};
+
+struct nds32_hint_map
+{
+ bfd_reloc_code_real_type hi_type;
+ char *opc;
+ enum nds32_relax_hint_type hint_type;
+ enum nds32_br_range range;
+ enum nds32_insn_type insn_list;
+};
+
+/* Table to match instructions with hint and relax pattern. */
+
+static struct nds32_hint_map hint_map [] =
+{
+ {
+ /* LONGCALL4. */
+ BFD_RELOC_NDS32_HI20,
+ "jal",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_U4G,
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
+ },
+ {
+ /* LONGCALL5. */
+ _dummy_first_bfd_reloc_code_real,
+ "bgezal",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_S16M,
+ N32_RELAX_BR | N32_RELAX_CALL
+ },
+ {
+ /* LONGCALL6. */
+ BFD_RELOC_NDS32_HI20,
+ "bgezal",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_U4G,
+ N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
+ },
+ {
+ /* LONGJUMP4. */
+ BFD_RELOC_NDS32_HI20,
+ "j",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_U4G,
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
+ },
+ {
+ /* LONGJUMP5. */
+ /* There is two kinds of veriation of LONGJUMP5. One of them
+ generate EMPTY relocation for converted INSN16 if needed.
+ But we don't distinguish them here. */
+ _dummy_first_bfd_reloc_code_real,
+ "beq",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_S16M,
+ N32_RELAX_BR | N32_RELAX_JUMP
+ },
+ {
+ /* LONGJUMP6. */
+ BFD_RELOC_NDS32_HI20,
+ "beq",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_U4G,
+ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
+ },
+ {
+ /* LONGJUMP7. */
+ _dummy_first_bfd_reloc_code_real,
+ "beqc",
+ NDS32_RELAX_HINT_NONE,
+ BR_RANGE_S16K,
+ N32_RELAX_MOVI | N32_RELAX_BR
+ },
+ {
+ /* LOADSTORE ADDRESS. */
+ BFD_RELOC_NDS32_HI20,
+ NULL,
+ NDS32_RELAX_HINT_LA,
+ BR_RANGE_U4G,
+ N32_RELAX_SETHI | N32_RELAX_ORI
+ },
+ {
+ /* LOADSTORE ADDRESS. */
+ BFD_RELOC_NDS32_HI20,
+ NULL,
+ NDS32_RELAX_HINT_LS,
+ BR_RANGE_U4G,
+ N32_RELAX_SETHI | N32_RELAX_LSI
+ },
+ {0, NULL, 0, 0 ,0}
+};
+
+/* Find the relaxation pattern according to instructions. */
+
+static bfd_boolean
+nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
+ struct nds32_relax_hint_table *hint_info)
+{
+ unsigned int opcode, seq_size;
+ enum nds32_br_range range;
+ struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
+ char *opc = NULL;
+ relax_info_t *relax_info = NULL;
+ nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
+ enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
+ struct nds32_relax_hint_table *table_ptr;
+ uint32_t *code_seq, *hint_code;
+ enum nds32_insn_type relax_type = 0;
+ struct nds32_hint_map *map_ptr = hint_map;
+ unsigned int i;
+ char *check_insn[] =
+ { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
+
+ /* TODO: PLT GOT. */
+ /* Traverse all pattern instruction and set flag. */
+ pattern = relocs_pattern;
+ while (pattern)
+ {
+ if (pattern->opcode->isize == 4)
+ {
+ /* 4 byte instruction. */
+ opcode = N32_OP6 (pattern->opcode->value);
+ switch (opcode)
+ {
+ case N32_OP6_SETHI:
+ hi_pattern = pattern;
+ relax_type |= N32_RELAX_SETHI;
+ break;
+ case N32_OP6_MEM:
+ relax_type |= N32_RELAX_MEM;
+ break;
+ case N32_OP6_ORI:
+ relax_type |= N32_RELAX_ORI;
+ break;
+ case N32_OP6_BR1:
+ case N32_OP6_BR2:
+ case N32_OP6_BR3:
+ relax_type |= N32_RELAX_BR;
+ break;
+ case N32_OP6_MOVI:
+ relax_type |= N32_RELAX_MOVI;
+ break;
+ case N32_OP6_LBI:
+ case N32_OP6_SBI:
+ case N32_OP6_LBSI:
+ case N32_OP6_LHI:
+ case N32_OP6_SHI:
+ case N32_OP6_LHSI:
+ case N32_OP6_LWI:
+ case N32_OP6_SWI:
+ case N32_OP6_LWC:
+ case N32_OP6_SWC:
+ relax_type |= N32_RELAX_LSI;
+ break;
+ case N32_OP6_JREG:
+ if (__GF (pattern->opcode->value, 0, 1) == 1)
+ relax_type |= N32_RELAX_CALL;
+ else
+ relax_type |= N32_RELAX_JUMP;
+ break;
+ case N32_OP6_JI:
+ if (__GF (pattern->opcode->value, 24, 1) == 1)
+ relax_type |= N32_RELAX_CALL;
+ else
+ relax_type |= N32_RELAX_JUMP;
+ break;
+ default:
+ as_warn (_("relax hint unrecognized instruction: line %d."),
+ pattern->frag->fr_line);
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* 2 byte instruction. Compare by opcode name because the opcode of
+ 2byte instruction is not regular. */
+ for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+ {
+ if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
+ {
+ relax_type |= N32_RELAX_BR;
+ break;
+ }
+ }
+ if (strcmp (pattern->opcode->opcode, "movi55") == 0)
+ relax_type |= N32_RELAX_MOVI;
+ }
+ pattern = pattern->next;
+ }
+
+ /* Analysis instruction flag to choose relaxation table. */
+ while (map_ptr->insn_list != 0)
+ {
+ if (map_ptr->insn_list == relax_type
+ && (!hi_pattern
+ || (hi_pattern->fixP
+ && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
+ {
+ opc = map_ptr->opc;
+ hint_type = map_ptr->hint_type;
+ range = map_ptr->range;
+ break;
+ }
+ map_ptr++;
+ }
+
+ if (map_ptr->insn_list == 0)
+ {
+ as_warn (_("Can not find match relax hint. line : %d"),
+ relocs_pattern->frag->fr_line);
+ return FALSE;
+ }
+
+ /* Get the match table. */
+ if (opc)
+ {
+ /* Branch relax pattern. */
+ relax_info = hash_find (nds32_relax_info_hash, opc);
+ if (!relax_info)
+ return FALSE;
+ fixup_info = relax_info->relax_fixup[range];
+ code_seq = relax_info->relax_code_seq[range];
+ seq_size = relax_info->relax_code_size[range];
+ }
+ else if (hint_type)
+ {
+ /* Load-store relax pattern. */
+ table_ptr = relax_ls_table;
+ while (table_ptr->main_type != 0)
+ {
+ if (table_ptr->main_type == hint_type)
+ {
+ fixup_info = table_ptr->relax_fixup;
+ code_seq = table_ptr->relax_code_seq;
+ seq_size = table_ptr->relax_code_size;
+ break;
+ }
+ table_ptr++;
+ }
+ if (table_ptr->main_type == 0)
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ hint_fixup = hint_info->relax_fixup;
+ hint_code = hint_info->relax_code_seq;
+ hint_info->relax_code_size = seq_size;
+
+ while (fixup_info->size != 0)
+ {
+ if (fixup_info->ramp & NDS32_HINT)
+ {
+ memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
+ hint_fixup++;
+ }
+ fixup_info++;
+ }
+ /* Clear final relocation. */
+ memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
+ /* Copy code sequance. */
+ memcpy (hint_code, code_seq, seq_size);
+ return TRUE;
+}
+
+/* Because there are a lot of variant of load-store, check
+ all these type here. */
+
+#define CLEAN_REG(insn) ((insn) & 0xff0003ff)
+static bfd_boolean
+nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
+{
+ char *check_insn[] =
+ { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
+ uint32_t insn = opcode->value;
+ unsigned int i;
+
+ insn = CLEAN_REG (opcode->value);
+ if (insn == seq)
+ return TRUE;
+
+ switch (seq)
+ {
+ case OP6 (LBI):
+ /* In relocation_table, it regards instruction LBI as representation
+ of all the NDS32_RELAX_HINT_LS pattern. */
+ if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
+ || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
+ || insn == OP6 (LWI) || insn == OP6 (SWI)
+ || insn == OP6 (LWC) || insn == OP6 (SWC))
+ return TRUE;
+ break;
+ case OP6 (BR2):
+ /* This is for LONGCALL5 and LONGCALL6. */
+ if (insn == OP6 (BR2))
+ return TRUE;
+ break;
+ case OP6 (BR1):
+ /* This is for LONGJUMP5 and LONGJUMP6. */
+ if (opcode->isize == 4
+ && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
+ return TRUE;
+ else if (opcode->isize == 2)
+ {
+ for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
+ if (strcmp (opcode->opcode, check_insn[i]) == 0)
+ return TRUE;
+ }
+ break;
+ case OP6 (MOVI):
+ /* This is for LONGJUMP7. */
+ if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Append relax relocation for link time relaxing. */
+
+static void
+nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
+{
+ struct nds32_relocs_pattern *relocs_pattern =
+ (struct nds32_relocs_pattern *) value;
+ struct nds32_relocs_pattern *pattern_temp, *pattern_now;
+ symbolS *sym, *hi_sym = NULL;
+ expressionS exp;
+ fragS *fragP;
+ segT seg_bak = now_seg;
+ frchainS *frchain_bak = frchain_now;
+ struct nds32_relax_hint_table hint_info;
+ nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
+ size_t fixup_size;
+ offsetT branch_offset;
+ fixS *fixP;
+ int range, offset;
+ unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
+ uint32_t *code_seq, code_insn;
+ char *where;
+
+ if (!relocs_pattern)
+ return;
+
+ if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
+ return;
+
+ /* Save symbol for some EMPTY relocation using. */
+ pattern_now = relocs_pattern;
+ while (pattern_now)
+ {
+ if (pattern_now->opcode->value == OP6 (SETHI))
+ {
+ hi_sym = pattern_now->sym;
+ break;
+ }
+ pattern_now = pattern_now->next;
+ }
+
+ /* Inserting fix up must specify now_seg or frchain_now. */
+ now_seg = relocs_pattern->seg;
+ frchain_now = relocs_pattern->frchain;
+ fragP = relocs_pattern->frag;
+ branch_offset = fragP->fr_offset;
+
+ hint_fixup = hint_info.relax_fixup;
+ code_seq = hint_info.relax_code_seq;
+ relax_code_size = hint_info.relax_code_size;
+ pattern_now = relocs_pattern;
+
+ /* Insert relaxation. */
+ exp.X_op = O_symbol;
+
+ while (pattern_now)
+ {
+ /* Choose the match fixup by instruction. */
+ code_insn = CLEAN_REG (*(code_seq + count));
+ if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
+ {
+ count = 0;
+ code_insn = CLEAN_REG (*(code_seq + count));
+
+ while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
+ {
+ count++;
+ if (count >= relax_code_size / 4)
+ {
+ as_bad (_("Internal error: Relax hint error. %s: %x"),
+ now_seg->name, pattern_now->opcode->value);
+ goto restore;
+ }
+ code_insn = CLEAN_REG (*(code_seq + count));
+ }
+ }
+ fragP = pattern_now->frag;
+ sym = pattern_now->sym;
+ branch_offset = fragP->fr_offset;
+ offset = count * 4;
+ where = pattern_now->where;
+ /* Find the instruction map fix. */
+ fixup_now = hint_fixup;
+ while (fixup_now->offset != offset)
+ {
+ fixup_now++;
+ if (fixup_now->size == 0)
+ break;
+ }
+ /* This element is without relaxation relocation. */
+ if (fixup_now->size == 0)
+ {
+ pattern_now = pattern_now->next;
+ continue;
+ }
+ fixup_size = fixup_now->size;
+
+ /* Insert all fixup. */
+ while (fixup_size != 0 && fixup_now->offset == offset)
+ {
+ /* Set the real instruction size in element. */
+ fixup_size = pattern_now->opcode->isize;
+ if (fixup_now->ramp & NDS32_FIX)
+ {
+ /* Convert original relocation. */
+ pattern_now->fixP->fx_r_type = fixup_now->r_type ;
+ fixup_size = 0;
+ }
+ else if ((fixup_now->ramp & NDS32_PTR) != 0)
+ {
+ /* This relocation has to point to another instruction. Make
+ sure each resolved relocation has to be pointed. */
+ pattern_temp = relocs_pattern;
+ /* All instruction in relax_table should be 32-bit. */
+ hint_count = hint_info.relax_code_size / 4;
+ code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
+ while (pattern_temp)
+ {
+ /* Point to every resolved relocation. */
+ if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
+ {
+ ptr_offset =
+ pattern_temp->where - pattern_temp->frag->fr_literal;
+ exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
+ pattern_temp->frag);
+ exp.X_add_number = 0;
+ fixP =
+ fix_new_exp (fragP, where - fragP->fr_literal,
+ fixup_size, &exp, 0, fixup_now->r_type);
+ fixP->fx_addnumber = fixP->fx_offset;
+ }
+ pattern_temp = pattern_temp->next;
+ }
+ fixup_size = 0;
+ }
+ else if (fixup_now->ramp & NDS32_ADDEND)
+ {
+ range = nds32_elf_sethi_range (relocs_pattern);
+ if (range == NDS32_LOADSTORE_NONE)
+ {
+ as_bad (_("Internal error: Range error. %s"), now_seg->name);
+ return;
+ }
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
+ exp.X_add_number |= ((range & 0x3f) << 8);
+ }
+ else if ((fixup_now->ramp & NDS32_ABS) != 0)
+ {
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_now->ramp & NDS32_INSN16) != 0)
+ {
+ if (!enable_16bit)
+ fixup_size = 0;
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_now->ramp & NDS32_SYM) != 0)
+ {
+ /* For EMPTY relocation save the true symbol. */
+ exp.X_add_symbol = hi_sym;
+ exp.X_add_number = branch_offset;
+ }
+ else
+ {
+ exp.X_add_symbol = sym;
+ exp.X_add_number = branch_offset;
+ }
+
+ if (fixup_size != 0)
+ {
+ fixP = fix_new_exp (fragP, where - fragP->fr_literal,
+ fixup_size, &exp, 0, fixup_now->r_type);
+ fixP->fx_addnumber = fixP->fx_offset;
+ }
+ fixup_now++;
+ fixup_size = fixup_now->size;
+ }
+ if (count < relax_code_size / 4)
+ count++;
+ pattern_now = pattern_now->next;
+ }
+
+restore:
+ now_seg = seg_bak;
+ frchain_now = frchain_bak;
+}
+
+/* Check instruction if it can be used for the baseline. */
+
+static bfd_boolean
+nds32_check_insn_available (struct nds32_asm_insn insn, char *str)
+{
+ int attr = insn.attr & ATTR_ALL;
+ static int baseline_isa = 0;
+ /* No isa setting or all isa can use. */
+ if (attr == 0 || attr == ATTR_ALL)
+ return TRUE;
+
+ if (baseline_isa == 0)
+ {
+ /* Map option baseline and instruction attribute. */
+ switch (nds32_baseline)
+ {
+ case ISA_V2:
+ baseline_isa = ATTR (ISA_V2);
+ break;
+ case ISA_V3:
+ baseline_isa = ATTR (ISA_V3);
+ break;
+ case ISA_V3M:
+ baseline_isa = ATTR (ISA_V3M);
+ break;
+ }
+ }
+
+ if ((baseline_isa & attr) == 0)
+ {
+ as_bad (_("Not support instrcution %s in the baseline."), str);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Stub of machine dependent. */
+
+void
+md_assemble (char *str)
+{
+ struct nds32_asm_insn insn;
+ char *out;
+ struct nds32_pseudo_opcode *popcode;
+ const struct nds32_field *fld = NULL;
+ fixS *fixP;
+ uint16_t insn_16;
+ struct nds32_relocs_pattern *relocs_temp;
+ expressionS *pexp;
+ fragS *fragP;
+ int label = label_exist;
+
+ popcode = nds32_lookup_pseudo_opcode (str);
+ /* Note that we need to check 'verbatim' and
+ 'opcode->physical_op'. If the assembly content is generated by
+ compiler and this opcode is a physical instruction, there is no
+ need to perform pseudo instruction expansion/transformation. */
+ if (popcode && !(verbatim && popcode->physical_op))
+ {
+ pseudo_opcode = TRUE;
+ nds32_pseudo_opcode_wrapper (str, popcode);
+ pseudo_opcode = FALSE;
+ nds32_elf_append_relax_relocs (NULL, relocs_list);
+
+ /* Free pseudo list. */
+ relocs_temp = relocs_list;
+ while (relocs_temp)
+ {
+ relocs_list = relocs_list->next;
+ free (relocs_temp);
+ relocs_temp = relocs_list;
+ }
+
+ return;
+ }
+
+ label_exist = 0;
+ insn.info = (expressionS *) alloca (sizeof (expressionS));
+ nds32_assemble (&asm_desc, &insn, str);
+
+ switch (asm_desc.result)
+ {
+ case NASM_ERR_UNKNOWN_OP:
+ as_bad (_("Unrecognized opcode, %s."), str);
+ return;
+ case NASM_ERR_SYNTAX:
+ as_bad (_("Incorrect syntax, %s."), str);
+ return;
+ case NASM_ERR_OPERAND:
+ as_bad (_("Unrecognized operand, %s."), str);
+ return;
+ case NASM_ERR_OUT_OF_RANGE:
+ as_bad (_("Operand out of range, %s."), str);
+ return;
+ case NASM_ERR_REG_REDUCED:
+ as_bad (_("Prohibited register used for reduced-register, %s."), str);
+ return;
+ case NASM_ERR_JUNK_EOL:
+ as_bad (_("Junk at end of line, %s."), str);
+ return;
+ }
+
+ gas_assert (insn.opcode);
+
+ nds32_set_elf_flags_by_insn (&insn);
+
+ gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
+
+ if (!nds32_check_insn_available (insn, str))
+ return;
+
+ /* Make sure the begining of text being 2-byte align. */
+ nds32_adjust_label (1);
+ fld = insn.field;
+ /* Try to allocate the max size to guarantee relaxable same branch
+ instructions in the same fragment. */
+ frag_grow (NDS32_MAXCHAR);
+ fragP = frag_now;
+ if (fld && (insn.attr & NASM_ATTR_BRANCH)
+ && (pseudo_opcode || (insn.opcode->value != INSN_JAL
+ && insn.opcode->value != INSN_J))
+ && (!verbatim || pseudo_opcode))
+ {
+ /* User assembly code branch relax for it. */
+ /* If fld is not NULL, it is a symbol. */
+ /* Branch msut relax to proper pattern in user assembly code exclude
+ J and JAL. Keep these two in original type for users which wants
+ to keep their size be fixed. In general, assembler does not convert
+ instruction generated by compiler. But jump instruction may be
+ truncated in text virtual model. For workaround, compiler generate
+ pseudo jump to fix this issue currently. */
+
+ /* Get branch range type. */
+ dwarf2_emit_insn (0);
+ enum nds32_br_range range_type;
+
+ pexp = insn.info;
+ range_type = get_range_type (fld);
+
+ out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
+ 0, /* VAR is un-used. */
+ range_type, /* SUBTYPE is used as range type. */
+ pexp->X_add_symbol, pexp->X_add_number, 0);
+
+ fragP->fr_fix += insn.opcode->isize;
+ fragP->tc_frag_data.opcode = insn.opcode;
+ fragP->tc_frag_data.insn = insn.insn;
+ if (insn.opcode->isize == 4)
+ bfd_putb32 (insn.insn, out);
+ else if (insn.opcode->isize == 2)
+ bfd_putb16 (insn.insn, out);
+ fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
+ return;
+ /* md_convert_frag will insert relocations. */
+ }
+ else if (!fld && !relaxing && enable_16bit && (optimize || optimize_for_space)
+ && ((!verbatim && insn.opcode->isize == 4
+ && nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
+ || (insn.opcode->isize == 2
+ && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
+ {
+ /* Record this one is relaxable. */
+ dwarf2_emit_insn (0);
+ out = frag_var (rs_machine_dependent,
+ 4, /* Max size is 32-bit instruction. */
+ 0, /* VAR is un-used. */
+ 0, NULL, 0, NULL);
+ fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
+ fragP->tc_frag_data.opcode = insn.opcode;
+ fragP->tc_frag_data.insn = insn.insn;
+ fragP->fr_fix += 2;
+
+ /* In original, we don't relax the instrucion with label on it,
+ but this may cause some redundant nop16. Therefore, tag this
+ relaxable instruction and relax it carefully. */
+ if (label)
+ fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
+
+ if (insn.opcode->isize == 4)
+ bfd_putb16 (insn_16, out);
+ else if (insn.opcode->isize == 2)
+ bfd_putb16 (insn.insn, out);
+ return;
+ }
+ else if ((verbatim || !relaxing) && optimize && label)
+ {
+ /* This instruction is with label. */
+ expressionS exp;
+ out = frag_var (rs_machine_dependent, insn.opcode->isize,
+ 0, 0, NULL, 0, NULL);
+ /* If this insturction is branch target, it is not relaxable. */
+ fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
+ fragP->tc_frag_data.opcode = insn.opcode;
+ fragP->tc_frag_data.insn = insn.insn;
+ fragP->fr_fix += insn.opcode->isize;
+ if (insn.opcode->isize == 4)
+ {
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
+ }
+ }
+ else
+ out = frag_more (insn.opcode->isize);
+
+ if (insn.opcode->isize == 4)
+ bfd_putb32 (insn.insn, out);
+ if (insn.opcode->isize == 2)
+ bfd_putb16 (insn.insn, out);
+
+ dwarf2_emit_insn (insn.opcode->isize);
+
+ /* Compiler generating code and user assembly pseudo load-store, insert
+ fixup here. */
+ pexp = insn.info;
+ fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
+ /* Build relaxation pattern when relaxing is enable. */
+ if (relaxing)
+ nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
+}
+
+/* md_macro_start */
+
+void
+nds32_macro_start (void)
+{
+}
+
+/* md_macro_info */
+
+void
+nds32_macro_info (void *info ATTRIBUTE_UNUSED)
+{
+}
+
+/* md_macro_end */
+
+void
+nds32_macro_end (void)
+{
+}
+
+/* GAS will call this function with one argument, an expressionS pointer, for
+ any expression that can not be recognized. When the function is called,
+ input_line_pointer will point to the start of the expression. */
+
+void
+md_operand (expressionS *expressionP)
+{
+ if (*input_line_pointer == '#')
+ {
+ input_line_pointer++;
+ expression (expressionP);
+ }
+}
+
+/* GAS will call this function for each section at the end of the assembly, to
+ permit the CPU back end to adjust the alignment of a section. The function
+ must take two arguments, a segT for the section and a valueT for the size of
+ the section, and return a valueT for the rounded size. */
+
+valueT
+md_section_align (segT segment, valueT size)
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+/* GAS will call this function when a symbol table lookup fails, before it
+ creates a new symbol. Typically this would be used to supply symbols whose
+ name or value changes dynamically, possibly in a context sensitive way.
+ Predefined symbols with fixed values, such as register names or condition
+ codes, are typically entered directly into the symbol table when md_begin
+ is called. One argument is passed, a char * for the symbol. */
+
+symbolS *
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+static long
+nds32_calc_branch_offset (segT segment, fragS *fragP,
+ long stretch ATTRIBUTE_UNUSED,
+ relax_info_t *relax_info,
+ enum nds32_br_range branch_range_type)
+{
+ struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
+ symbolS *branch_symbol = fragP->fr_symbol;
+ offsetT branch_offset = fragP->fr_offset;
+ offsetT branch_target_address;
+ offsetT branch_insn_address;
+ long offset = 0;
+
+ if ((S_GET_SEGMENT (branch_symbol) != segment)
+ || S_IS_WEAK (branch_symbol))
+ {
+ /* The symbol is not in the SEGMENT. It could be far far away. */
+ offset = 0x80000000;
+ }
+ else
+ {
+ /* Calculate symbol-to-instruction offset. */
+ branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
+ /* If the destination symbol is beyond current frag address,
+ STRETCH will take effect to symbol's position. */
+ if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
+ branch_target_address += stretch;
+
+ branch_insn_address = fragP->fr_address + fragP->fr_fix;
+ branch_insn_address -= opcode->isize;
+
+ /* Update BRANCH_INSN_ADDRESS to relaxed position. */
+ branch_insn_address += (relax_info->relax_code_size[branch_range_type]
+ - relax_info->relax_branch_isize[branch_range_type]);
+
+ offset = branch_target_address - branch_insn_address;
+ }
+
+ return offset;
+}
+
+static enum nds32_br_range
+nds32_convert_to_range_type (long offset)
+{
+ enum nds32_br_range range_type;
+
+ if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
+ range_type = BR_RANGE_S256;
+ else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
+ range_type = BR_RANGE_S16K;
+ else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
+ range_type = BR_RANGE_S64K;
+ else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
+ range_type = BR_RANGE_S16M;
+ else /* 4G bytes */
+ range_type = BR_RANGE_U4G;
+
+ return range_type;
+}
+
+/* Set insntruction register mask. */
+
+static void
+nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
+ uint32_t ori_insn, int range)
+{
+ nds32_cond_field_t *cond_fields = relax_info->cond_field;
+ nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
+ uint32_t mask;
+ int i = 0;
+
+ /* The instruction has conditions. Collect condition values. */
+ while (code_seq_cond[i].bitmask != 0)
+ {
+ if (offset == code_seq_cond[i].offset)
+ {
+ mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
+ /* Sign extend. */
+ if (cond_fields[i].signed_extend)
+ mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
+ ((cond_fields[i].bitmask + 1) >> 1);
+ *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
+ }
+ i++;
+ }
+}
+
+
+static int
+nds32_relax_branch_instructions (segT segment, fragS *fragP,
+ long stretch ATTRIBUTE_UNUSED,
+ int init)
+{
+ enum nds32_br_range branch_range_type;
+ struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
+ long offset = 0;
+ enum nds32_br_range real_range_type;
+ int adjust = 0;
+ relax_info_t *relax_info;
+ int diff = 0;
+ int i, j, k;
+ int code_seq_size;
+ uint32_t *code_seq;
+ uint32_t insn;
+ int insn_size;
+ int code_seq_offset;
+
+ /* Replace with gas_assert (fragP->fr_symbol != NULL); */
+ if (fragP->fr_symbol == NULL)
+ return adjust;
+
+ /* If frag_var is not enough room, the previos frag is fr_full and with
+ opcode. The new one is rs_dependent but without opcode. */
+ if (opcode == NULL)
+ return adjust;
+
+ relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
+
+ if (relax_info == NULL)
+ return adjust;
+
+ if (init)
+ branch_range_type = relax_info->br_range;
+ else
+ branch_range_type = fragP->fr_subtype;
+
+ offset = nds32_calc_branch_offset (segment, fragP, stretch,
+ relax_info, branch_range_type);
+
+ real_range_type = nds32_convert_to_range_type (offset);
+
+ /* If actual range is equal to instruction jump range, do nothing. */
+ if (real_range_type == branch_range_type)
+ return adjust;
+
+ /* Find out proper relaxation code sequence. */
+ for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
+ {
+ if (real_range_type <= (unsigned int) i)
+ {
+ if (init)
+ diff = relax_info->relax_code_size[i] - opcode->isize;
+ else
+ diff = relax_info->relax_code_size[i]
+ - relax_info->relax_code_size[branch_range_type];
+
+ /* If the instruction could be converted to 16-bits,
+ minus the difference. */
+ code_seq_offset = 0;
+ j = 0;
+ k = 0;
+ code_seq_size = relax_info->relax_code_size[i];
+ code_seq = relax_info->relax_code_seq[i];
+ while (code_seq_offset < code_seq_size)
+ {
+ insn = code_seq[j];
+ if (insn & 0x80000000) /* 16-bits instruction. */
+ {
+ insn_size = 2;
+ }
+ else /* 32-bits instruction. */
+ {
+ insn_size = 4;
+
+ while (relax_info->relax_fixup[i][k].size !=0
+ && relax_info->relax_fixup[i][k].offset < code_seq_offset)
+ k++;
+ }
+
+ code_seq_offset += insn_size;
+ j++;
+ }
+
+ /* Update fr_subtype to new NDS32_BR_RANGE. */
+ fragP->fr_subtype = i;
+ break;
+ }
+ }
+
+ return diff + adjust;
+}
+
+/* Adjust relaxable frag till current frag. */
+
+static int
+nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
+{
+ int adj;
+ if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
+ adj = -2;
+ else
+ adj = 2;
+
+ startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
+
+ while (startP)
+ {
+ startP = startP->fr_next;
+ if (startP)
+ {
+ startP->fr_address += adj;
+ if (startP == fragP)
+ break;
+ }
+ }
+ return adj;
+}
+
+static addressT
+nds32_get_align (addressT address, int align)
+{
+ addressT mask, new_address;
+
+ mask = ~((~0) << align);
+ new_address = (address + mask) & (~mask);
+ return (new_address - address);
+}
+
+/* Check the prev_frag is legal. */
+static void
+invalid_prev_frag (fragS * fragP, fragS **prev_frag)
+{
+ addressT address;
+ fragS *frag_start = *prev_frag;
+
+ if (!frag_start)
+ return;
+
+ if (frag_start->last_fr_address >= fragP->last_fr_address)
+ {
+ *prev_frag = NULL;
+ return;
+ }
+
+ fragS *frag_t = *prev_frag;
+ while (frag_t != fragP)
+ {
+ if (frag_t->fr_type == rs_align
+ || frag_t->fr_type == rs_align_code
+ || frag_t->fr_type == rs_align_test)
+ {
+ /* Relax instruction can not walk across lable. */
+ if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ {
+ prev_frag = NULL;
+ return;
+ }
+ /* Relax previos relaxable to align rs_align frag. */
+ address = frag_t->fr_address + frag_t->fr_fix;
+ addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
+ if (offset & 0x2)
+ {
+ /* If there is label on the prev_frag, check if it is aligned. */
+ if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix - 2 )
+ & 0x2) == 0)
+ nds32_adjust_relaxable_frag (*prev_frag, frag_t);
+ }
+ *prev_frag = NULL;
+ return;
+ }
+ frag_t = frag_t->fr_next;
+ }
+}
+
+/* md_relax_frag */
+
+int
+nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
+{
+ /* Currently, there are two kinds of relaxation in nds32 assembler.
+ 1. relax for branch
+ 2. relax for 32-bits to 16-bits */
+
+ static fragS *prev_frag = NULL;
+ int adjust = 0;
+
+ invalid_prev_frag (fragP, &prev_frag);
+
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
+ adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ prev_frag = NULL;
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
+ && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
+ /* Here is considered relaxed case originally. But it may cause
+ unendless loop when relaxing. Once the instruction is relaxed,
+ it can not be undo. */
+ prev_frag = fragP;
+
+ return adjust;
+}
+
+/* This function returns an initial guess of the length by which a fragment
+ must grow to hold a branch to reach its destination. Also updates
+ fr_type/fr_subtype as necessary.
+
+ It is called just before doing relaxation. Any symbol that is now undefined
+ will not become defined. The guess for fr_var is ACTUALLY the growth beyond
+ fr_fix. Whatever we do to grow fr_fix or fr_var contributes to our returned
+ value. Although it may not be explicit in the frag, pretend fr_var starts
+ with a 0 value. */
+
+int
+md_estimate_size_before_relax (fragS *fragP, segT segment)
+{
+ /* Currently, there are two kinds of relaxation in nds32 assembler.
+ 1. relax for branch
+ 2. relax for 32-bits to 16-bits */
+
+ /* Save previos relaxable frag. */
+ static fragS *prev_frag = NULL;
+ int adjust = 0;
+
+ invalid_prev_frag (fragP, &prev_frag);
+
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
+ adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
+ prev_frag = NULL;
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
+ adjust = 2;
+ else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
+ prev_frag = fragP;
+
+ return adjust;
+}
+
+/* GAS will call this for each rs_machine_dependent fragment. The instruction
+ is completed using the data from the relaxation pass. It may also create any
+ necessary relocations.
+
+ *FRAGP has been relaxed to its final size, and now needs to have the bytes
+ inside it modified to conform to the new size. It is called after relaxation
+ is finished.
+
+ fragP->fr_type == rs_machine_dependent.
+ fragP->fr_subtype is the subtype of what the address relaxed to. */
+
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
+{
+ /* Convert branch relaxation instructions. */
+ symbolS *branch_symbol = fragP->fr_symbol;
+ offsetT branch_offset = fragP->fr_offset;
+ enum nds32_br_range branch_range_type = fragP->fr_subtype;
+ struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
+ uint32_t origin_insn = fragP->tc_frag_data.insn;
+ int backup_endian;
+ relax_info_t *relax_info;
+ char *fr_buffer;
+ int fr_where;
+ int addend ATTRIBUTE_UNUSED;
+ offsetT branch_target_address, branch_insn_address;
+ expressionS exp;
+ fixS *fixP;
+ uint32_t *code_seq;
+ uint32_t insn;
+ int code_size, insn_size, offset, fixup_size;
+ int buf_offset;
+ int i, k;
+ uint16_t insn_16;
+ nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
+ /* Save the 1st instruction is converted to 16 bit or not. */
+ unsigned int branch_size;
+
+ /* Replace with gas_assert (branch_symbol != NULL); */
+ if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
+ return;
+
+ /* If frag_var is not enough room, the previos frag is fr_full and with
+ opcode. The new one is rs_dependent but without opcode. */
+ if (opcode == NULL)
+ return;
+
+ /* Relax the insntruction. */
+ if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
+ {
+ expressionS exp_t;
+ if (fragP->tc_frag_data.opcode->isize == 2)
+ {
+ insn_16 = fragP->tc_frag_data.insn;
+ nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
+ }
+ else
+ insn = fragP->tc_frag_data.insn;
+ fragP->fr_fix += 2;
+ fr_where = fragP->fr_fix - 4;
+ fr_buffer = fragP->fr_literal + fr_where;
+ exp_t.X_op = O_symbol;
+ exp_t.X_add_symbol = abs_section_sym;
+ exp_t.X_add_number = 0;
+ fix_new_exp (fragP, fr_where, 4, &exp_t, 0,
+ BFD_RELOC_NDS32_INSN16);
+ number_to_chars_bigendian (fr_buffer, insn, 4);
+ }
+ else
+ {
+ /* Branch instruction adjust and append relocations. */
+ relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
+
+ if (relax_info == NULL)
+ return;
+
+ backup_endian = target_big_endian;
+ target_big_endian = 1;
+
+ fr_where = fragP->fr_fix - opcode->isize;
+ fr_buffer = fragP->fr_literal + fr_where;
+
+ if ((S_GET_SEGMENT (branch_symbol) != sec)
+ || S_IS_WEAK (branch_symbol))
+ {
+ if (fragP->fr_offset & 3)
+ as_warn (_("Addend to unresolved symbol is not on word boundary."));
+ addend = 0;
+ }
+ else
+ {
+ /* Calculate symbol-to-instruction offset. */
+ branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
+ branch_insn_address = fragP->fr_address + fr_where;
+ addend = (branch_target_address - branch_insn_address) >> 1;
+ }
+
+ code_size = relax_info->relax_code_size[branch_range_type];
+ code_seq = relax_info->relax_code_seq[branch_range_type];
+
+ memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
+ sizeof (fixup_info));
+
+ /* Fill in frag. */
+ i = 0;
+ k = 0;
+ offset = 0; /* code_seq offset */
+ buf_offset = 0; /* fr_buffer offset */
+ while (offset < code_size)
+ {
+ insn = code_seq[i];
+ if (insn & 0x80000000) /* 16-bits instruction. */
+ {
+ insn = (insn >> 16) & 0xFFFF;
+ insn_size = 2;
+ }
+ else /* 32-bits instruction. */
+ {
+ insn_size = 4;
+ }
+
+ nds32_elf_get_set_cond (relax_info, offset, &insn,
+ origin_insn, branch_range_type);
+
+ /* Try to convert to 16-bits instruction. Currently, only the first
+ insntruction in pattern can be converted. EX: bnez sethi ori jr,
+ only bnez can be converted to 16 bit and ori can't. */
+
+ while (fixup_info[k].size != 0
+ && relax_info->relax_fixup[branch_range_type][k].offset < offset)
+ k++;
+
+ md_number_to_chars (fr_buffer + buf_offset, insn, insn_size);
+ buf_offset += insn_size;
+
+ offset += insn_size;
+ i++;
+ }
+
+ /* Set up fixup. */
+ exp.X_op = O_symbol;
+
+ for (i = 0; fixup_info[i].size != 0; i++)
+ {
+ fixup_size = fixup_info[i].size;
+
+ if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
+ {
+ /* This is a reverse branch. */
+ exp.X_add_symbol = symbol_temp_new (sec, 0, fragP->fr_next);
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
+ {
+ /* This relocation has to point to another instruction. */
+ branch_size = fr_where + code_size - 4;
+ exp.X_add_symbol = symbol_temp_new (sec, branch_size, fragP);
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
+ {
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
+ {
+ if (!enable_16bit)
+ continue;
+ /* This is a tag relocation. */
+ exp.X_add_symbol = abs_section_sym;
+ exp.X_add_number = 0;
+ }
+ else
+ {
+ exp.X_add_symbol = branch_symbol;
+ exp.X_add_number = branch_offset;
+ }
+
+ if (fixup_info[i].r_type != 0)
+ {
+ fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
+ fixup_size, &exp, 0, fixup_info[i].r_type);
+ fixP->fx_addnumber = fixP->fx_offset;
+ }
+ }
+
+ fragP->fr_fix = fr_where + buf_offset;
+
+ target_big_endian = backup_endian;
+ }
+}
+
+/* tc_frob_file_before_fix */
+
+void
+nds32_frob_file_before_fix (void)
+{
+}
+
+static bfd_boolean
+nds32_relaxable_section (asection *sec)
+{
+ return ((sec->flags & SEC_DEBUGGING) == 0
+ && strcmp (sec->name, ".eh_frame") != 0);
+}
+
+/* TC_FORCE_RELOCATION */
+int
+nds32_force_relocation (fixS * fix)
+{
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_NDS32_INSN16:
+ case BFD_RELOC_NDS32_LABEL:
+ case BFD_RELOC_NDS32_LONGCALL1:
+ case BFD_RELOC_NDS32_LONGCALL2:
+ case BFD_RELOC_NDS32_LONGCALL3:
+ case BFD_RELOC_NDS32_LONGJUMP1:
+ case BFD_RELOC_NDS32_LONGJUMP2:
+ case BFD_RELOC_NDS32_LONGJUMP3:
+ case BFD_RELOC_NDS32_LOADSTORE:
+ case BFD_RELOC_NDS32_9_FIXED:
+ case BFD_RELOC_NDS32_15_FIXED:
+ case BFD_RELOC_NDS32_17_FIXED:
+ case BFD_RELOC_NDS32_25_FIXED:
+ case BFD_RELOC_NDS32_9_PCREL:
+ case BFD_RELOC_NDS32_15_PCREL:
+ case BFD_RELOC_NDS32_17_PCREL:
+ case BFD_RELOC_NDS32_WORD_9_PCREL:
+ case BFD_RELOC_NDS32_10_UPCREL:
+ case BFD_RELOC_NDS32_25_PCREL:
+ case BFD_RELOC_NDS32_MINUEND:
+ case BFD_RELOC_NDS32_SUBTRAHEND:
+ return 1;
+
+ case BFD_RELOC_8:
+ case BFD_RELOC_16:
+ case BFD_RELOC_32:
+ case BFD_RELOC_NDS32_DIFF_ULEB128:
+ /* Linker should handle difference between two symbol. */
+ return fix->fx_subsy != NULL
+ && nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
+ case BFD_RELOC_64:
+ if (fix->fx_subsy)
+ as_bad ("Double word for difference between two symbols "
+ "is not supported across relaxation.");
+ default:
+ ;
+ }
+
+ if (generic_force_reloc (fix))
+ return 1;
+
+ return fix->fx_pcrel;
+}
+
+/* TC_VALIDATE_FIX_SUB */
+
+int
+nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
+{
+ segT sub_symbol_segment;
+
+ /* This code is referred from Xtensa. Check their implementation for
+ details. */
+
+ /* Make sure both symbols are in the same segment, and that segment is
+ "normal" and relaxable. */
+ sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
+ return (sub_symbol_segment == add_symbol_segment
+ && add_symbol_segment != undefined_section);
+}
+
+void
+md_number_to_chars (char *buf, valueT val, int n)
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+/* This function is called to convert an ASCII string into a floating point
+ value in format used by the CPU. */
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ int i;
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+ default:
+ *sizeP = 0;
+ return _("Bad call to md_atof()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+
+ return 0;
+}
+
+/* md_elf_section_change_hook */
+
+void
+nds32_elf_section_change_hook (void)
+{
+}
+
+/* md_cleanup */
+
+void
+nds32_cleanup (void)
+{
+}
+
+/* This function is used to scan leb128 subtraction expressions,
+ and insert fixups for them.
+
+ e.g., .leb128 .L1 - .L0
+
+ These expressions are heavily used in debug information or
+ exception tables. Because relaxation will change code size,
+ we must resolve them in link time. */
+
+static void
+nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, void *xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo = seg_info (sec);
+ struct frag *fragP;
+
+ subseg_set (sec, 0);
+
+ for (fragP = seginfo->frchainP->frch_root;
+ fragP; fragP = fragP->fr_next)
+ {
+ expressionS *exp;
+
+ /* Only unsigned leb128 can be handle. */
+ if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
+ || fragP->fr_symbol == NULL)
+ continue;
+
+ exp = symbol_get_value_expression (fragP->fr_symbol);
+
+ if (exp->X_op != O_subtract)
+ continue;
+
+ fix_new_exp (fragP, fragP->fr_fix, 0,
+ exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
+ }
+}
+
+static void
+nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
+ void *xxx ATTRIBUTE_UNUSED)
+{
+ segment_info_type *seginfo;
+ fragS *fragP;
+ fixS *fixP;
+ expressionS exp;
+ fixS *fixp;
+
+ seginfo = seg_info (sec);
+ if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
+ return;
+ /* If there is no relocation and relax is disabled, it is not necessary to
+ insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization. */
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ if (!fixp->fx_done)
+ break;
+ if (!fixp && !enable_relax_ex9 && !verbatim)
+ return;
+
+ subseg_change (sec, 0);
+
+ /* Set RELAX_ENTRY flags for linker. */
+ fragP = seginfo->frchainP->frch_root;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = section_symbol (sec);
+ exp.X_add_number = 0;
+ if (!enable_relax_relocs)
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
+ else
+ {
+ /* These flags are only enabled when global relax is enabled.
+ Maybe we can check DISABLE_RELAX_FLAG at linke-time,
+ so we set them anyway. */
+ if (enable_relax_ex9)
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
+ if (enable_relax_ifc)
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
+ if (verbatim)
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
+ }
+ if (optimize)
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
+ if (optimize_for_space)
+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
+
+ fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
+ fixP->fx_no_overflow = 1;
+}
+
+/* Analysis relax hint and insert suitable relocation pattern. */
+
+static void
+nds32_elf_analysis_relax_hint (void)
+{
+ hash_traverse (nds32_hint_hash, nds32_elf_append_relax_relocs);
+}
+
+void
+md_end (void)
+{
+ nds32_elf_analysis_relax_hint ();
+ bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
+}
+
+/* Implement md_allow_local_subtract. */
+
+bfd_boolean
+nds32_allow_local_subtract (expressionS *expr_l ATTRIBUTE_UNUSED,
+ expressionS *expr_r ATTRIBUTE_UNUSED,
+ segT sec ATTRIBUTE_UNUSED)
+{
+ /* Don't allow any subtraction, because relax may change the code. */
+ return FALSE;
+}
+
+/* Sort relocation by address.
+
+ We didn't use qsort () in stdlib, because quick-sort is not a stable
+ sorting algorithm. Relocations at the same address (r_offset) must keep
+ their relative order. For example, RELAX_ENTRY must be the very first
+ relocation entry.
+
+ Currently, this function implements insertion-sort. */
+
+static int
+compar_relent (const void *lhs, const void *rhs)
+{
+ const arelent **l = (const arelent **) lhs;
+ const arelent **r = (const arelent **) rhs;
+
+ if ((*l)->address > (*r)->address)
+ return 1;
+ else if ((*l)->address == (*r)->address)
+ return 0;
+ else
+ return -1;
+}
+
+/* SET_SECTION_RELOCS ()
+
+ Although this macro is originally used to set a relocation for each section,
+ we use it to sort relocations in the same section by the address of the
+ relocation. */
+
+void
+nds32_set_section_relocs (asection *sec, arelent ** relocs ATTRIBUTE_UNUSED,
+ unsigned int n ATTRIBUTE_UNUSED)
+{
+ bfd *abfd ATTRIBUTE_UNUSED = sec->owner;
+ if (bfd_get_section_flags (abfd, sec) & (flagword) SEC_RELOC)
+ nds32_insertion_sort (sec->orelocation, sec->reloc_count,
+ sizeof (arelent**), compar_relent);
+}
+
+long
+nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
+{
+ if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
+ || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
+ {
+ /* Let linker resolve undefined symbols. */
+ return 0;
+ }
+
+ return fixP->fx_frag->fr_address + fixP->fx_where;
+}
+
+/* md_post_relax_hook ()
+ Insert relax entry relocation into sections. */
+
+void
+nds32_post_relax_hook (void)
+{
+ bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
+}
+
+/* tc_fix_adjustable ()
+
+ Return whether this symbol (fixup) can be replaced with
+ section symbols. */
+
+bfd_boolean
+nds32_fix_adjustable (fixS *fixP)
+{
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_NDS32_WORD_9_PCREL:
+ case BFD_RELOC_NDS32_9_PCREL:
+ case BFD_RELOC_NDS32_15_PCREL:
+ case BFD_RELOC_NDS32_17_PCREL:
+ case BFD_RELOC_NDS32_25_PCREL:
+ case BFD_RELOC_NDS32_HI20:
+ case BFD_RELOC_NDS32_LO12S0:
+ case BFD_RELOC_8:
+ case BFD_RELOC_16:
+ case BFD_RELOC_32:
+ case BFD_RELOC_NDS32_PTR:
+ case BFD_RELOC_NDS32_LONGCALL4:
+ case BFD_RELOC_NDS32_LONGCALL5:
+ case BFD_RELOC_NDS32_LONGCALL6:
+ case BFD_RELOC_NDS32_LONGJUMP4:
+ case BFD_RELOC_NDS32_LONGJUMP5:
+ case BFD_RELOC_NDS32_LONGJUMP6:
+ case BFD_RELOC_NDS32_LONGJUMP7:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* elf_tc_final_processing */
+
+void
+elf_nds32_final_processing (void)
+{
+ /* An FPU_COM instruction is found without previous non-FPU_COM
+ instruction. */
+ if (nds32_fpu_com
+ && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
+ {
+ /* Since only FPU_COM instructions are used and no other FPU instructions
+ are used. The nds32_elf_flags will be decided by the enabled options
+ by command line or default configuration. */
+ if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
+ {
+ nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
+ nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
+ }
+ else
+ {
+ /* Should never here. */
+ as_bad (_("Used FPU instructions requires enabling FPU extension"));
+ }
+ }
+
+ if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
+ {
+ /* Single/double FPU has been used, set FPU register config. */
+ /* We did not check the actual number of register used. We may
+ want to do it while assemble. */
+ nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
+ nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
+ }
+
+ if (nds32_pic)
+ nds32_elf_flags |= E_NDS32_HAS_PIC;
+
+ if (nds32_gpr16)
+ nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
+
+ nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
+ elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
+}
+
+/* Implement md_apply_fix. Apply the fix-up or tranform the fix-up for
+ later relocation generation. */
+
+void
+nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+{
+ char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ bfd_vma value = *valP;
+
+ if (fixP->fx_r_type < BFD_RELOC_UNUSED
+ && fixP->fx_r_type > BFD_RELOC_NONE
+ && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
+ {
+ /* In our old nds32 binutils, it must convert relocations which is
+ generated by CGEN. However, it does not have to consider this anymore.
+ In current, it only deal with data relocations which enum
+ is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
+ It is believed that we can construct a better mechanism to
+ deal with the whole relocation issue in nds32 target
+ without using CGEN. */
+ fixP->fx_addnumber = value;
+ fixP->tc_fix_data = NULL;
+
+ /* Tranform specific relocations here for later relocation generation.
+ Tag data here for ex9 relaxtion and tag tls data for linker. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_NDS32_DATA:
+ if (!enable_relax_ex9)
+ fixP->fx_done = 1;
+ break;
+ case BFD_RELOC_NDS32_TPOFF:
+ case BFD_RELOC_NDS32_TLS_LE_HI20:
+ case BFD_RELOC_NDS32_TLS_LE_LO12:
+ case BFD_RELOC_NDS32_TLS_LE_ADD:
+ case BFD_RELOC_NDS32_TLS_LE_LS:
+ case BFD_RELOC_NDS32_GOTTPOFF:
+ case BFD_RELOC_NDS32_TLS_IE_HI20:
+ case BFD_RELOC_NDS32_TLS_IE_LO12S2:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ fixP->fx_done = 1;
+
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ {
+ /* HOW DIFF RELOCATION WORKS.
+
+ First of all, this relocation is used to calculate the distance
+ between two symbols in the SAME section. It is used for jump-
+ table, debug information, exception table, et al. Therefore,
+ it is a unsigned positive value. It is NOT used for general-
+ purpose arithmetic.
+
+ Consider this example, the distance between .LEND and .LBEGIN
+ is stored at the address of foo.
+
+ ---- >8 ---- >8 ---- >8 ---- >8 ----
+ .data
+ foo:
+ .word .LBEGIN - .LEND
+
+ .text
+ [before]
+ .LBEGIN
+ \
+ [between] distance
+ /
+ .LEND
+ [after]
+ ---- 8< ---- 8< ---- 8< ---- 8< ----
+
+ We use a single relocation entry for this expression.
+ * The initial distance value is stored direcly in that location
+ specified by r_offset (i.e., foo in this example.)
+ * The begin of the region, i.e., .LBEGIN, is specified by
+ r_info/R_SYM and r_addend, e.g., .text + 0x32.
+ * The end of region, i.e., .LEND, is represented by
+ .LBEGIN + distance instead of .LEND, so we only need
+ a single relocation entry instead of two.
+
+ When an instruction is relaxed, we adjust the relocation entry
+ depending on where the instruction locates. There are three
+ cases, before, after and between the region.
+ * between: Distance value is read from r_offset, adjusted and
+ written back into r_offset.
+ * before: Only r_addend is adjust.
+ * after: We don't care about it.
+
+ Hereby, there are some limitation.
+
+ `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
+ are semantically different, and we cannot handle latter case
+ when relaxation.
+
+ The latter expression means subtracting 1 from the distance
+ between .LEND and .LBEGIN. And the former expression means
+ the distance between (.LEND - 1) and .LBEGIN.
+
+ The nuance affects whether to adjust distance value when relax
+ an instruction. In another words, whether the instruction
+ locates in the region. Because we use a single relocation entry,
+ there is no field left for .LEND and the subtrahend.
+
+ Since GCC-4.5, GCC may produce debug information in such expression
+ .long .L1-1-.L0
+ in order to describe register clobbering during an function-call.
+ .L0:
+ call foo
+ .L1:
+
+ Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
+ for details. */
+
+ value -= S_GET_VALUE (fixP->fx_subsy);
+ *valP = value;
+ fixP->fx_subsy = NULL;
+ fixP->fx_offset -= value;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
+ md_number_to_chars (where, value, 1);
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
+ md_number_to_chars (where, value, 2);
+ break;
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
+ md_number_to_chars (where, value, 4);
+ break;
+ case BFD_RELOC_NDS32_DIFF_ULEB128:
+ /* cvt_frag_to_fill () has called output_leb128 () for us. */
+ break;
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("expression too complex"));
+ return;
+ }
+ }
+ else if (fixP->fx_done)
+ {
+ /* We're finished with this fixup. Install it because
+ bfd_install_relocation won't be called to do it. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ md_number_to_chars (where, value, 1);
+ break;
+ case BFD_RELOC_16:
+ md_number_to_chars (where, value, 2);
+ break;
+ case BFD_RELOC_32:
+ md_number_to_chars (where, value, 4);
+ break;
+ case BFD_RELOC_64:
+ md_number_to_chars (where, value, 8);
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Internal error: Unknown fixup type %d (`%s')"),
+ fixP->fx_r_type,
+ bfd_get_reloc_code_name (fixP->fx_r_type));
+ break;
+ }
+ }
+}
+
+/* Implement tc_gen_reloc. Generate ELF relocation for a fix-up. */
+
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
+{
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
+ reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
+
+ code = fixP->fx_r_type;
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("internal error: can't export reloc type %d (`%s')"),
+ fixP->fx_r_type, bfd_get_reloc_code_name (code));
+ return NULL;
+ }
+
+ /* Add relocation handling here. */
+
+ switch (fixP->fx_r_type)
+ {
+ default:
+ /* In general, addend of a relocation is the offset to the
+ associated symbol. */
+ reloc->addend = fixP->fx_offset;
+ break;
+
+ case BFD_RELOC_NDS32_DATA:
+ /* Prevent linker from optimizing data in text sections.
+ For example, jump table. */
+ reloc->addend = fixP->fx_size;
+ break;
+ }
+
+ return reloc;
+}
+
+struct suffix_name suffix_table[] =
+{
+ {"GOTOFF", BFD_RELOC_NDS32_GOTOFF, 1},
+ {"GOT", BFD_RELOC_NDS32_GOT20, 1},
+ {"TPOFF", BFD_RELOC_NDS32_TPOFF, 0},
+ {"PLT", BFD_RELOC_NDS32_25_PLTREL, 1},
+ {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF, 0}
+};
+
+/* Implement md_parse_name. */
+
+int
+nds32_parse_name (char const *name, expressionS *exprP,
+ enum expr_mode mode ATTRIBUTE_UNUSED,
+ char *nextcharP ATTRIBUTE_UNUSED)
+{
+ exprP->X_op_symbol = NULL;
+ exprP->X_md = BFD_RELOC_UNUSED;
+
+ exprP->X_add_symbol = symbol_find_or_make (name);
+ exprP->X_op = O_symbol;
+ exprP->X_add_number = 0;
+
+ if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
+ {
+ /* Set for _GOT_OFFSET_TABLE_. */
+ exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
+ }
+ else if (*nextcharP == '@')
+ {
+ size_t i;
+ char *next;
+ for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
+ {
+ next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
+ if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
+ strlen (suffix_table[i].suffix)) == 0
+ && !is_part_of_name (*next))
+ {
+ if (!nds32_pic && suffix_table[i].pic)
+ as_bad (_("need PIC qualifier with symbol."));
+ exprP->X_md = suffix_table[i].reloc;
+ *input_line_pointer = *nextcharP;
+ input_line_pointer = next;
+ *nextcharP = *input_line_pointer;
+ *input_line_pointer = '\0';
+ break;
+ }
+ }
+ }
+ return 1;
+}
+
+/* Implement tc_regname_to_dw2regnum. */
+
+int
+tc_nds32_regname_to_dw2regnum (char *regname)
+{
+ struct nds32_keyword *sym = hash_find (nds32_gprs_hash, regname);
+
+ if (!sym)
+ return -1;
+
+ return sym->value;
+}
+
+void
+tc_nds32_frame_initial_instructions (void)
+{
+ /* CIE */
+ /* Default cfa is register-31/sp. */
+ cfi_add_CFA_def_cfa (31, 0);
+}
diff --git a/binutils-2.25/gas/config/tc-nds32.h b/binutils-2.25/gas/config/tc-nds32.h
new file mode 100644
index 00000000..1483d51f
--- /dev/null
+++ b/binutils-2.25/gas/config/tc-nds32.h
@@ -0,0 +1,281 @@
+/* tc-nds32.h -- Header file for tc-nds32.c.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of GAS.
+
+ 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef TC_NDS32
+#define TC_NDS32
+
+#include "bfd_stdint.h"
+
+#define LISTING_HEADER \
+ (target_big_endian ? "NDS32 GAS" : "NDS32 GAS Little Endian")
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_nds32
+
+/* mapping to mach_table[5] */
+#define ISA_V1 bfd_mach_n1h
+#define ISA_V2 bfd_mach_n1h_v2
+#define ISA_V3 bfd_mach_n1h_v3
+#define ISA_V3M bfd_mach_n1h_v3m
+
+/* Default to big endian. Please note that for Andes architecture,
+ instructions are always in big-endian format. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
+
+/* as.c. */
+/* Extend GAS command line option handling capability. */
+extern int nds32_parse_option (int, char *);
+extern void nds32_after_parse_args (void);
+/* The endianness of the target format may change based on command
+ line arguments. */
+extern const char * nds32_target_format (void);
+
+#define md_parse_option(optc, optarg) nds32_parse_option (optc, optarg)
+#define md_after_parse_args() nds32_after_parse_args ()
+#define TARGET_FORMAT nds32_target_format()
+
+/* expr.c */
+extern int nds32_parse_name (char const *, expressionS *, enum expr_mode, char *);
+extern bfd_boolean nds32_allow_local_subtract (expressionS *, expressionS *, segT);
+#define md_parse_name(name, exprP, mode, nextcharP) \
+ nds32_parse_name (name, exprP, mode, nextcharP)
+#define md_allow_local_subtract(lhs,rhs,sect) nds32_allow_local_subtract (lhs, rhs, sect)
+
+/* dwarf2dbg.c. */
+#define DWARF2_USE_FIXED_ADVANCE_PC 1
+
+/* write.c. */
+extern long nds32_pcrel_from_section (struct fix *, segT);
+extern bfd_boolean nds32_fix_adjustable (struct fix *);
+extern void nds32_frob_file (void);
+extern void nds32_post_relax_hook (void);
+extern void nds32_frob_file_before_fix (void);
+extern void elf_nds32_final_processing (void);
+extern int nds32_validate_fix_sub (struct fix *, segT);
+extern int nds32_force_relocation (struct fix *);
+extern void nds32_set_section_relocs (asection *, arelent ** , unsigned int);
+
+/* Fill in rs_align_code fragments. TODO: Review this. */
+extern void nds32_handle_align (fragS *);
+extern int nds32_relax_frag (segT, fragS *, long);
+extern int tc_nds32_regname_to_dw2regnum (char *);
+extern void tc_nds32_frame_initial_instructions (void);
+
+#define MD_PCREL_FROM_SECTION(fix, sect) nds32_pcrel_from_section (fix, sect)
+#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 0
+#define tc_fix_adjustable(FIX) nds32_fix_adjustable (FIX)
+#define md_apply_fix(fixP, addn, seg) nds32_apply_fix (fixP, addn, seg)
+#define md_post_relax_hook nds32_post_relax_hook ()
+#define tc_frob_file_before_fix() nds32_frob_file_before_fix ()
+#define elf_tc_final_processing() elf_nds32_final_processing ()
+/* For DIFF relocations. The default behavior is inconsistent with the
+ asm internal document. */
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
+ (! SEG_NORMAL (SEC) || TC_FORCE_RELOCATION (FIX))
+#define TC_FORCE_RELOCATION(fix) nds32_force_relocation (fix)
+#define TC_VALIDATE_FIX_SUB(FIX,SEG) nds32_validate_fix_sub (FIX,SEG)
+#define SET_SECTION_RELOCS(sec, relocs, n) nds32_set_section_relocs (sec, relocs, n)
+/* Values passed to md_apply_fix don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+#define HANDLE_ALIGN(f) nds32_handle_align (f)
+#undef DIFF_EXPR_OK /* They should be fixed in linker. */
+#define md_relax_frag(segment, fragP, stretch) nds32_relax_frag (segment, fragP, stretch)
+#define WORKING_DOT_WORD /* We don't need to handle .word strangely. */
+/* Using to chain fixup with previous fixup. */
+#define TC_FIX_TYPE struct fix *
+#define TC_INIT_FIX_DATA(fixP) \
+ do \
+ { \
+ fixP->tc_fix_data = NULL; \
+ } \
+ while (0)
+
+/* read.c. */
+/* Extend GAS macro handling capability. */
+extern void nds32_macro_start (void);
+extern void nds32_macro_end (void);
+extern void nds32_macro_info (void *);
+extern void nds32_start_line_hook (void);
+extern void nds32_elf_section_change_hook (void);
+extern void md_begin (void);
+extern void md_end (void);
+extern int nds32_start_label (int, int);
+extern void nds32_cleanup (void);
+extern void nds32_flush_pending_output (void);
+extern void nds32_cons_align (int);
+extern void nds32_check_label (symbolS *);
+extern void nds32_frob_label (symbolS *);
+extern void nds32_pre_do_align (int, char *, int, int);
+extern void nds32_do_align (int);
+
+#define md_macro_start() nds32_macro_start ()
+#define md_macro_end() nds32_macro_end ()
+#define md_macro_info(args) nds32_macro_info (args)
+#define TC_START_LABEL(C, S, STR) (C == ':' && nds32_start_label (0, 0))
+#define tc_check_label(label) nds32_check_label (label)
+#define tc_frob_label(label) nds32_frob_label (label)
+#define md_end md_end
+#define md_start_line_hook() nds32_start_line_hook ()
+#define md_cons_align(n) nds32_cons_align (n)
+/* COLE: TODO: Review md_do_align. */
+#define md_do_align(N, FILL, LEN, MAX, LABEL) \
+ nds32_pre_do_align (N, FILL, LEN, MAX); \
+ if ((N) > 1 && (subseg_text_p (now_seg) \
+ || strncmp (now_seg->name, ".gcc_except_table", sizeof(".gcc_except_table") - 1) == 0)) \
+ nds32_do_align (N); \
+ goto LABEL;
+#define md_elf_section_change_hook() nds32_elf_section_change_hook ()
+#define md_flush_pending_output() nds32_flush_pending_output ()
+#define md_cleanup() nds32_cleanup ()
+#define LOCAL_LABELS_FB 1 /* Permit temporary numeric labels. */
+
+/* frags.c. */
+
+#define NDS32_FRAG_RELAXABLE 0x1
+#define NDS32_FRAG_RELAXED 0x2
+#define NDS32_FRAG_BRANCH 0x4
+#define NDS32_FRAG_LABEL 0x8
+
+struct nds32_frag_type
+{
+ relax_substateT flag;
+ struct nds32_opcode *opcode;
+ uint32_t insn;
+ /* To Save previos label fixup if existence. */
+ struct fix *fixup;
+};
+
+extern void nds32_frag_init (fragS *);
+
+#define TC_FRAG_TYPE struct nds32_frag_type
+#define TC_FRAG_INIT(fragP) nds32_frag_init (fragP)
+
+/* CFI directive. */
+extern void nds32_elf_frame_initial_instructions (void);
+extern int tc_nds32_regname_to_dw2regnum (char *);
+
+#define TARGET_USE_CFIPOP 1
+#define DWARF2_DEFAULT_RETURN_COLUMN 30
+#define DWARF2_CIE_DATA_ALIGNMENT -4
+#define DWARF2_LINE_MIN_INSN_LENGTH 2
+
+#define tc_regname_to_dw2regnum tc_nds32_regname_to_dw2regnum
+#define tc_cfi_frame_initial_instructions tc_nds32_frame_initial_instructions
+
+/* COLE: TODO: Review These. They seem to be obsoleted. */
+#if 1
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy)))
+#define TC_HANDLES_FX_DONE
+/* This arranges for gas/write.c to not apply a relocation if
+ obj_fix_adjustable() says it is not adjustable. */
+#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP)
+#endif
+
+/* Because linker may relax the code, assemble-time expression
+ optimization is not allowed. */
+#define md_allow_eh_opt 0
+
+/* For nds32 relax. */
+enum nds32_br_range
+{
+ BR_RANGE_S256 = 0,
+ BR_RANGE_S16K,
+ BR_RANGE_S64K,
+ BR_RANGE_S16M,
+ BR_RANGE_U4G,
+ BR_RANGE_NUM
+};
+
+enum nds32_ramp
+{
+ NDS32_CREATE_LABEL = 1,
+ NDS32_RELAX = (1 << 1), /* Obsolete in the future. */
+ NDS32_ORIGIN = (1 << 2),
+ NDS32_INSN16 = (1 << 3),
+ NDS32_PTR = (1 << 4),
+ NDS32_ABS = (1 << 5),
+ NDS32_HINT = (1 << 6),
+ NDS32_FIX = (1 << 7),
+ NDS32_ADDEND = (1 << 8),
+ NDS32_SYM = (1 << 9)
+};
+
+typedef struct nds32_relax_fixup_info
+{
+ int offset;
+ int size;
+ /* Reverse branch has to jump to the end of instruction pattern. */
+ int ramp;
+ enum bfd_reloc_code_real r_type;
+} nds32_relax_fixup_info_t;
+
+typedef struct nds32_cond_field
+{
+ int offset;
+ int bitpos; /* Register position. */
+ int bitmask; /* Number of register bits. */
+ bfd_boolean signed_extend;
+} nds32_cond_field_t;
+
+/* The max relaxation pattern is 20-bytes including the nop. */
+#define NDS32_MAXCHAR 20
+/* In current, the max entend number of instruction for one pseudo instruction
+ is 4, but its number of relocation may be 12. */
+#define MAX_RELAX_NUM 4
+#define MAX_RELAX_FIX 12
+
+typedef struct nds32_relax_info
+{
+ /* Opcode for the instruction. */
+ const char *opcode;
+ enum nds32_br_range br_range;
+ nds32_cond_field_t cond_field[MAX_RELAX_NUM]; /* TODO: Reuse nds32_field? */
+ /* Code sequences for different branch range. */
+ uint32_t relax_code_seq[BR_RANGE_NUM][MAX_RELAX_NUM];
+ nds32_cond_field_t relax_code_condition[BR_RANGE_NUM][MAX_RELAX_NUM];
+ unsigned int relax_code_size[BR_RANGE_NUM];
+ int relax_branch_isize[BR_RANGE_NUM];
+ nds32_relax_fixup_info_t relax_fixup[BR_RANGE_NUM][MAX_RELAX_FIX];
+} relax_info_t;
+
+enum nds32_relax_hint_type
+{
+ NDS32_RELAX_HINT_NONE = 0,
+ NDS32_RELAX_HINT_LA,
+ NDS32_RELAX_HINT_LS
+};
+
+struct nds32_relax_hint_table
+{
+ enum nds32_relax_hint_type main_type;
+ unsigned int relax_code_size;
+ uint32_t relax_code_seq[MAX_RELAX_NUM];
+ nds32_relax_fixup_info_t relax_fixup[MAX_RELAX_FIX];
+};
+
+#endif /* TC_NDS32 */
diff --git a/binutils-2.25/gas/config/tc-nios2.c b/binutils-2.25/gas/config/tc-nios2.c
index 08b7aece..21f42886 100644
--- a/binutils-2.25/gas/config/tc-nios2.c
+++ b/binutils-2.25/gas/config/tc-nios2.c
@@ -1,5 +1,5 @@
/* Altera Nios II assembler.
- Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
Contributed by Nigel Gray (ngray@altera.com).
Contributed by Mentor Graphics, Inc.
@@ -1164,6 +1164,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|| fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_LE16
|| fixP->fx_r_type == BFD_RELOC_NIOS2_GOTOFF
|| fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPREL
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL26_NOAT
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT_LO
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT_HA
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL_LO
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL_HA
/* Add other relocs here as we generate them. */
));
@@ -1300,21 +1305,28 @@ struct nios2_special_relocS
bfd_reloc_code_real_type reloc_type;
};
+/* This table is sorted so that prefix strings are listed after the longer
+ strings that include them -- e.g., %got after %got_hiadj, etc. */
+
struct nios2_special_relocS nios2_special_reloc[] = {
{"%hiadj", BFD_RELOC_NIOS2_HIADJ16},
{"%hi", BFD_RELOC_NIOS2_HI16},
{"%lo", BFD_RELOC_NIOS2_LO16},
{"%gprel", BFD_RELOC_NIOS2_GPREL},
+ {"%call_lo", BFD_RELOC_NIOS2_CALL_LO},
+ {"%call_hiadj", BFD_RELOC_NIOS2_CALL_HA},
{"%call", BFD_RELOC_NIOS2_CALL16},
{"%gotoff_lo", BFD_RELOC_NIOS2_GOTOFF_LO},
{"%gotoff_hiadj", BFD_RELOC_NIOS2_GOTOFF_HA},
+ {"%gotoff", BFD_RELOC_NIOS2_GOTOFF},
+ {"%got_hiadj", BFD_RELOC_NIOS2_GOT_HA},
+ {"%got_lo", BFD_RELOC_NIOS2_GOT_LO},
+ {"%got", BFD_RELOC_NIOS2_GOT16},
{"%tls_gd", BFD_RELOC_NIOS2_TLS_GD16},
{"%tls_ldm", BFD_RELOC_NIOS2_TLS_LDM16},
{"%tls_ldo", BFD_RELOC_NIOS2_TLS_LDO16},
{"%tls_ie", BFD_RELOC_NIOS2_TLS_IE16},
{"%tls_le", BFD_RELOC_NIOS2_TLS_LE16},
- {"%gotoff", BFD_RELOC_NIOS2_GOTOFF},
- {"%got", BFD_RELOC_NIOS2_GOT16}
};
#define NIOS2_NUM_SPECIAL_RELOCS \
@@ -1595,7 +1607,10 @@ nios2_assemble_args_m (nios2_insn_infoS *insn_info)
unsigned long immed
= nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
insn_info->insn_reloc,
- BFD_RELOC_NIOS2_CALL26, 0);
+ (nios2_as_options.noat
+ ? BFD_RELOC_NIOS2_CALL26_NOAT
+ : BFD_RELOC_NIOS2_CALL26),
+ 0);
SET_INSN_FIELD (IMM26, insn_info->insn_code, immed);
nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
@@ -1991,6 +2006,7 @@ nios2_consume_arg (nios2_insn_infoS *insn, char *argstr, const char *parsestr)
as_bad (_("badly formed expression near %s"), argstr);
break;
case 'o':
+ case 'E':
break;
default:
BAD_CASE (*parsestr);
@@ -2728,7 +2744,10 @@ md_assemble (char *op_str)
&& !nios2_as_options.noat
&& insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL
&& insn->insn_reloc
- && insn->insn_reloc->reloc_type == BFD_RELOC_NIOS2_CALL26)
+ && ((insn->insn_reloc->reloc_type
+ == BFD_RELOC_NIOS2_CALL26)
+ || (insn->insn_reloc->reloc_type
+ == BFD_RELOC_NIOS2_CALL26_NOAT)))
output_call (insn);
else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ANDI)
output_andi (insn);
@@ -2817,7 +2836,12 @@ nios2_fix_adjustable (fixS *fixp)
|| fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPMOD
|| fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPREL
|| fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_TPREL
- || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF)
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_GOT_LO
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_GOT_HA
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL_LO
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL_HA
+ )
return 0;
return 1;
@@ -2980,12 +3004,10 @@ nios2_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
}
/* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) */
-static int nios2_tls_ldo_reloc;
-
-void
+bfd_reloc_code_real_type
nios2_cons (expressionS *exp, int size)
{
- nios2_tls_ldo_reloc = 0;
+ bfd_reloc_code_real_type nios2_tls_ldo_reloc = BFD_RELOC_NONE;
SKIP_WHITESPACE ();
if (input_line_pointer[0] == '%')
@@ -2998,10 +3020,10 @@ nios2_cons (expressionS *exp, int size)
else
{
input_line_pointer += 8;
- nios2_tls_ldo_reloc = 1;
+ nios2_tls_ldo_reloc = BFD_RELOC_NIOS2_TLS_DTPREL;
}
}
- if (nios2_tls_ldo_reloc)
+ if (nios2_tls_ldo_reloc != BFD_RELOC_NONE)
{
SKIP_WHITESPACE ();
if (input_line_pointer[0] != '(')
@@ -3043,26 +3065,9 @@ nios2_cons (expressionS *exp, int size)
}
}
}
- if (!nios2_tls_ldo_reloc)
+ if (nios2_tls_ldo_reloc == BFD_RELOC_NONE)
expression (exp);
-}
-
-/* Implement TC_CONS_FIX_NEW. */
-void
-nios2_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
- expressionS *exp)
-{
- bfd_reloc_code_real_type r;
-
- r = (nbytes == 1 ? BFD_RELOC_8
- : (nbytes == 2 ? BFD_RELOC_16
- : (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
-
- if (nios2_tls_ldo_reloc)
- r = BFD_RELOC_NIOS2_TLS_DTPREL;
-
- fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
- nios2_tls_ldo_reloc = 0;
+ return nios2_tls_ldo_reloc;
}
/* Implement HANDLE_ALIGN. */
diff --git a/binutils-2.25/gas/config/tc-nios2.h b/binutils-2.25/gas/config/tc-nios2.h
index 9e691941..82bb6247 100644
--- a/binutils-2.25/gas/config/tc-nios2.h
+++ b/binutils-2.25/gas/config/tc-nios2.h
@@ -1,5 +1,5 @@
/* Definitions for Altera Nios II assembler.
- Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
Contributed by Nigel Gray (ngray@altera.com).
Contributed by Mentor Graphics, Inc.
@@ -107,11 +107,7 @@ extern flagword nios2_elf_section_flags (flagword, int, int);
#define CFI_DIFF_EXPR_OK 0
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) nios2_cons (EXP, NBYTES)
-extern void nios2_cons (expressionS *exp, int size);
-
-#define TC_CONS_FIX_NEW nios2_cons_fix_new
-extern void nios2_cons_fix_new (struct frag *frag, int where,
- unsigned int nbytes, struct expressionS *exp);
+extern bfd_reloc_code_real_type nios2_cons (expressionS *exp, int size);
/* We want .cfi_* pseudo-ops for generating unwind info. */
#define TARGET_USE_CFIPOP 1
diff --git a/binutils-2.25/gas/config/tc-ns32k.c b/binutils-2.25/gas/config/tc-ns32k.c
index 709a9bc1..1c97d434 100644
--- a/binutils-2.25/gas/config/tc-ns32k.c
+++ b/binutils-2.25/gas/config/tc-ns32k.c
@@ -1,7 +1,5 @@
/* ns32k.c -- Assemble on the National Semiconductor 32k series
- Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -2183,7 +2181,8 @@ void
cons_fix_new_ns32k (fragS *frag, /* Which frag? */
int where, /* Where in that frag? */
int size, /* 1, 2 or 4 usually. */
- expressionS *exp) /* Expression. */
+ expressionS *exp, /* Expression. */
+ bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
{
fix_new_ns32k_exp (frag, where, size, exp,
0, 2, 0, 0, 0, 0);
diff --git a/binutils-2.25/gas/config/tc-ns32k.h b/binutils-2.25/gas/config/tc-ns32k.h
index 0ee53e55..02d71966 100644
--- a/binutils-2.25/gas/config/tc-ns32k.h
+++ b/binutils-2.25/gas/config/tc-ns32k.h
@@ -1,6 +1,5 @@
/* tc-ns32k.h -- Opcode table for National Semi 32k processor
- Copyright 1987, 1992, 1993, 1994, 1995, 1997, 2000, 2002, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -55,7 +54,8 @@ extern int md_pcrel_adjust (fragS *);
#define ARG_LEN 50
#define TC_CONS_FIX_NEW cons_fix_new_ns32k
-extern void cons_fix_new_ns32k (fragS *, int, int, expressionS *);
+extern void cons_fix_new_ns32k (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
/* The NS32x32 has a non 0 nop instruction which should be used in aligns. */
#define NOP_OPCODE 0xa2
diff --git a/binutils-2.25/gas/config/tc-openrisc.h b/binutils-2.25/gas/config/tc-openrisc.h
deleted file mode 100644
index c1b0ea15..00000000
--- a/binutils-2.25/gas/config/tc-openrisc.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* tc-openrisc.h -- Header file for tc-openrisc.c.
- Copyright 2001, 2002, 2003, 2005, 2007 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 3, 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, 51 Franklin Street - Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-#define TC_OPENRISC
-
-#define LISTING_HEADER "OpenRISC GAS "
-
-/* The target BFD architecture. */
-#define TARGET_ARCH bfd_arch_openrisc
-
-extern unsigned long openrisc_machine;
-#define TARGET_MACH (openrisc_machine)
-
-#define TARGET_FORMAT "elf32-openrisc"
-#define TARGET_BYTES_BIG_ENDIAN 1
-
-extern const char openrisc_comment_chars [];
-#define tc_comment_chars openrisc_comment_chars
-
-/* Permit temporary numeric labels. */
-#define LOCAL_LABELS_FB 1
-
-#define DIFF_EXPR_OK 1 /* .-foo gets turned into PC relative relocs */
-
-/* We don't need to handle .word strangely. */
-#define WORKING_DOT_WORD
-
-/* Values passed to md_apply_fix don't include the symbol value. */
-#define MD_APPLY_SYM_VALUE(FIX) 0
-
-#define md_apply_fix gas_cgen_md_apply_fix
-
-extern bfd_boolean openrisc_fix_adjustable (struct fix *);
-#define tc_fix_adjustable(FIX) openrisc_fix_adjustable (FIX)
-
-#define tc_gen_reloc gas_cgen_tc_gen_reloc
-
-/* Call md_pcrel_from_section(), not md_pcrel_from(). */
-extern long md_pcrel_from_section (struct fix *, segT);
-#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC)
-
-/* For 8 vs 16 vs 32 bit branch selection. */
-extern const struct relax_type md_relax_table[];
-#define TC_GENERIC_RELAX_TABLE md_relax_table
diff --git a/binutils-2.25/gas/config/tc-openrisc.c b/binutils-2.25/gas/config/tc-or1k.c
index 981cdfb6..7b479ca5 100644
--- a/binutils-2.25/gas/config/tc-openrisc.c
+++ b/binutils-2.25/gas/config/tc-or1k.c
@@ -1,7 +1,6 @@
-/* tc-openrisc.c -- Assembler for the OpenRISC family.
- Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009
- Free Software Foundation.
- Contributed by Johan Rydberg, jrydberg@opencores.org
+/* tc-or1k.c -- Assembler for the OpenRISC family.
+ Copyright 2001-2014 Free Software Foundation.
+ Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org
This file is part of GAS, the GNU Assembler.
@@ -16,26 +15,25 @@
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, 51 Franklin Street - Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
+ along with this program; if not, see <http://www.gnu.org/licenses/> */
#include "as.h"
+#include "safe-ctype.h"
#include "subsegs.h"
#include "symcat.h"
-#include "opcodes/openrisc-desc.h"
-#include "opcodes/openrisc-opc.h"
+#include "opcodes/or1k-desc.h"
+#include "opcodes/or1k-opc.h"
#include "cgen.h"
+#include "elf/or1k.h"
+#include "dw2gencfi.h"
/* Structure to hold all of the different components describing
an individual instruction. */
-typedef struct openrisc_insn openrisc_insn;
-struct openrisc_insn
+typedef struct
{
- const CGEN_INSN * insn;
- const CGEN_INSN * orig_insn;
- CGEN_FIELDS fields;
+ const CGEN_INSN * insn;
+ const CGEN_INSN * orig_insn;
+ CGEN_FIELDS fields;
#if CGEN_INT_INSN_P
CGEN_INSN_INT buffer [1];
#define INSN_VALUE(buf) (*(buf))
@@ -43,13 +41,13 @@ struct openrisc_insn
unsigned char buffer [CGEN_MAX_INSN_SIZE];
#define INSN_VALUE(buf) (buf)
#endif
- char * addr;
- fragS * frag;
+ char * addr;
+ fragS * frag;
int num_fixups;
fixS * fixups [GAS_CGEN_MAX_FIXUPS];
int indices [MAX_OPERAND_INSTANCES];
-};
-
+}
+or1k_insn;
const char comment_chars[] = "#";
const char line_comment_chars[] = "#";
@@ -57,9 +55,8 @@ const char line_separator_chars[] = ";";
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";
-
-#define OPENRISC_SHORTOPTS "m:"
-const char * md_shortopts = OPENRISC_SHORTOPTS;
+#define OR1K_SHORTOPTS "m:"
+const char * md_shortopts = OR1K_SHORTOPTS;
struct option md_longopts[] =
{
@@ -67,7 +64,7 @@ struct option md_longopts[] =
};
size_t md_longopts_size = sizeof (md_longopts);
-unsigned long openrisc_machine = 0; /* default */
+unsigned long or1k_machine = 0; /* default */
int
md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
@@ -86,30 +83,38 @@ ignore_pseudo (int val ATTRIBUTE_UNUSED)
discard_rest_of_line ();
}
-const char openrisc_comment_chars [] = ";#";
+static bfd_boolean nodelay = FALSE;
+static void
+s_nodelay (int val ATTRIBUTE_UNUSED)
+{
+ nodelay = TRUE;
+}
+
+const char or1k_comment_chars [] = ";#";
/* The target specific pseudo-ops which we support. */
const pseudo_typeS md_pseudo_table[] =
{
+ { "align", s_align_bytes, 0 },
{ "word", cons, 4 },
{ "proc", ignore_pseudo, 0 },
{ "endproc", ignore_pseudo, 0 },
- { NULL, NULL, 0 }
+ { "nodelay", s_nodelay, 0 },
+ { NULL, NULL, 0 }
};
-
void
md_begin (void)
{
/* Initialize the `cgen' interface. */
/* Set the machine number and endian. */
- gas_cgen_cpu_desc = openrisc_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
+ gas_cgen_cpu_desc = or1k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
CGEN_CPU_OPEN_ENDIAN,
CGEN_ENDIAN_BIG,
CGEN_CPU_OPEN_END);
- openrisc_cgen_init_asm (gas_cgen_cpu_desc);
+ or1k_cgen_init_asm (gas_cgen_cpu_desc);
/* This is a callback from cgen to gas to parse operands. */
cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
@@ -119,13 +124,13 @@ void
md_assemble (char * str)
{
static int last_insn_had_delay_slot = 0;
- openrisc_insn insn;
+ or1k_insn insn;
char * errmsg;
/* Initialize GAS's cgen interface for a new instruction. */
gas_cgen_init_parse ();
- insn.insn = openrisc_cgen_assemble_insn
+ insn.insn = or1k_cgen_assemble_insn
(gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
if (!insn.insn)
@@ -136,10 +141,11 @@ md_assemble (char * str)
/* Doesn't really matter what we pass for RELAX_P here. */
gas_cgen_finish_insn (insn.insn, insn.buffer,
- CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
+ CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
last_insn_had_delay_slot
= CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
+ (void) last_insn_had_delay_slot;
}
@@ -169,10 +175,8 @@ md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
return 0;
}
-
-/* Interface to relax_segment. */
-/* FIXME: Look through this. */
+/* Interface to relax_segment. */
const relax_typeS md_relax_table[] =
{
@@ -186,71 +190,14 @@ const relax_typeS md_relax_table[] =
each list. */
{1, 1, 0, 0},
- /* The displacement used by GAS is from the end of the 2 byte insn,
- so we subtract 2 from the following. */
- /* 16 bit insn, 8 bit disp -> 10 bit range.
- This doesn't handle a branch in the right slot at the border:
- the "& -4" isn't taken into account. It's not important enough to
- complicate things over it, so we subtract an extra 2 (or + 2 in -ve
- case). */
- {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
- /* 32 bit insn, 24 bit disp -> 26 bit range. */
- {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
- /* Same thing, but with leading nop for alignment. */
- {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
+ /* The displacement used by GAS is from the end of the 4 byte insn,
+ so we subtract 4 from the following. */
+ {(((1 << 25) - 1) << 2) - 4, -(1 << 25) - 4, 0, 0},
};
-/* Return an initial guess of the length by which a fragment must grow to
- hold a branch to reach its destination.
- Also updates fr_type/fr_subtype as necessary.
-
- Called just before doing relaxation.
- Any symbol that is now undefined will not become defined.
- The guess for fr_var is ACTUALLY the growth beyond fr_fix.
- Whatever we do to grow fr_fix or fr_var contributes to our returned value.
- Although it may not be explicit in the frag, pretend fr_var starts with a
- 0 value. */
-
int
-md_estimate_size_before_relax (fragS * fragP, segT segment)
+md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
{
- /* The only thing we have to handle here are symbols outside of the
- current segment. They may be undefined or in a different segment in
- which case linker scripts may place them anywhere.
- However, we can't finish the fragment here and emit the reloc as insn
- alignment requirements may move the insn about. */
-
- if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
- {
- /* The symbol is undefined in this segment.
- Change the relaxation subtype to the max allowable and leave
- all further handling to md_convert_frag. */
- fragP->fr_subtype = 2;
-
- {
- const CGEN_INSN * insn;
- int i;
-
- /* Update the recorded insn.
- Fortunately we don't have to look very far.
- FIXME: Change this to record in the instruction the next higher
- relaxable insn to use. */
- for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
- {
- if ((strcmp (CGEN_INSN_MNEMONIC (insn),
- CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
- == 0)
- && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
- break;
- }
- if (i == 4)
- abort ();
-
- fragP->fr_cgen.insn = insn;
- return 2;
- }
- }
-
return md_relax_table[fragP->fr_subtype].rlx_length;
}
@@ -263,13 +210,13 @@ md_estimate_size_before_relax (fragS * fragP, segT segment)
void
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
- segT sec ATTRIBUTE_UNUSED,
- fragS * fragP ATTRIBUTE_UNUSED)
+ segT sec ATTRIBUTE_UNUSED,
+ fragS * fragP ATTRIBUTE_UNUSED)
{
/* FIXME */
}
-
+
/* Functions concerning relocs. */
/* The location from which a PC relative jump should be calculated,
@@ -280,12 +227,16 @@ md_pcrel_from_section (fixS * fixP, segT sec)
{
if (fixP->fx_addsy != (symbolS *) NULL
&& (! S_IS_DEFINED (fixP->fx_addsy)
- || S_GET_SEGMENT (fixP->fx_addsy) != sec))
- /* The symbol is undefined (or is defined but not in this section).
- Let the linker figure it out. */
- return 0;
+ || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
+ || S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy)))
+ {
+ /* The symbol is undefined (or is defined but not in this section).
+ Let the linker figure it out. */
+ return 0;
+ }
- return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;
+ return fixP->fx_frag->fr_address + fixP->fx_where;
}
@@ -295,40 +246,23 @@ md_pcrel_from_section (fixS * fixP, segT sec)
bfd_reloc_code_real_type
md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
- const CGEN_OPERAND * operand,
- fixS * fixP)
+ const CGEN_OPERAND * operand,
+ fixS * fixP)
{
- bfd_reloc_code_real_type type;
+ if (fixP->fx_cgen.opinfo)
+ return fixP->fx_cgen.opinfo;
switch (operand->type)
{
- case OPENRISC_OPERAND_ABS_26:
- fixP->fx_pcrel = 0;
- type = BFD_RELOC_OPENRISC_ABS_26;
- goto emit;
- case OPENRISC_OPERAND_DISP_26:
+ case OR1K_OPERAND_DISP26:
fixP->fx_pcrel = 1;
- type = BFD_RELOC_OPENRISC_REL_26;
- goto emit;
-
- case OPENRISC_OPERAND_HI16:
- type = BFD_RELOC_HI16;
- goto emit;
+ return BFD_RELOC_OR1K_REL_26;
- case OPENRISC_OPERAND_LO16:
- type = BFD_RELOC_LO16;
- goto emit;
-
- emit:
- return type;
-
- default : /* avoid -Wall warning */
- break;
+ default: /* avoid -Wall warning */
+ return BFD_RELOC_NONE;
}
-
- return BFD_RELOC_NONE;
}
-
+
/* Write a value out to the object file, using the appropriate endianness. */
void
@@ -339,10 +273,9 @@ md_number_to_chars (char * buf, valueT val, int n)
/* Turn a string in input_line_pointer into a floating point constant of type
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
- emitted is stored in *sizeP . An error message is returned, or NULL on OK.
-*/
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK. */
-/* Equal to MAX_PRECISION in atof-ieee.c */
+/* Equal to MAX_PRECISION in atof-ieee.c. */
#define MAX_LITTLENUMS 6
char *
@@ -352,12 +285,78 @@ md_atof (int type, char * litP, int * sizeP)
}
bfd_boolean
-openrisc_fix_adjustable (fixS * fixP)
+or1k_fix_adjustable (fixS * fixP)
{
/* We need the symbol name for the VTABLE entries. */
if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
- return 0;
+ return FALSE;
+
+ return TRUE;
+}
+
+#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
+
+arelent *
+tc_gen_reloc (asection *sec, fixS *fx)
+{
+ bfd_reloc_code_real_type code = fx->fx_r_type;
+
+ if (fx->fx_addsy != NULL
+ && strcmp (S_GET_NAME (fx->fx_addsy), GOT_NAME) == 0
+ && (code == BFD_RELOC_OR1K_GOTPC_HI16
+ || code == BFD_RELOC_OR1K_GOTPC_LO16))
+ {
+ arelent * reloc;
+
+ reloc = xmalloc (sizeof (* reloc));
+ reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fx->fx_addsy);
+ reloc->address = fx->fx_frag->fr_address + fx->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fx->fx_r_type);
+ reloc->addend = fx->fx_offset;
+ return reloc;
+ }
+
+ return gas_cgen_tc_gen_reloc (sec, fx);
+}
+
+void
+or1k_apply_fix (struct fix *f, valueT *t, segT s)
+{
+ gas_cgen_md_apply_fix (f, t, s);
+
+ switch (f->fx_r_type)
+ {
+ case BFD_RELOC_OR1K_TLS_GD_HI16:
+ case BFD_RELOC_OR1K_TLS_GD_LO16:
+ case BFD_RELOC_OR1K_TLS_LDM_HI16:
+ case BFD_RELOC_OR1K_TLS_LDM_LO16:
+ case BFD_RELOC_OR1K_TLS_LDO_HI16:
+ case BFD_RELOC_OR1K_TLS_LDO_LO16:
+ case BFD_RELOC_OR1K_TLS_IE_HI16:
+ case BFD_RELOC_OR1K_TLS_IE_LO16:
+ case BFD_RELOC_OR1K_TLS_LE_HI16:
+ case BFD_RELOC_OR1K_TLS_LE_LO16:
+ S_SET_THREAD_LOCAL (f->fx_addsy);
+ break;
+ default:
+ break;
+ }
+}
- return 1;
+void
+or1k_elf_final_processing (void)
+{
+ if (nodelay)
+ elf_elfheader (stdoutput)->e_flags |= EF_OR1K_NODELAY;
}
+
+/* Standard calling conventions leave the CFA at SP on entry. */
+
+void
+or1k_cfi_frame_initial_instructions (void)
+{
+ cfi_add_CFA_def_cfa_register (1);
+}
+
diff --git a/binutils-2.25/gas/config/tc-or1k.h b/binutils-2.25/gas/config/tc-or1k.h
new file mode 100644
index 00000000..18e22a5d
--- /dev/null
+++ b/binutils-2.25/gas/config/tc-or1k.h
@@ -0,0 +1,79 @@
+/* tc-or1k.h -- Header file for tc-or1k.c.
+ Copyright 2001-2014 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 3, 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 this program; if not, see <http://www.gnu.org/licenses/> */
+
+#define TC_OR1K
+
+#define LISTING_HEADER "Or1k GAS "
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_or1k
+
+extern unsigned long or1k_machine;
+#define TARGET_MACH (or1k_machine)
+
+#define TARGET_FORMAT "elf32-or1k"
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+extern const char or1k_comment_chars [];
+#define tc_comment_chars or1k_comment_chars
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK 1 /* .-foo gets turned into PC relative relocs. */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+/* Values passed to md_apply_fix don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define md_apply_fix or1k_apply_fix
+extern void or1k_apply_fix (struct fix *, valueT *, segT);
+
+extern bfd_boolean or1k_fix_adjustable (struct fix *);
+#define tc_fix_adjustable(FIX) or1k_fix_adjustable (FIX)
+
+/* Call md_pcrel_from_section(), not md_pcrel_from(). */
+extern long md_pcrel_from_section (struct fix *, segT);
+#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC)
+
+/* For 8 vs 16 vs 32 bit branch selection. */
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+#define GAS_CGEN_PCREL_R_TYPE(r_type) gas_cgen_pcrel_r_type(r_type)
+
+#define elf_tc_final_processing or1k_elf_final_processing
+void or1k_elf_final_processing (void);
+
+/* Enable cfi directives. */
+#define TARGET_USE_CFIPOP 1
+
+/* Stack grows to lower addresses and wants 4 byte boundary. */
+#define DWARF2_CIE_DATA_ALIGNMENT -4
+
+/* Define the column that represents the PC. */
+#define DWARF2_DEFAULT_RETURN_COLUMN 9
+
+/* or1k instructions are 4 bytes long. */
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+
+#define tc_cfi_frame_initial_instructions \
+ or1k_cfi_frame_initial_instructions
+extern void or1k_cfi_frame_initial_instructions (void);
diff --git a/binutils-2.25/gas/config/tc-or32.c b/binutils-2.25/gas/config/tc-or32.c
deleted file mode 100644
index 23e44af1..00000000
--- a/binutils-2.25/gas/config/tc-or32.c
+++ /dev/null
@@ -1,967 +0,0 @@
-/* Assembly backend for the OpenRISC 1000.
- Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010, 2012
- Free Software Foundation, Inc.
- Contributed by Damjan Lampret <lampret@opencores.org>.
- Modified bu Johan Rydberg, <johan.rydberg@netinsight.se>.
- Based upon a29k port.
-
- 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 3, 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, 51 Franklin Street - Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* tc-a29k.c used as a template. */
-
-#include "as.h"
-#include "safe-ctype.h"
-#include "opcode/or32.h"
-#include "elf/or32.h"
-
-#define DEBUG 0
-
-#ifndef REGISTER_PREFIX
-#define REGISTER_PREFIX '%'
-#endif
-
-/* Make it easier to clone this machine desc into another one. */
-#define machine_opcode or32_opcode
-#define machine_opcodes or32_opcodes
-#define machine_ip or32_ip
-#define machine_it or32_it
-
-/* Handle of the OPCODE hash table. */
-static struct hash_control *op_hash = NULL;
-
-struct machine_it
-{
- char * error;
- unsigned long opcode;
- struct nlist * nlistp;
- expressionS exp;
- int pcrel;
- int reloc_offset; /* Offset of reloc within insn. */
- int reloc;
-}
-the_insn;
-
-const pseudo_typeS md_pseudo_table[] =
-{
- {"align", s_align_bytes, 4 },
- {"space", s_space, 0 },
- {"cputype", s_ignore, 0 },
- {"reg", s_lsym, 0 }, /* Register equate, same as equ. */
- {"sect", s_ignore, 0 }, /* Creation of coff sections. */
- {"proc", s_ignore, 0 }, /* Start of a function. */
- {"endproc", s_ignore, 0 }, /* Function end. */
- {"word", cons, 4 },
- {NULL, 0, 0 },
-};
-
-int md_short_jump_size = 4;
-int md_long_jump_size = 4;
-
-/* This array holds the chars that always start a comment.
- If the pre-processor is disabled, these aren't very useful. */
-const char comment_chars[] = "#";
-
-/* This array holds the chars that only start a comment at the beginning of
- a line. If the line seems to have the form '# 123 filename'
- .line and .file directives will appear in the pre-processed output. */
-/* Note that input_file.c hand checks for '#' at the beginning of the
- first line of the input file. This is because the compiler outputs
- #NO_APP at the beginning of its output. */
-/* Also note that comments like this one will always work. */
-const char line_comment_chars[] = "#";
-
-/* We needed an unused char for line separation to work around the
- lack of macros, using sed and such. */
-const char line_separator_chars[] = ";";
-
-/* Chars that can be used to separate mant from exp in floating point nums. */
-const char EXP_CHARS[] = "eE";
-
-/* Chars that mean this number is a floating point constant.
- As in 0f12.456
- or 0d1.2345e12. */
-const char FLT_CHARS[] = "rRsSfFdDxXpP";
-
-/* "l.jalr r9" precalculated opcode. */
-static unsigned long jalr_r9_opcode;
-
-static void machine_ip (char *);
-
-
-/* Set bits in machine opcode according to insn->encoding
- description and passed operand. */
-
-static void
-encode (const struct machine_opcode *insn,
- unsigned long *opcode,
- signed long param_val,
- char param_ch)
-{
- int opc_pos = 0;
- int param_pos = 0;
- char *enc;
-
-#if DEBUG
- printf (" encode: opcode=%.8lx param_val=%.8lx abs=%.8lx param_ch=%c\n",
- *opcode, param_val, abs (param_val), param_ch);
-#endif
- for (enc = insn->encoding; *enc != '\0'; enc++)
- if (*enc == param_ch)
- {
- if (enc - 2 >= insn->encoding && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
- continue;
- else
- param_pos ++;
- }
-
- opc_pos = 32;
-
- for (enc = insn->encoding; *enc != '\0';)
- {
- if ((*enc == '0') && (*(enc + 1) == 'x'))
- {
- int tmp = strtol (enc, NULL, 16);
-
- opc_pos -= 4;
- *opcode |= tmp << opc_pos;
- enc += 3;
- }
- else if ((*enc == '0') || (*enc == '-'))
- {
- opc_pos--;
- enc++;
- }
- else if (*enc == '1')
- {
- opc_pos--;
- *opcode |= 1 << opc_pos;
- enc++;
- }
- else if (*enc == param_ch)
- {
- opc_pos--;
- param_pos--;
- *opcode |= ((param_val >> param_pos) & 0x1) << opc_pos;
- enc++;
- }
- else if (ISALPHA (*enc))
- {
- opc_pos--;
- enc++;
- }
- else
- enc++;
- }
-
-#if DEBUG
- printf (" opcode=%.8lx\n", *opcode);
-#endif
-}
-
-/* This function is called once, at assembler startup time. It should
- set up all the tables, etc., that the MD part of the assembler will
- need. */
-
-void
-md_begin (void)
-{
- const char *retval = NULL;
- int lose = 0;
- int skipnext = 0;
- unsigned int i;
-
- /* Hash up all the opcodes for fast use later. */
- op_hash = hash_new ();
-
- for (i = 0; i < or32_num_opcodes; i++)
- {
- const char *name = machine_opcodes[i].name;
-
- if (skipnext)
- {
- skipnext = 0;
- continue;
- }
-
- retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]);
- if (retval != NULL)
- {
- fprintf (stderr, "internal error: can't hash `%s': %s\n",
- machine_opcodes[i].name, retval);
- lose = 1;
- }
- }
-
- if (lose)
- as_fatal (_("Broken assembler. No assembly attempted."));
-
- encode (&machine_opcodes[insn_index ("l.jalr")], &jalr_r9_opcode, 9, 'B');
-}
-
-/* Returns non zero if instruction is to be used. */
-
-static int
-check_invalid_opcode (unsigned long opcode)
-{
- return opcode == jalr_r9_opcode;
-}
-
-/* Assemble a single instruction. Its label has already been handled
- by the generic front end. We just parse opcode and operands, and
- produce the bytes of data and relocation. */
-
-void
-md_assemble (char *str)
-{
- char *toP;
-
-#if DEBUG
- printf ("NEW INSTRUCTION\n");
-#endif
-
- know (str);
- machine_ip (str);
- toP = frag_more (4);
-
- /* Put out the opcode. */
- md_number_to_chars (toP, the_insn.opcode, 4);
-
- /* Put out the symbol-dependent stuff. */
- if (the_insn.reloc != BFD_RELOC_NONE)
- {
- fix_new_exp (frag_now,
- (toP - frag_now->fr_literal + the_insn.reloc_offset),
- 4, /* size */
- &the_insn.exp,
- the_insn.pcrel,
- the_insn.reloc);
- }
-}
-
-/* This is true of the we have issued a "lo(" or "hi"(. */
-static int waiting_for_shift = 0;
-
-static int mask_or_shift = 0;
-
-static char *
-parse_operand (char *s, expressionS *operandp, int opt)
-{
- char *save = input_line_pointer;
- char *new_pointer;
-
-#if DEBUG
- printf (" PROCESS NEW OPERAND(%s) == %c (%d)\n", s, opt ? opt : '!', opt);
-#endif
-
- input_line_pointer = s;
-
- if (strncasecmp (s, "HI(", 3) == 0)
- {
- waiting_for_shift = 1;
- mask_or_shift = BFD_RELOC_HI16;
-
- input_line_pointer += 3;
- }
- else if (strncasecmp (s, "LO(", 3) == 0)
- {
- mask_or_shift = BFD_RELOC_LO16;
-
- input_line_pointer += 3;
- }
- else
- mask_or_shift = 0;
-
- if ((*s == '(') && (*(s+1) == 'r'))
- s++;
-
- if ((*s == 'r') && ISDIGIT (*(s + 1)))
- {
- operandp->X_add_number = strtol (s + 1, NULL, 10);
- operandp->X_op = O_register;
- for (; (*s != ',') && (*s != '\0');)
- s++;
- input_line_pointer = save;
- return s;
- }
-
- expression (operandp);
-
- if (operandp->X_op == O_absent)
- {
- if (! opt)
- as_bad (_("missing operand"));
- else
- {
- operandp->X_add_number = 0;
- operandp->X_op = O_constant;
- }
- }
-
- new_pointer = input_line_pointer;
- input_line_pointer = save;
-
-#if DEBUG
- printf (" %s=parse_operand(%s): operandp->X_op = %u\n", new_pointer, s,
- operandp->X_op);
-#endif
-
- return new_pointer;
-}
-
-/* Instruction parsing. Takes a string containing the opcode.
- Operands are at input_line_pointer. Output is in the_insn.
- Warnings or errors are generated. */
-
-static void
-machine_ip (char *str)
-{
- char *s;
- const char *args;
- const struct machine_opcode *insn;
- unsigned long opcode;
- expressionS the_operand;
- expressionS *operand = &the_operand;
- unsigned int regno;
- int reloc = BFD_RELOC_NONE;
-
-#if DEBUG
- printf ("machine_ip(%s)\n", str);
-#endif
-
- s = str;
- for (; ISALNUM (*s) || *s == '.'; ++s)
- if (ISUPPER (*s))
- *s = TOLOWER (*s);
-
- switch (*s)
- {
- case '\0':
- break;
-
- case ' ': /* FIXME-SOMEDAY more whitespace. */
- *s++ = '\0';
- break;
-
- default:
- as_bad (_("unknown opcode1: `%s'"), str);
- return;
- }
-
- if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
- {
- as_bad (_("unknown opcode2 `%s'."), str);
- return;
- }
-
- opcode = 0;
- memset (&the_insn, '\0', sizeof (the_insn));
- the_insn.reloc = BFD_RELOC_NONE;
-
- reloc = BFD_RELOC_NONE;
-
- /* Build the opcode, checking as we go to make sure that the
- operands match.
-
- If an operand matches, we modify the_insn or opcode appropriately,
- and do a "continue". If an operand fails to match, we "break". */
- if (insn->args[0] != '\0')
- /* Prime the pump. */
- s = parse_operand (s, operand, insn->args[0] == 'I');
-
- for (args = insn->args;; ++args)
- {
-#if DEBUG
- printf (" args = %s\n", args);
-#endif
- switch (*args)
- {
- case '\0': /* End of args. */
- /* We have have 0 args, do the bazoooka! */
- if (args == insn->args)
- encode (insn, &opcode, 0, 0);
-
- if (*s == '\0')
- {
- /* We are truly done. */
- the_insn.opcode = opcode;
- if (check_invalid_opcode (opcode))
- as_bad (_("instruction not allowed: %s"), str);
- return;
- }
- as_bad (_("too many operands: %s"), s);
- break;
-
- case ',': /* Must match a comma. */
- if (*s++ == ',')
- {
- reloc = BFD_RELOC_NONE;
-
- /* Parse next operand. */
- s = parse_operand (s, operand, args[1] == 'I');
-#if DEBUG
- printf (" ',' case: operand->X_add_number = %d, *args = %s, *s = %s\n",
- operand->X_add_number, args, s);
-#endif
- continue;
- }
- break;
-
- case '(': /* Must match a (. */
- s = parse_operand (s, operand, args[1] == 'I');
- continue;
-
- case ')': /* Must match a ). */
- continue;
-
- case 'r': /* A general register. */
- args++;
-
- if (operand->X_op != O_register)
- break; /* Only registers. */
-
- know (operand->X_add_symbol == 0);
- know (operand->X_op_symbol == 0);
- regno = operand->X_add_number;
- encode (insn, &opcode, regno, *args);
-#if DEBUG
- printf (" r: operand->X_op = %d\n", operand->X_op);
-#endif
- continue;
-
- default:
- /* if (! ISALPHA (*args))
- break; */ /* Only immediate values. */
-
- if (mask_or_shift)
- {
-#if DEBUG
- printf ("mask_or_shift = %d\n", mask_or_shift);
-#endif
- reloc = mask_or_shift;
- }
- mask_or_shift = 0;
-
- if (strncasecmp (args, "LO(", 3) == 0)
- {
-#if DEBUG
- printf ("reloc_const\n");
-#endif
- reloc = BFD_RELOC_LO16;
- }
- else if (strncasecmp (args, "HI(", 3) == 0)
- {
-#if DEBUG
- printf ("reloc_consth\n");
-#endif
- reloc = BFD_RELOC_HI16;
- }
-
- if (*s == '(')
- operand->X_op = O_constant;
- else if (*s == ')')
- s += 1;
-#if DEBUG
- printf (" default case: operand->X_add_number = %d, *args = %s, *s = %s\n", operand->X_add_number, args, s);
-#endif
- if (operand->X_op == O_constant)
- {
- if (reloc == BFD_RELOC_NONE)
- {
- bfd_vma v, mask;
-
- mask = 0x3ffffff;
- v = abs (operand->X_add_number) & ~ mask;
- if (v)
- as_bad (_("call/jmp target out of range (1)"));
- }
-
- if (reloc == BFD_RELOC_HI16)
- operand->X_add_number = ((operand->X_add_number >> 16) & 0xffff);
-
- the_insn.pcrel = 0;
- encode (insn, &opcode, operand->X_add_number, *args);
- /* the_insn.reloc = BFD_RELOC_NONE; */
- continue;
- }
-
- if (reloc == BFD_RELOC_NONE)
- the_insn.reloc = BFD_RELOC_32_GOT_PCREL;
- else
- the_insn.reloc = reloc;
-
- /* the_insn.reloc = insn->reloc; */
-#if DEBUG
- printf (" reloc sym=%d\n", the_insn.reloc);
- printf (" BFD_RELOC_NONE=%d\n", BFD_RELOC_NONE);
-#endif
- the_insn.exp = *operand;
-
- /* the_insn.reloc_offset = 1; */
- the_insn.pcrel = 1; /* Assume PC-relative jump. */
-
- /* FIXME-SOON, Do we figure out whether abs later, after
- know sym val? */
- if (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_HI16)
- the_insn.pcrel = 0;
-
- encode (insn, &opcode, operand->X_add_number, *args);
- continue;
- }
-
- /* Types or values of args don't match. */
- as_bad (_("invalid operands"));
- return;
- }
-}
-
-char *
-md_atof (int type, char * litP, int * sizeP)
-{
- return ieee_md_atof (type, litP, sizeP, TRUE);
-}
-
-/* Write out big-endian. */
-
-void
-md_number_to_chars (char *buf, valueT val, int n)
-{
- number_to_chars_bigendian (buf, val, n);
-}
-
-void
-md_apply_fix (fixS * fixP, valueT * val, segT seg ATTRIBUTE_UNUSED)
-{
- char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
- long t_val;
-
- t_val = (long) *val;
-
-#if DEBUG
- printf ("md_apply_fix val:%x\n", t_val);
-#endif
-
- fixP->fx_addnumber = t_val; /* Remember value for emit_reloc. */
-
- switch (fixP->fx_r_type)
- {
- case BFD_RELOC_32: /* XXXXXXXX pattern in a word. */
-#if DEBUG
- printf ("reloc_const: val=%x\n", t_val);
-#endif
- buf[0] = t_val >> 24;
- buf[1] = t_val >> 16;
- buf[2] = t_val >> 8;
- buf[3] = t_val;
- break;
-
- case BFD_RELOC_16: /* XXXX0000 pattern in a word. */
-#if DEBUG
- printf ("reloc_const: val=%x\n", t_val);
-#endif
- buf[0] = t_val >> 8;
- buf[1] = t_val;
- break;
-
- case BFD_RELOC_8: /* XX000000 pattern in a word. */
-#if DEBUG
- printf ("reloc_const: val=%x\n", t_val);
-#endif
- buf[0] = t_val;
- break;
-
- case BFD_RELOC_LO16: /* 0000XXXX pattern in a word. */
-#if DEBUG
- printf ("reloc_const: val=%x\n", t_val);
-#endif
- buf[2] = t_val >> 8; /* Holds bits 0000XXXX. */
- buf[3] = t_val;
- break;
-
- case BFD_RELOC_HI16: /* 0000XXXX pattern in a word. */
-#if DEBUG
- printf ("reloc_consth: val=%x\n", t_val);
-#endif
- buf[2] = t_val >> 24; /* Holds bits XXXX0000. */
- buf[3] = t_val >> 16;
- break;
-
- case BFD_RELOC_32_GOT_PCREL: /* 0000XXXX pattern in a word. */
- if (!fixP->fx_done)
- ;
- else if (fixP->fx_pcrel)
- {
- long v = t_val >> 28;
-
- if (v != 0 && v != -1)
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("call/jmp target out of range (2)"));
- }
- else
- /* This case was supposed to be handled in machine_ip. */
- abort ();
-
- buf[0] |= (t_val >> 26) & 0x03; /* Holds bits 0FFFFFFC of address. */
- buf[1] = t_val >> 18;
- buf[2] = t_val >> 10;
- buf[3] = t_val >> 2;
- break;
-
- case BFD_RELOC_VTABLE_INHERIT:
- case BFD_RELOC_VTABLE_ENTRY:
- fixP->fx_done = 0;
- break;
-
- case BFD_RELOC_NONE:
- default:
- as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type);
- break;
- }
-
- if (fixP->fx_addsy == (symbolS *) NULL)
- fixP->fx_done = 1;
-}
-
-/* Should never be called for or32. */
-
-void
-md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
- addressT from_addr ATTRIBUTE_UNUSED,
- addressT to_addr ATTRIBUTE_UNUSED,
- fragS * frag ATTRIBUTE_UNUSED,
- symbolS * to_symbol ATTRIBUTE_UNUSED)
-{
- as_fatal ("or32_create_short_jmp\n");
-}
-
-/* Should never be called for or32. */
-
-void
-md_convert_frag (bfd * headers ATTRIBUTE_UNUSED,
- segT seg ATTRIBUTE_UNUSED,
- fragS * fragP ATTRIBUTE_UNUSED)
-{
- as_fatal ("or32_convert_frag\n");
-}
-
-/* Should never be called for or32. */
-
-void
-md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
- addressT from_addr ATTRIBUTE_UNUSED,
- addressT to_addr ATTRIBUTE_UNUSED,
- fragS * frag ATTRIBUTE_UNUSED,
- symbolS * to_symbol ATTRIBUTE_UNUSED)
-{
- as_fatal ("or32_create_long_jump\n");
-}
-
-/* Should never be called for or32. */
-
-int
-md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
- segT segtype ATTRIBUTE_UNUSED)
-{
- as_fatal ("or32_estimate_size_before_relax\n");
- return 0;
-}
-
-/* Translate internal representation of relocation info to target format.
-
- On sparc/29k: first 4 bytes are normal unsigned long address, next three
- bytes are index, most sig. byte first. Byte 7 is broken up with
- bit 7 as external, bits 6 & 5 unused, and the lower
- five bits as relocation type. Next 4 bytes are long addend. */
-/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com. */
-
-#ifdef OBJ_AOUT
-void
-tc_aout_fix_to_chars (char *where,
- fixS *fixP,
- relax_addressT segment_address_in_file)
-{
- long r_symbolnum;
-
-#if DEBUG
- printf ("tc_aout_fix_to_chars\n");
-#endif
-
- know (fixP->fx_r_type < BFD_RELOC_NONE);
- know (fixP->fx_addsy != NULL);
-
- md_number_to_chars
- (where,
- fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
- 4);
-
- r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
- ? S_GET_TYPE (fixP->fx_addsy)
- : fixP->fx_addsy->sy_number);
-
- where[4] = (r_symbolnum >> 16) & 0x0ff;
- where[5] = (r_symbolnum >> 8) & 0x0ff;
- where[6] = r_symbolnum & 0x0ff;
- where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
-
- /* Also easy. */
- md_number_to_chars (&where[8], fixP->fx_addnumber, 4);
-}
-
-#endif /* OBJ_AOUT */
-
-const char *md_shortopts = "";
-
-struct option md_longopts[] =
-{
- { NULL, no_argument, NULL, 0 }
-};
-size_t md_longopts_size = sizeof (md_longopts);
-
-int
-md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-void
-md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
-{
-}
-
-/* This is called when a line is unrecognized. This is used to handle
- definitions of or32 style local labels. */
-
-int
-or32_unrecognized_line (int c)
-{
- int lab;
- char *s;
-
- if (c != '$'
- || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
- return 0;
-
- s = input_line_pointer;
-
- lab = 0;
- while (ISDIGIT ((unsigned char) *s))
- {
- lab = lab * 10 + *s - '0';
- ++s;
- }
-
- if (*s != ':')
- /* Not a label definition. */
- return 0;
-
- if (dollar_label_defined (lab))
- {
- as_bad (_("label \"$%d\" redefined"), lab);
- return 0;
- }
-
- define_dollar_label (lab);
- colon (dollar_label_name (lab, 0));
- input_line_pointer = s + 1;
-
- return 1;
-}
-
-/* Default the values of symbols known that should be "predefined". We
- don't bother to predefine them unless you actually use one, since there
- are a lot of them. */
-
-symbolS *
-md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
-{
- return NULL;
-}
-
-/* Parse an operand that is machine-specific. */
-
-void
-md_operand (expressionS *expressionP)
-{
-#if DEBUG
- printf (" md_operand(input_line_pointer = %s)\n", input_line_pointer);
-#endif
-
- if (input_line_pointer[0] == REGISTER_PREFIX && input_line_pointer[1] == 'r')
- {
- /* We have a numeric register expression. No biggy. */
- input_line_pointer += 2; /* Skip %r */
- (void) expression (expressionP);
-
- if (expressionP->X_op != O_constant
- || expressionP->X_add_number > 255)
- as_bad (_("Invalid expression after %%%%\n"));
- expressionP->X_op = O_register;
- }
- else if (input_line_pointer[0] == '&')
- {
- /* We are taking the 'address' of a register...this one is not
- in the manual, but it *is* in traps/fpsymbol.h! What they
- seem to want is the register number, as an absolute number. */
- input_line_pointer++; /* Skip & */
- (void) expression (expressionP);
-
- if (expressionP->X_op != O_register)
- as_bad (_("invalid register in & expression"));
- else
- expressionP->X_op = O_constant;
- }
- else if (input_line_pointer[0] == '$'
- && ISDIGIT ((unsigned char) input_line_pointer[1]))
- {
- long lab;
- char *name;
- symbolS *sym;
-
- /* This is a local label. */
- ++input_line_pointer;
- lab = (long) get_absolute_expression ();
-
- if (dollar_label_defined (lab))
- {
- name = dollar_label_name (lab, 0);
- sym = symbol_find (name);
- }
- else
- {
- name = dollar_label_name (lab, 1);
- sym = symbol_find_or_make (name);
- }
-
- expressionP->X_op = O_symbol;
- expressionP->X_add_symbol = sym;
- expressionP->X_add_number = 0;
- }
- else if (input_line_pointer[0] == '$')
- {
- char *s;
- char type;
- int fieldnum, fieldlimit;
- LITTLENUM_TYPE floatbuf[8];
-
- /* $float(), $doubleN(), or $extendN() convert floating values
- to integers. */
- s = input_line_pointer;
-
- ++s;
-
- fieldnum = 0;
- if (strncmp (s, "double", sizeof "double" - 1) == 0)
- {
- s += sizeof "double" - 1;
- type = 'd';
- fieldlimit = 2;
- }
- else if (strncmp (s, "float", sizeof "float" - 1) == 0)
- {
- s += sizeof "float" - 1;
- type = 'f';
- fieldlimit = 1;
- }
- else if (strncmp (s, "extend", sizeof "extend" - 1) == 0)
- {
- s += sizeof "extend" - 1;
- type = 'x';
- fieldlimit = 4;
- }
- else
- return;
-
- if (ISDIGIT (*s))
- {
- fieldnum = *s - '0';
- ++s;
- }
- if (fieldnum >= fieldlimit)
- return;
-
- SKIP_WHITESPACE ();
- if (*s != '(')
- return;
- ++s;
- SKIP_WHITESPACE ();
-
- s = atof_ieee (s, type, floatbuf);
- if (s == NULL)
- return;
- s = s;
-
- SKIP_WHITESPACE ();
- if (*s != ')')
- return;
- ++s;
- SKIP_WHITESPACE ();
-
- input_line_pointer = s;
- expressionP->X_op = O_constant;
- expressionP->X_unsigned = 1;
- expressionP->X_add_number = ((floatbuf[fieldnum * 2]
- << LITTLENUM_NUMBER_OF_BITS)
- + floatbuf[fieldnum * 2 + 1]);
- }
-}
-
-/* Round up a section size to the appropriate boundary. */
-
-valueT
-md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size ATTRIBUTE_UNUSED)
-{
- return size; /* Byte alignment is fine. */
-}
-
-/* Exactly what point is a PC-relative offset relative TO?
- On the 29000, they're relative to the address of the instruction,
- which we have set up as the address of the fixup too. */
-
-long
-md_pcrel_from (fixS *fixP)
-{
- return fixP->fx_where + fixP->fx_frag->fr_address;
-}
-
-/* Generate a reloc for a fixup. */
-
-arelent *
-tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
-{
- arelent *reloc;
-
- reloc = xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
- *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
- reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
- /* reloc->address = fixp->fx_frag->fr_address + fixp->fx_where + fixp->fx_addnumber;*/
- reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
-
- if (reloc->howto == (reloc_howto_type *) NULL)
- {
- as_bad_where (fixp->fx_file, fixp->fx_line,
- _("reloc %d not supported by object file format"),
- (int) fixp->fx_r_type);
- return NULL;
- }
-
- if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
- reloc->address = fixp->fx_offset;
-
- reloc->addend = fixp->fx_addnumber;
- return reloc;
-}
diff --git a/binutils-2.25/gas/config/tc-or32.h b/binutils-2.25/gas/config/tc-or32.h
deleted file mode 100644
index bd0d37f8..00000000
--- a/binutils-2.25/gas/config/tc-or32.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* tc-or32.h -- Assemble for the OpenRISC 1000.
- Copyright (C) 2002, 2003. 2005, 2007 Free Software Foundation, Inc.
- Contributed by Damjan Lampret <lampret@opencores.org>.
- Based upon a29k port.
-
- 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 3, 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, 51 Franklin Street - Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-#define TC_OR32
-
-#define TARGET_BYTES_BIG_ENDIAN 1
-
-#define LEX_DOLLAR 1
-
-#ifdef OBJ_ELF
-#define TARGET_FORMAT "elf32-or32"
-#define TARGET_ARCH bfd_arch_or32
-#endif
-
-#ifdef OBJ_COFF
-#define TARGET_FORMAT "coff-or32-big"
-#define reloc_type int
-#endif
-
-#define tc_unrecognized_line(c) or32_unrecognized_line (c)
-
-extern int or32_unrecognized_line (int);
-
-#define tc_coff_symbol_emit_hook(a) ; /* Not used. */
-
-#define COFF_MAGIC SIPFBOMAGIC
-
-/* No shared lib support, so we don't need to ensure externally
- visible symbols can be overridden. */
-#define EXTERN_FORCE_RELOC 0
-
-#ifdef OBJ_ELF
-/* Values passed to md_apply_fix don't include the symbol value. */
-#define MD_APPLY_SYM_VALUE(FIX) 0
-#endif
-
-#define ZERO_BASED_SEGMENTS
diff --git a/binutils-2.25/gas/config/tc-pdp11.c b/binutils-2.25/gas/config/tc-pdp11.c
index 98e241f6..1b3df58b 100644
--- a/binutils-2.25/gas/config/tc-pdp11.c
+++ b/binutils-2.25/gas/config/tc-pdp11.c
@@ -1,6 +1,5 @@
/* tc-pdp11.c - pdp11-specific -
- Copyright 2001, 2002, 2004, 2005, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-pdp11.h b/binutils-2.25/gas/config/tc-pdp11.h
index 31a690e0..af71667a 100644
--- a/binutils-2.25/gas/config/tc-pdp11.h
+++ b/binutils-2.25/gas/config/tc-pdp11.h
@@ -1,5 +1,5 @@
/* tc-pdp11.h -- Header file for tc-pdp11.c.
- Copyright 2001, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-pj.c b/binutils-2.25/gas/config/tc-pj.c
index 9dbe810e..dba4cbcc 100644
--- a/binutils-2.25/gas/config/tc-pj.c
+++ b/binutils-2.25/gas/config/tc-pj.c
@@ -1,6 +1,5 @@
/* tc-pj.c -- Assemble code for Pico Java
- Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -97,7 +96,8 @@ parse_exp_save_ilp (char *s, expressionS *op)
we want to handle magic pending reloc expressions specially. */
void
-pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp)
+pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp,
+ bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
{
static int rv[5][2] =
{ { 0, 0 },
diff --git a/binutils-2.25/gas/config/tc-pj.h b/binutils-2.25/gas/config/tc-pj.h
index bec85a24..61cd11f9 100644
--- a/binutils-2.25/gas/config/tc-pj.h
+++ b/binutils-2.25/gas/config/tc-pj.h
@@ -1,5 +1,5 @@
/* This file is tc-pj.h
- Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Contributed by Steve Chamberlain of Transmeta, sac@pobox.com
@@ -31,11 +31,12 @@
? "Pico Java GAS Big Endian" \
: "Pico Java GAS Little Endian")
-void pj_cons_fix_new_pj (struct frag *, int, int, expressionS *);
+void pj_cons_fix_new_pj (struct frag *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
arelent *tc_gen_reloc (asection *, struct fix *);
#define md_section_align(SEGMENT, SIZE) (SIZE)
-#define md_convert_frag(B, S, F) (as_fatal (_("convert_frag\n")), 0)
+#define md_convert_frag(B, S, F) as_fatal (_("convert_frag\n"))
#define md_estimate_size_before_relax(A, B) (as_fatal (_("estimate size\n")),0)
#define md_undefined_symbol(NAME) 0
@@ -45,8 +46,8 @@ arelent *tc_gen_reloc (asection *, struct fix *);
#define md_pcrel_from(FIX) \
((FIX)->fx_where + (FIX)->fx_frag->fr_address - 1)
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
- pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP)
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \
+ pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP, RELOC)
/* No shared lib support, so we don't need to ensure externally
visible symbols can be overridden. */
diff --git a/binutils-2.25/gas/config/tc-ppc.c b/binutils-2.25/gas/config/tc-ppc.c
index 6b54f5ad..189a22ba 100644
--- a/binutils-2.25/gas/config/tc-ppc.c
+++ b/binutils-2.25/gas/config/tc-ppc.c
@@ -1,7 +1,5 @@
/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
@@ -29,6 +27,7 @@
#ifdef OBJ_ELF
#include "elf/ppc.h"
+#include "elf/ppc64.h"
#include "dwarf2dbg.h"
#endif
@@ -86,7 +85,11 @@ static int set_target_endian = 0;
compensating for #lo being treated as a signed number. */
#define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
-#define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
+#define SEX16(val) (((val) ^ 0x8000) - 0x8000)
+
+/* For the time being on ppc64, don't report overflow on @h and @ha
+ applied to constants. */
+#define REPORT_OVERFLOW_HI 0
static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
@@ -126,9 +129,10 @@ static void ppc_vbyte (int);
#endif
#ifdef OBJ_ELF
-static void ppc_elf_cons (int);
static void ppc_elf_rdata (int);
static void ppc_elf_lcomm (int);
+static void ppc_elf_localentry (int);
+static void ppc_elf_abiversion (int);
#endif
#ifdef TE_PE
@@ -199,11 +203,20 @@ unsigned long nop_limit = 4;
ppc_cpu_t ppc_cpu = 0;
ppc_cpu_t sticky = 0;
+/* Value for ELF e_flags EF_PPC64_ABI. */
+unsigned int ppc_abiversion = 0;
+
/* Flags set on encountering toc relocs. */
enum {
has_large_toc_reloc = 1,
has_small_toc_reloc = 2
} toc_reloc_types;
+
+/* Warn on emitting data to code sections. */
+int warn_476;
+unsigned long last_insn;
+segT last_seg;
+subsegT last_subseg;
/* The target specific pseudo-ops which we support. */
@@ -249,14 +262,12 @@ const pseudo_typeS md_pseudo_table[] =
#endif
#ifdef OBJ_ELF
- { "llong", ppc_elf_cons, 8 },
- { "quad", ppc_elf_cons, 8 },
- { "long", ppc_elf_cons, 4 },
- { "word", ppc_elf_cons, 2 },
- { "short", ppc_elf_cons, 2 },
+ { "llong", cons, 8 },
{ "rdata", ppc_elf_rdata, 0 },
{ "rodata", ppc_elf_rdata, 0 },
{ "lcomm", ppc_elf_lcomm, 0 },
+ { "localentry", ppc_elf_localentry, 0 },
+ { "abiversion", ppc_elf_abiversion, 0 },
#endif
#ifdef TE_PE
@@ -1060,6 +1071,8 @@ const char *const md_shortopts = "um:";
#define OPTION_NOPS (OPTION_MD_BASE + 0)
const struct option md_longopts[] = {
{"nops", required_argument, NULL, OPTION_NOPS},
+ {"ppc476-workaround", no_argument, &warn_476, 1},
+ {"no-ppc476-workaround", no_argument, &warn_476, 0},
{NULL, no_argument, NULL, 0}
};
const size_t md_longopts_size = sizeof (md_longopts);
@@ -1238,6 +1251,9 @@ md_parse_option (int c, char *arg)
}
break;
+ case 0:
+ break;
+
default:
return 0;
}
@@ -1311,7 +1327,8 @@ PowerPC options:\n\
-Qy, -Qn ignored\n"));
#endif
fprintf (stream, _("\
--nops=count when aligning, more than COUNT nops uses a branch\n"));
+-nops=count when aligning, more than COUNT nops uses a branch\n\
+-ppc476-workaround warn if emitting data to code sections\n"));
}
/* Set ppc_cpu if it is not already set. */
@@ -1764,10 +1781,23 @@ ppc_insert_operand (unsigned long insn,
right = max & -max;
min = 0;
- if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0)
+ {
+ /* Extend the allowed range for addis to [-65536, 65535].
+ Similarly for some VLE high part insns. For 64-bit it
+ would be good to disable this for signed fields since the
+ value is sign extended into the high 32 bits of the register.
+ If the value is, say, an address, then we might care about
+ the high bits. However, gcc as of 2014-06 uses unsigned
+ values when loading the high part of 64-bit constants using
+ lis.
+ Use the same extended range for cmpli, to allow at least
+ [-32768, 65535]. */
+ min = ~max & -right;
+ }
+ else if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
{
- if ((operand->flags & PPC_OPERAND_SIGNOPT) == 0)
- max = (max >> 1) & -right;
+ max = (max >> 1) & -right;
min = ~max & -right;
}
@@ -1923,6 +1953,8 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
MAP32 ("bitfld", BFD_RELOC_PPC_EMB_BIT_FLD),
MAP32 ("relsda", BFD_RELOC_PPC_EMB_RELSDA),
MAP32 ("xgot", BFD_RELOC_PPC_TOC16),
+ MAP64 ("high", BFD_RELOC_PPC64_ADDR16_HIGH),
+ MAP64 ("higha", BFD_RELOC_PPC64_ADDR16_HIGHA),
MAP64 ("higher", BFD_RELOC_PPC64_HIGHER),
MAP64 ("highera", BFD_RELOC_PPC64_HIGHER_S),
MAP64 ("highest", BFD_RELOC_PPC64_HIGHEST),
@@ -1932,19 +1964,24 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
MAP64 ("toc@l", BFD_RELOC_PPC64_TOC16_LO),
MAP64 ("toc@h", BFD_RELOC_PPC64_TOC16_HI),
MAP64 ("toc@ha", BFD_RELOC_PPC64_TOC16_HA),
+ MAP64 ("dtprel@high", BFD_RELOC_PPC64_DTPREL16_HIGH),
+ MAP64 ("dtprel@higha", BFD_RELOC_PPC64_DTPREL16_HIGHA),
MAP64 ("dtprel@higher", BFD_RELOC_PPC64_DTPREL16_HIGHER),
MAP64 ("dtprel@highera", BFD_RELOC_PPC64_DTPREL16_HIGHERA),
MAP64 ("dtprel@highest", BFD_RELOC_PPC64_DTPREL16_HIGHEST),
MAP64 ("dtprel@highesta", BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
+ MAP64 ("localentry", BFD_RELOC_PPC64_ADDR64_LOCAL),
+ MAP64 ("tprel@high", BFD_RELOC_PPC64_TPREL16_HIGH),
+ MAP64 ("tprel@higha", BFD_RELOC_PPC64_TPREL16_HIGHA),
MAP64 ("tprel@higher", BFD_RELOC_PPC64_TPREL16_HIGHER),
MAP64 ("tprel@highera", BFD_RELOC_PPC64_TPREL16_HIGHERA),
MAP64 ("tprel@highest", BFD_RELOC_PPC64_TPREL16_HIGHEST),
MAP64 ("tprel@highesta", BFD_RELOC_PPC64_TPREL16_HIGHESTA),
- { (char *) 0, 0, 0, 0, BFD_RELOC_UNUSED }
+ { (char *) 0, 0, 0, 0, BFD_RELOC_NONE }
};
if (*str++ != '@')
- return BFD_RELOC_UNUSED;
+ return BFD_RELOC_NONE;
for (ch = *str, str2 = ident;
(str2 < ident + sizeof (ident) - 1
@@ -2030,63 +2067,49 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
return (bfd_reloc_code_real_type) reloc;
}
- return BFD_RELOC_UNUSED;
+ return BFD_RELOC_NONE;
}
-/* Like normal .long/.short/.word, except support @got, etc.
- Clobbers input_line_pointer, checks end-of-line. */
-static void
-ppc_elf_cons (int nbytes /* 1=.byte, 2=.word, 4=.long, 8=.llong */)
-{
- expressionS exp;
- bfd_reloc_code_real_type reloc;
-
- if (is_it_end_of_statement ())
- {
- demand_empty_rest_of_line ();
- return;
- }
+/* Support @got, etc. on constants emitted via .short, .int etc. */
- do
- {
- expression (&exp);
- if (*input_line_pointer == '@'
- && (reloc = ppc_elf_suffix (&input_line_pointer,
- &exp)) != BFD_RELOC_UNUSED)
- {
- reloc_howto_type *reloc_howto;
- int size;
+bfd_reloc_code_real_type
+ppc_elf_parse_cons (expressionS *exp, unsigned int nbytes)
+{
+ expression (exp);
+ if (nbytes >= 2 && *input_line_pointer == '@')
+ return ppc_elf_suffix (&input_line_pointer, exp);
+ return BFD_RELOC_NONE;
+}
- reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
- size = bfd_get_reloc_size (reloc_howto);
+/* Warn when emitting data to code sections, unless we are emitting
+ a relocation that ld --ppc476-workaround uses to recognise data
+ *and* there was an unconditional branch prior to the data. */
- if (size > nbytes)
- {
- as_bad (_("%s relocations do not fit in %d bytes\n"),
- reloc_howto->name, nbytes);
- }
- else
- {
- char *p;
- int offset;
-
- p = frag_more (nbytes);
- memset (p, 0, nbytes);
- offset = 0;
- if (target_big_endian)
- offset = nbytes - size;
- fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
- &exp, 0, reloc);
- }
- }
- else
- emit_expr (&exp, (unsigned int) nbytes);
+void
+ppc_elf_cons_fix_check (expressionS *exp ATTRIBUTE_UNUSED,
+ unsigned int nbytes, fixS *fix)
+{
+ if (warn_476
+ && (now_seg->flags & SEC_CODE) != 0
+ && (nbytes != 4
+ || fix == NULL
+ || !(fix->fx_r_type == BFD_RELOC_32
+ || fix->fx_r_type == BFD_RELOC_CTOR
+ || fix->fx_r_type == BFD_RELOC_32_PCREL)
+ || !(last_seg == now_seg && last_subseg == now_subseg)
+ || !((last_insn & (0x3f << 26)) == (18u << 26)
+ || ((last_insn & (0x3f << 26)) == (16u << 26)
+ && (last_insn & (0x14 << 21)) == (0x14 << 21))
+ || ((last_insn & (0x3f << 26)) == (19u << 26)
+ && (last_insn & (0x3ff << 1)) == (16u << 1)
+ && (last_insn & (0x14 << 21)) == (0x14 << 21)))))
+ {
+ /* Flag that we've warned. */
+ if (fix != NULL)
+ fix->fx_tcbit = 1;
+
+ as_warn (_("data in executable section"));
}
- while (*input_line_pointer++ == ',');
-
- /* Put terminator back into stream. */
- input_line_pointer--;
- demand_empty_rest_of_line ();
}
/* Solaris pseduo op to change to the .rodata section. */
@@ -2210,6 +2233,101 @@ ppc_elf_lcomm (int xxx ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
+/* Pseudo op to set symbol local entry point. */
+static void
+ppc_elf_localentry (int ignore ATTRIBUTE_UNUSED)
+{
+ char *name = input_line_pointer;
+ char c = get_symbol_end ();
+ char *p;
+ expressionS exp;
+ symbolS *sym;
+ asymbol *bfdsym;
+ elf_symbol_type *elfsym;
+
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("expected comma after name `%s' in .localentry directive"),
+ name);
+ *p = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ expression (&exp);
+ if (exp.X_op == O_absent)
+ {
+ as_bad (_("missing expression in .localentry directive"));
+ exp.X_op = O_constant;
+ exp.X_add_number = 0;
+ }
+ *p = 0;
+ sym = symbol_find_or_make (name);
+ *p = c;
+
+ if (resolve_expression (&exp)
+ && exp.X_op == O_constant)
+ {
+ unsigned char encoded = PPC64_SET_LOCAL_ENTRY_OFFSET (exp.X_add_number);
+
+ if (exp.X_add_number != (offsetT) PPC64_LOCAL_ENTRY_OFFSET (encoded))
+ as_bad (_(".localentry expression for `%s' "
+ "is not a valid power of 2"), S_GET_NAME (sym));
+ else
+ {
+ bfdsym = symbol_get_bfdsym (sym);
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+ gas_assert (elfsym);
+ elfsym->internal_elf_sym.st_other &= ~STO_PPC64_LOCAL_MASK;
+ elfsym->internal_elf_sym.st_other |= encoded;
+ if (ppc_abiversion == 0)
+ ppc_abiversion = 2;
+ }
+ }
+ else
+ as_bad (_(".localentry expression for `%s' "
+ "does not evaluate to a constant"), S_GET_NAME (sym));
+
+ demand_empty_rest_of_line ();
+}
+
+/* Pseudo op to set ABI version. */
+static void
+ppc_elf_abiversion (int ignore ATTRIBUTE_UNUSED)
+{
+ expressionS exp;
+
+ expression (&exp);
+ if (exp.X_op == O_absent)
+ {
+ as_bad (_("missing expression in .abiversion directive"));
+ exp.X_op = O_constant;
+ exp.X_add_number = 0;
+ }
+
+ if (resolve_expression (&exp)
+ && exp.X_op == O_constant)
+ ppc_abiversion = exp.X_add_number;
+ else
+ as_bad (_(".abiversion expression does not evaluate to a constant"));
+ demand_empty_rest_of_line ();
+}
+
+/* Set ABI version in output file. */
+void
+ppc_elf_end (void)
+{
+ if (ppc_obj64 && ppc_abiversion != 0)
+ {
+ elf_elfheader (stdoutput)->e_flags &= ~EF_PPC64_ABI;
+ elf_elfheader (stdoutput)->e_flags |= ppc_abiversion & EF_PPC64_ABI;
+ }
+}
+
/* Validate any relocations emitted for -mrelocatable, possibly adding
fixups for word relocations in writable segments, so we can adjust
them at runtime. */
@@ -2226,8 +2344,7 @@ ppc_elf_validate_fix (fixS *fixp, segT seg)
return;
case SHLIB_MRELOCATABLE:
- if (fixp->fx_r_type <= BFD_RELOC_UNUSED
- && fixp->fx_r_type != BFD_RELOC_16_GOTOFF
+ if (fixp->fx_r_type != BFD_RELOC_16_GOTOFF
&& fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF
&& fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF
&& fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
@@ -2727,12 +2844,12 @@ md_assemble (char *str)
/* FIXME: these next two specifically specify 32/64 bit
toc entries. We don't support them today. Is this
the right way to say that? */
- toc_reloc = BFD_RELOC_UNUSED;
+ toc_reloc = BFD_RELOC_NONE;
as_bad (_("unimplemented toc32 expression modifier"));
break;
case must_be_64:
/* FIXME: see above. */
- toc_reloc = BFD_RELOC_UNUSED;
+ toc_reloc = BFD_RELOC_NONE;
as_bad (_("unimplemented toc64 expression modifier"));
break;
default:
@@ -2802,7 +2919,7 @@ md_assemble (char *str)
bfd_reloc_code_real_type reloc;
char *orig_str = str;
- if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+ if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
switch (reloc)
{
default:
@@ -2810,55 +2927,76 @@ md_assemble (char *str)
break;
case BFD_RELOC_LO16:
- /* X_unsigned is the default, so if the user has done
- something which cleared it, we always produce a
- signed value. */
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number &= 0xffff;
- else
+ ex.X_add_number &= 0xffff;
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
ex.X_add_number = SEX16 (ex.X_add_number);
break;
case BFD_RELOC_HI16:
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number = PPC_HI (ex.X_add_number);
- else
- ex.X_add_number = SEX16 (PPC_HI (ex.X_add_number));
+ if (REPORT_OVERFLOW_HI && ppc_obj64)
+ {
+ /* PowerPC64 @h is tested for overflow. */
+ ex.X_add_number = (addressT) ex.X_add_number >> 16;
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ {
+ addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
+ ex.X_add_number
+ = ((addressT) ex.X_add_number ^ sign) - sign;
+ }
+ break;
+ }
+ /* Fall thru */
+
+ case BFD_RELOC_PPC64_ADDR16_HIGH:
+ ex.X_add_number = PPC_HI (ex.X_add_number);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ ex.X_add_number = SEX16 (ex.X_add_number);
break;
case BFD_RELOC_HI16_S:
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number = PPC_HA (ex.X_add_number);
- else
- ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
+ if (REPORT_OVERFLOW_HI && ppc_obj64)
+ {
+ /* PowerPC64 @ha is tested for overflow. */
+ ex.X_add_number
+ = ((addressT) ex.X_add_number + 0x8000) >> 16;
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ {
+ addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
+ ex.X_add_number
+ = ((addressT) ex.X_add_number ^ sign) - sign;
+ }
+ break;
+ }
+ /* Fall thru */
+
+ case BFD_RELOC_PPC64_ADDR16_HIGHA:
+ ex.X_add_number = PPC_HA (ex.X_add_number);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ ex.X_add_number = SEX16 (ex.X_add_number);
break;
case BFD_RELOC_PPC64_HIGHER:
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number = PPC_HIGHER (ex.X_add_number);
- else
- ex.X_add_number = SEX16 (PPC_HIGHER (ex.X_add_number));
+ ex.X_add_number = PPC_HIGHER (ex.X_add_number);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ ex.X_add_number = SEX16 (ex.X_add_number);
break;
case BFD_RELOC_PPC64_HIGHER_S:
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
- else
- ex.X_add_number = SEX16 (PPC_HIGHERA (ex.X_add_number));
+ ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ ex.X_add_number = SEX16 (ex.X_add_number);
break;
case BFD_RELOC_PPC64_HIGHEST:
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
- else
- ex.X_add_number = SEX16 (PPC_HIGHEST (ex.X_add_number));
+ ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ ex.X_add_number = SEX16 (ex.X_add_number);
break;
case BFD_RELOC_PPC64_HIGHEST_S:
- if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
- ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
- else
- ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
+ ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ ex.X_add_number = SEX16 (ex.X_add_number);
break;
}
#endif /* OBJ_ELF */
@@ -2867,7 +3005,7 @@ md_assemble (char *str)
}
else
{
- bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
+ bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
#ifdef OBJ_ELF
if (ex.X_op == O_symbol && str[0] == '(')
{
@@ -2884,7 +3022,7 @@ md_assemble (char *str)
expression (&tls_exp);
if (tls_exp.X_op == O_symbol)
{
- reloc = BFD_RELOC_UNUSED;
+ reloc = BFD_RELOC_NONE;
if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0)
{
reloc = BFD_RELOC_PPC_TLSGD;
@@ -2895,7 +3033,7 @@ md_assemble (char *str)
reloc = BFD_RELOC_PPC_TLSLD;
input_line_pointer += 7;
}
- if (reloc != BFD_RELOC_UNUSED)
+ if (reloc != BFD_RELOC_NONE)
{
SKIP_WHITESPACE ();
str = input_line_pointer;
@@ -2912,7 +3050,7 @@ md_assemble (char *str)
}
}
- if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+ if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
{
/* Some TLS tweaks. */
switch (reloc)
@@ -3008,116 +3146,21 @@ md_assemble (char *str)
break;
}
}
-
- /* For the absolute forms of branches, convert the PC
- relative form back into the absolute. */
- if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
- {
- switch (reloc)
- {
- case BFD_RELOC_PPC_B26:
- reloc = BFD_RELOC_PPC_BA26;
- break;
- case BFD_RELOC_PPC_B16:
- reloc = BFD_RELOC_PPC_BA16;
- break;
- case BFD_RELOC_PPC_B16_BRTAKEN:
- reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
- break;
- case BFD_RELOC_PPC_B16_BRNTAKEN:
- reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
- break;
- default:
- break;
- }
- }
-
- switch (reloc)
- {
- case BFD_RELOC_PPC_TOC16:
- toc_reloc_types |= has_small_toc_reloc;
- break;
- case BFD_RELOC_PPC64_TOC16_LO:
- case BFD_RELOC_PPC64_TOC16_HI:
- case BFD_RELOC_PPC64_TOC16_HA:
- toc_reloc_types |= has_large_toc_reloc;
- break;
- default:
- break;
- }
-
- if ((operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
- {
- switch (reloc)
- {
- case BFD_RELOC_16:
- reloc = BFD_RELOC_PPC64_ADDR16_DS;
- break;
- case BFD_RELOC_LO16:
- reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
- break;
- case BFD_RELOC_16_GOTOFF:
- reloc = BFD_RELOC_PPC64_GOT16_DS;
- break;
- case BFD_RELOC_LO16_GOTOFF:
- reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
- break;
- case BFD_RELOC_LO16_PLTOFF:
- reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
- break;
- case BFD_RELOC_16_BASEREL:
- reloc = BFD_RELOC_PPC64_SECTOFF_DS;
- break;
- case BFD_RELOC_LO16_BASEREL:
- reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
- break;
- case BFD_RELOC_PPC_TOC16:
- reloc = BFD_RELOC_PPC64_TOC16_DS;
- break;
- case BFD_RELOC_PPC64_TOC16_LO:
- reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
- break;
- case BFD_RELOC_PPC64_PLTGOT16:
- reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
- break;
- case BFD_RELOC_PPC64_PLTGOT16_LO:
- reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
- break;
- case BFD_RELOC_PPC_DTPREL16:
- reloc = BFD_RELOC_PPC64_DTPREL16_DS;
- break;
- case BFD_RELOC_PPC_DTPREL16_LO:
- reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
- break;
- case BFD_RELOC_PPC_TPREL16:
- reloc = BFD_RELOC_PPC64_TPREL16_DS;
- break;
- case BFD_RELOC_PPC_TPREL16_LO:
- reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
- break;
- case BFD_RELOC_PPC_GOT_DTPREL16:
- case BFD_RELOC_PPC_GOT_DTPREL16_LO:
- case BFD_RELOC_PPC_GOT_TPREL16:
- case BFD_RELOC_PPC_GOT_TPREL16_LO:
- break;
- default:
- as_bad (_("unsupported relocation for DS offset field"));
- break;
- }
- }
}
#endif /* OBJ_ELF */
- if (reloc != BFD_RELOC_UNUSED)
+ if (reloc != BFD_RELOC_NONE)
;
/* Determine a BFD reloc value based on the operand information.
We are only prepared to turn a few of the operands into
relocs. */
- else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ else if ((operand->flags & (PPC_OPERAND_RELATIVE
+ | PPC_OPERAND_ABSOLUTE)) != 0
&& operand->bitm == 0x3fffffc
&& operand->shift == 0)
reloc = BFD_RELOC_PPC_B26;
- else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ else if ((operand->flags & (PPC_OPERAND_RELATIVE
+ | PPC_OPERAND_ABSOLUTE)) != 0
&& operand->bitm == 0xfffc
&& operand->shift == 0)
reloc = BFD_RELOC_PPC_B16;
@@ -3133,40 +3176,126 @@ md_assemble (char *str)
&& operand->bitm == 0x1fffffe
&& operand->shift == 0)
reloc = BFD_RELOC_PPC_VLE_REL24;
- else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
- && operand->bitm == 0x3fffffc
- && operand->shift == 0)
- reloc = BFD_RELOC_PPC_BA26;
- else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
- && operand->bitm == 0xfffc
- && operand->shift == 0)
- reloc = BFD_RELOC_PPC_BA16;
-#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
- else if ((operand->flags & PPC_OPERAND_PARENS) != 0
+ else if ((operand->flags & PPC_OPERAND_NEGATIVE) == 0
&& (operand->bitm & 0xfff0) == 0xfff0
&& operand->shift == 0)
{
+ reloc = BFD_RELOC_16;
+#if defined OBJ_XCOFF || defined OBJ_ELF
/* Note: the symbol may be not yet defined. */
- if (ppc_is_toc_sym (ex.X_add_symbol))
+ if ((operand->flags & PPC_OPERAND_PARENS) != 0
+ && ppc_is_toc_sym (ex.X_add_symbol))
{
reloc = BFD_RELOC_PPC_TOC16;
#ifdef OBJ_ELF
- if (ppc_obj64
- && (operand->flags & PPC_OPERAND_DS) != 0)
- reloc = BFD_RELOC_PPC64_TOC16_DS;
+ as_warn (_("assuming %s on symbol"),
+ ppc_obj64 ? "@toc" : "@xgot");
#endif
}
- else
+#endif
+ }
+
+ /* For the absolute forms of branches, convert the PC
+ relative form back into the absolute. */
+ if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+ {
+ switch (reloc)
{
- reloc = BFD_RELOC_16;
+ case BFD_RELOC_PPC_B26:
+ reloc = BFD_RELOC_PPC_BA26;
+ break;
+ case BFD_RELOC_PPC_B16:
+ reloc = BFD_RELOC_PPC_BA16;
+ break;
#ifdef OBJ_ELF
- if (ppc_obj64
- && (operand->flags & PPC_OPERAND_DS) != 0)
- reloc = BFD_RELOC_PPC64_ADDR16_DS;
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
+ break;
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
+ break;
#endif
+ default:
+ break;
}
}
-#endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
+
+#ifdef OBJ_ELF
+ switch (reloc)
+ {
+ case BFD_RELOC_PPC_TOC16:
+ toc_reloc_types |= has_small_toc_reloc;
+ break;
+ case BFD_RELOC_PPC64_TOC16_LO:
+ case BFD_RELOC_PPC64_TOC16_HI:
+ case BFD_RELOC_PPC64_TOC16_HA:
+ toc_reloc_types |= has_large_toc_reloc;
+ break;
+ default:
+ break;
+ }
+
+ if (ppc_obj64
+ && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
+ {
+ switch (reloc)
+ {
+ case BFD_RELOC_16:
+ reloc = BFD_RELOC_PPC64_ADDR16_DS;
+ break;
+ case BFD_RELOC_LO16:
+ reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
+ break;
+ case BFD_RELOC_16_GOTOFF:
+ reloc = BFD_RELOC_PPC64_GOT16_DS;
+ break;
+ case BFD_RELOC_LO16_GOTOFF:
+ reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
+ break;
+ case BFD_RELOC_LO16_PLTOFF:
+ reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
+ break;
+ case BFD_RELOC_16_BASEREL:
+ reloc = BFD_RELOC_PPC64_SECTOFF_DS;
+ break;
+ case BFD_RELOC_LO16_BASEREL:
+ reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
+ break;
+ case BFD_RELOC_PPC_TOC16:
+ reloc = BFD_RELOC_PPC64_TOC16_DS;
+ break;
+ case BFD_RELOC_PPC64_TOC16_LO:
+ reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16:
+ reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_LO:
+ reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_DTPREL16:
+ reloc = BFD_RELOC_PPC64_DTPREL16_DS;
+ break;
+ case BFD_RELOC_PPC_DTPREL16_LO:
+ reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_TPREL16:
+ reloc = BFD_RELOC_PPC64_TPREL16_DS;
+ break;
+ case BFD_RELOC_PPC_TPREL16_LO:
+ reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_GOT_DTPREL16:
+ case BFD_RELOC_PPC_GOT_DTPREL16_LO:
+ case BFD_RELOC_PPC_GOT_TPREL16:
+ case BFD_RELOC_PPC_GOT_TPREL16_LO:
+ break;
+ default:
+ as_bad (_("unsupported relocation for DS offset field"));
+ break;
+ }
+ }
+#endif
/* We need to generate a fixup for this expression. */
if (fc >= MAX_INSN_FIXUPS)
@@ -3240,7 +3369,12 @@ md_assemble (char *str)
ppc_apuinfo_section_add (PPC_APUINFO_CACHELCK, 1);
if (opcode->flags & PPC_OPCODE_RFMCI)
ppc_apuinfo_section_add (PPC_APUINFO_RFMCI, 1);
- if (opcode->flags & PPC_OPCODE_VLE)
+ /* Only set the VLE flag if the instruction has been pulled via
+ the VLE instruction set. This way the flag is guaranteed to
+ be set for VLE-only instructions or for VLE-only processors,
+ however it'll remain clear for dual-mode instructions on
+ dual-mode and, more importantly, standard-mode processors. */
+ if ((ppc_cpu & opcode->flags) == PPC_OPCODE_VLE)
ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
}
#endif
@@ -3272,6 +3406,9 @@ md_assemble (char *str)
frag_now->insn_addr = addr_mod;
frag_now->has_code = 1;
md_number_to_chars (f, insn, insn_length);
+ last_insn = insn;
+ last_seg = now_seg;
+ last_subseg = now_subseg;
#ifdef OBJ_ELF
dwarf2_emit_insn (insn_length);
@@ -3281,7 +3418,7 @@ md_assemble (char *str)
for (i = 0; i < fc; i++)
{
fixS *fixP;
- if (fixups[i].reloc != BFD_RELOC_UNUSED)
+ if (fixups[i].reloc != BFD_RELOC_NONE)
{
reloc_howto_type *reloc_howto;
int size;
@@ -3314,7 +3451,7 @@ md_assemble (char *str)
insn_length,
&fixups[i].exp,
(operand->flags & PPC_OPERAND_RELATIVE) != 0,
- BFD_RELOC_UNUSED);
+ BFD_RELOC_NONE);
}
fixP->fx_pcrel_adjust = fixups[i].opindex;
}
@@ -3429,6 +3566,8 @@ ppc_section_flags (flagword flags, bfd_vma attr ATTRIBUTE_UNUSED, int type)
static void
ppc_byte (int ignore ATTRIBUTE_UNUSED)
{
+ int count = 0;
+
if (*input_line_pointer != '\"')
{
cons (1);
@@ -3452,8 +3591,11 @@ ppc_byte (int ignore ATTRIBUTE_UNUSED)
}
FRAG_APPEND_1_CHAR (c);
+ ++count;
}
+ if (warn_476 && count != 0 && (now_seg->flags & SEC_CODE) != 0)
+ as_warn (_("data in executable section"));
demand_empty_rest_of_line ();
}
@@ -6159,6 +6301,22 @@ ppc_force_relocation (fixS *fix)
case BFD_RELOC_24_PLT_PCREL:
case BFD_RELOC_PPC64_TOC:
return 1;
+ case BFD_RELOC_PPC_B26:
+ case BFD_RELOC_PPC_BA26:
+ case BFD_RELOC_PPC_B16:
+ case BFD_RELOC_PPC_BA16:
+ /* All branch fixups targeting a localentry symbol must
+ force a relocation. */
+ if (fix->fx_addsy)
+ {
+ asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);
+ elf_symbol_type *elfsym
+ = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+ gas_assert (elfsym);
+ if ((STO_PPC64_LOCAL_MASK & elfsym->internal_elf_sym.st_other) != 0)
+ return 1;
+ }
+ break;
default:
break;
}
@@ -6173,6 +6331,32 @@ ppc_force_relocation (fixS *fix)
int
ppc_fix_adjustable (fixS *fix)
{
+ switch (fix->fx_r_type)
+ {
+ /* All branch fixups targeting a localentry symbol must
+ continue using the symbol. */
+ case BFD_RELOC_PPC_B26:
+ case BFD_RELOC_PPC_BA26:
+ case BFD_RELOC_PPC_B16:
+ case BFD_RELOC_PPC_BA16:
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ case BFD_RELOC_PPC_BA16_BRTAKEN:
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ if (fix->fx_addsy)
+ {
+ asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);
+ elf_symbol_type *elfsym
+ = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+ gas_assert (elfsym);
+ if ((STO_PPC64_LOCAL_MASK & elfsym->internal_elf_sym.st_other) != 0)
+ return 0;
+ }
+ break;
+ default:
+ break;
+ }
+
return (fix->fx_r_type != BFD_RELOC_16_GOTOFF
&& fix->fx_r_type != BFD_RELOC_LO16_GOTOFF
&& fix->fx_r_type != BFD_RELOC_HI16_GOTOFF
@@ -6296,7 +6480,7 @@ ppc_handle_align (struct frag *fragP)
fixups we generated by the calls to fix_new_exp, above. */
void
-md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+md_apply_fix (fixS *fixP, valueT *valP, segT seg)
{
valueT value = * valP;
offsetT fieldval;
@@ -6390,25 +6574,51 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
fieldval = value & 0xffff;
sign_extend_16:
if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
- fieldval = (fieldval ^ 0x8000) - 0x8000;
+ fieldval = SEX16 (fieldval);
fixP->fx_no_overflow = 1;
break;
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_PCREL:
#ifdef OBJ_ELF
+ if (REPORT_OVERFLOW_HI && ppc_obj64)
+ {
+ fieldval = value >> 16;
+ if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
+ {
+ valueT sign = (((valueT) -1 >> 16) + 1) >> 1;
+ fieldval = ((valueT) fieldval ^ sign) - sign;
+ }
+ break;
+ }
+ /* Fall thru */
+
case BFD_RELOC_PPC_VLE_HI16A:
case BFD_RELOC_PPC_VLE_HI16D:
+ case BFD_RELOC_PPC64_ADDR16_HIGH:
#endif
- case BFD_RELOC_HI16:
- case BFD_RELOC_HI16_PCREL:
fieldval = PPC_HI (value);
goto sign_extend_16;
+ case BFD_RELOC_HI16_S:
+ case BFD_RELOC_HI16_S_PCREL:
#ifdef OBJ_ELF
+ if (REPORT_OVERFLOW_HI && ppc_obj64)
+ {
+ fieldval = (value + 0x8000) >> 16;
+ if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
+ {
+ valueT sign = (((valueT) -1 >> 16) + 1) >> 1;
+ fieldval = ((valueT) fieldval ^ sign) - sign;
+ }
+ break;
+ }
+ /* Fall thru */
+
case BFD_RELOC_PPC_VLE_HA16A:
case BFD_RELOC_PPC_VLE_HA16D:
+ case BFD_RELOC_PPC64_ADDR16_HIGHA:
#endif
- case BFD_RELOC_HI16_S:
- case BFD_RELOC_HI16_S_PCREL:
fieldval = PPC_HA (value);
goto sign_extend_16;
@@ -6471,10 +6681,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_PPC_GOT_DTPREL16_HA:
case BFD_RELOC_PPC64_TPREL16_DS:
case BFD_RELOC_PPC64_TPREL16_LO_DS:
+ case BFD_RELOC_PPC64_TPREL16_HIGH:
+ case BFD_RELOC_PPC64_TPREL16_HIGHA:
case BFD_RELOC_PPC64_TPREL16_HIGHER:
case BFD_RELOC_PPC64_TPREL16_HIGHERA:
case BFD_RELOC_PPC64_TPREL16_HIGHEST:
case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
+ case BFD_RELOC_PPC64_DTPREL16_HIGH:
+ case BFD_RELOC_PPC64_DTPREL16_HIGHA:
case BFD_RELOC_PPC64_DTPREL16_DS:
case BFD_RELOC_PPC64_DTPREL16_LO_DS:
case BFD_RELOC_PPC64_DTPREL16_HIGHER:
@@ -6614,7 +6828,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
return;
gas_assert (fixP->fx_addsy != NULL);
- if (fixP->fx_r_type == BFD_RELOC_UNUSED)
+ if (fixP->fx_r_type == BFD_RELOC_NONE)
{
char *sfile;
unsigned int sline;
@@ -6660,6 +6874,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_PPC64_HIGHER_S:
case BFD_RELOC_PPC64_HIGHEST:
case BFD_RELOC_PPC64_HIGHEST_S:
+ case BFD_RELOC_PPC64_ADDR16_HIGH:
+ case BFD_RELOC_PPC64_ADDR16_HIGHA:
+ case BFD_RELOC_PPC64_ADDR64_LOCAL:
break;
case BFD_RELOC_PPC_DTPMOD:
@@ -6736,10 +6953,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_PPC64_TOC16_LO:
case BFD_RELOC_PPC64_TOC16_HI:
case BFD_RELOC_PPC64_TOC16_HA:
+ case BFD_RELOC_PPC64_DTPREL16_HIGH:
+ case BFD_RELOC_PPC64_DTPREL16_HIGHA:
case BFD_RELOC_PPC64_DTPREL16_HIGHER:
case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
+ case BFD_RELOC_PPC64_TPREL16_HIGH:
+ case BFD_RELOC_PPC64_TPREL16_HIGHA:
case BFD_RELOC_PPC64_TPREL16_HIGHER:
case BFD_RELOC_PPC64_TPREL16_HIGHERA:
case BFD_RELOC_PPC64_TPREL16_HIGHEST:
@@ -6772,6 +6993,16 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
if (fixP->fx_size && APPLY_RELOC)
md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
fieldval, fixP->fx_size);
+ if (warn_476
+ && (seg->flags & SEC_CODE) != 0
+ && fixP->fx_size == 4
+ && fixP->fx_done
+ && !fixP->fx_tcbit
+ && (fixP->fx_r_type == BFD_RELOC_32
+ || fixP->fx_r_type == BFD_RELOC_CTOR
+ || fixP->fx_r_type == BFD_RELOC_32_PCREL))
+ as_warn_where (fixP->fx_file, fixP->fx_line,
+ _("data in executable section"));
}
/* We are only able to convert some relocs to pc-relative. */
diff --git a/binutils-2.25/gas/config/tc-ppc.h b/binutils-2.25/gas/config/tc-ppc.h
index 3dd3f819..3cd9bf16 100644
--- a/binutils-2.25/gas/config/tc-ppc.h
+++ b/binutils-2.25/gas/config/tc-ppc.h
@@ -1,6 +1,5 @@
/* tc-ppc.h -- Header file for tc-ppc.c.
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
@@ -232,12 +231,23 @@ extern int ppc_fix_adjustable (struct fix *);
/* Values passed to md_apply_fix don't include symbol values. */
#define MD_APPLY_SYM_VALUE(FIX) 0
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+ ppc_elf_parse_cons (EXP, NBYTES)
+extern bfd_reloc_code_real_type ppc_elf_parse_cons (expressionS *,
+ unsigned int);
+#define TC_CONS_FIX_CHECK(EXP, NBYTES, FIX) \
+ ppc_elf_cons_fix_check (EXP, NBYTES, FIX)
+extern void ppc_elf_cons_fix_check (expressionS *, unsigned int, struct fix *);
+
#define tc_frob_file_before_adjust ppc_frob_file_before_adjust
extern void ppc_frob_file_before_adjust (void);
#define tc_adjust_symtab() ppc_elf_adjust_symtab ()
extern void ppc_elf_adjust_symtab (void);
+extern void ppc_elf_end (void);
+#define md_end ppc_elf_end
+
#endif /* OBJ_ELF */
#if defined (OBJ_ELF) || defined (OBJ_XCOFF)
diff --git a/binutils-2.25/gas/config/tc-rl78.c b/binutils-2.25/gas/config/tc-rl78.c
index 651f3f67..1627c61e 100644
--- a/binutils-2.25/gas/config/tc-rl78.c
+++ b/binutils-2.25/gas/config/tc-rl78.c
@@ -1,5 +1,5 @@
/* tc-rl78.c -- Assembler for the Renesas RL78
- Copyright 2011-2013 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -20,7 +20,6 @@
#include "as.h"
#include "struc-symbol.h"
-#include "obstack.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
#include "libbfd.h"
@@ -86,6 +85,15 @@ typedef struct rl78_bytesT
static rl78_bytesT rl78_bytes;
void
+rl78_relax (int type, int pos)
+{
+ rl78_bytes.relax[rl78_bytes.n_relax].type = type;
+ rl78_bytes.relax[rl78_bytes.n_relax].field_pos = pos;
+ rl78_bytes.relax[rl78_bytes.n_relax].val_ofs = rl78_bytes.n_base + rl78_bytes.n_ops;
+ rl78_bytes.n_relax ++;
+}
+
+void
rl78_linkrelax_addr16 (void)
{
rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
@@ -199,6 +207,16 @@ rl78_op (expressionS exp, int nbytes, int type)
if (nbytes > 2
&& exp.X_md == BFD_RELOC_RL78_CODE)
exp.X_md = 0;
+
+ if (nbytes == 1
+ && (exp.X_md == BFD_RELOC_RL78_LO16
+ || exp.X_md == BFD_RELOC_RL78_HI16))
+ as_bad (_("16-bit relocation used in 8-bit operand"));
+
+ if (nbytes == 2
+ && exp.X_md == BFD_RELOC_RL78_HI8)
+ as_bad (_("8-bit relocation used in 16-bit operand"));
+
rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
rl78_bytes.n_ops += nbytes;
@@ -263,6 +281,8 @@ enum options
{
OPTION_RELAX = OPTION_MD_BASE,
OPTION_G10,
+ OPTION_32BIT_DOUBLES,
+ OPTION_64BIT_DOUBLES,
};
#define RL78_SHORTOPTS ""
@@ -273,6 +293,8 @@ struct option md_longopts[] =
{
{"relax", no_argument, NULL, OPTION_RELAX},
{"mg10", no_argument, NULL, OPTION_G10},
+ {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
+ {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
@@ -289,6 +311,14 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
case OPTION_G10:
elf_flags |= E_FLAG_RL78_G10;
return 1;
+
+ case OPTION_32BIT_DOUBLES:
+ elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
+ return 1;
+
+ case OPTION_64BIT_DOUBLES:
+ elf_flags |= E_FLAG_RL78_64BIT_DOUBLES;
+ return 1;
}
return 0;
}
@@ -296,9 +326,12 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
void
md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
{
+ fprintf (stream, _(" RL78 specific command line options:\n"));
+ fprintf (stream, _(" --mg10 Enable support for G10 variant\n"));
+ fprintf (stream, _(" --m32bit-doubles [default]\n"));
+ fprintf (stream, _(" --m64bit-doubles\n"));
}
-
static void
s_bss (int ignore ATTRIBUTE_UNUSED)
{
@@ -309,15 +342,23 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
+static void
+rl78_float_cons (int ignore ATTRIBUTE_UNUSED)
+{
+ if (elf_flags & E_FLAG_RL78_64BIT_DOUBLES)
+ return float_cons ('d');
+ return float_cons ('f');
+}
+
/* The target specific pseudo-ops which we support. */
const pseudo_typeS md_pseudo_table[] =
{
- /* Our "standard" pseudos. */
- { "double", float_cons, 'd' },
- { "bss", s_bss, 0 },
- { "3byte", cons, 3 },
- { "int", cons, 4 },
- { "word", cons, 4 },
+ /* Our "standard" pseudos. */
+ { "double", rl78_float_cons, 'd' },
+ { "bss", s_bss, 0 },
+ { "3byte", cons, 3 },
+ { "int", cons, 4 },
+ { "word", cons, 4 },
/* End of list marker. */
{ NULL, NULL, 0 }
@@ -347,6 +388,23 @@ md_number_to_chars (char * buf, valueT val, int n)
number_to_chars_littleendian (buf, val, n);
}
+static void
+require_end_of_expr (char *fname)
+{
+ while (* input_line_pointer == ' '
+ || * input_line_pointer == '\t')
+ input_line_pointer ++;
+
+ if (! * input_line_pointer
+ || strchr ("\n\r,", * input_line_pointer)
+ || strchr (comment_chars, * input_line_pointer)
+ || strchr (line_comment_chars, * input_line_pointer)
+ || strchr (line_separator_chars, * input_line_pointer))
+ return;
+
+ as_bad (_("%%%s() must be outermost term in expression"), fname);
+}
+
static struct
{
char * fname;
@@ -388,6 +446,8 @@ md_operand (expressionS * exp ATTRIBUTE_UNUSED)
input_line_pointer ++;
exp->X_md = reloc;
+
+ require_end_of_expr (reloc_functions[i].fname);
}
void
@@ -467,12 +527,13 @@ md_assemble (char * str)
rl78_parse ();
/* This simplifies the relaxation code. */
- if (rl78_bytes.link_relax)
+ if (rl78_bytes.n_relax || rl78_bytes.link_relax)
{
int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
/* We do it this way because we want the frag to have the
- rl78_bytes in it, which we initialize above. */
- bytes = frag_more (olen);
+ rl78_bytes in it, which we initialize above. The extra bytes
+ are for relaxing. */
+ bytes = frag_more (olen + 3);
frag_then = frag_now;
frag_variant (rs_machine_dependent,
olen /* max_chars */,
@@ -552,6 +613,7 @@ rl78_cons_fix_new (fragS * frag,
expressionS * exp)
{
bfd_reloc_code_real_type type;
+ fixS *fixP;
switch (size)
{
@@ -601,16 +663,495 @@ rl78_cons_fix_new (fragS * frag,
type = BFD_RELOC_RL78_DIFF;
}
- fix_new_exp (frag, where, (int) size, exp, 0, type);
+ fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
+ switch (exp->X_md)
+ {
+ /* These are intended to have values larger than the container,
+ since the backend puts only the portion we need in it.
+ However, we don't have a backend-specific reloc for them as
+ they're handled with complex relocations. */
+ case BFD_RELOC_RL78_LO16:
+ case BFD_RELOC_RL78_HI16:
+ case BFD_RELOC_RL78_HI8:
+ fixP->fx_no_overflow = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/*----------------------------------------------------------------------*/
+/* To recap: we estimate everything based on md_estimate_size, then
+ adjust based on rl78_relax_frag. When it all settles, we call
+ md_convert frag to update the bytes. The relaxation types and
+ relocations are in fragP->tc_frag_data, which is a copy of that
+ rl78_bytes.
+
+ Our scheme is as follows: fr_fix has the size of the smallest
+ opcode (like BRA.S). We store the number of total bytes we need in
+ fr_subtype. When we're done relaxing, we use fr_subtype and the
+ existing opcode bytes to figure out what actual opcode we need to
+ put in there. If the fixup isn't resolvable now, we use the
+ maximal size. */
+
+#define TRACE_RELAX 0
+#define tprintf if (TRACE_RELAX) printf
+
+
+typedef enum
+{
+ OT_other,
+ OT_bt,
+ OT_bt_sfr,
+ OT_bt_es,
+ OT_bc,
+ OT_bh
+} op_type_T;
+
+/* We're looking for these types of relaxations:
+
+ BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
+ B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
+
+ BT sfr 00110001 sbit0cc0 sfr----- addr----
+ BT ES: 00010001 00101110 sbit0cc1 addr----
+
+ BC 110111cc addr----
+ B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
+
+ BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
+ B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
+*/
+
+/* Given the opcode bytes at OP, figure out which opcode it is and
+ return the type of opcode. We use this to re-encode the opcode as
+ a different size later. */
+
+static op_type_T
+rl78_opcode_type (char * op)
+{
+ if (op[0] == 0x31
+ && ((op[1] & 0x0f) == 0x05
+ || (op[1] & 0x0f) == 0x03))
+ return OT_bt;
+
+ if (op[0] == 0x31
+ && ((op[1] & 0x0f) == 0x04
+ || (op[1] & 0x0f) == 0x02))
+ return OT_bt_sfr;
+
+ if (op[0] == 0x11
+ && op[1] == 0x31
+ && ((op[2] & 0x0f) == 0x05
+ || (op[2] & 0x0f) == 0x03))
+ return OT_bt_es;
+
+ if ((op[0] & 0xfc) == 0xdc)
+ return OT_bc;
+
+ if (op[0] == 0x61
+ && (op[1] & 0xef) == 0xc3)
+ return OT_bh;
+
+ return OT_other;
+}
+
+/* Returns zero if *addrP has the target address. Else returns nonzero
+ if we cannot compute the target address yet. */
+
+static int
+rl78_frag_fix_value (fragS * fragP,
+ segT segment,
+ int which,
+ addressT * addrP,
+ int need_diff,
+ addressT * sym_addr)
+{
+ addressT addr = 0;
+ rl78_bytesT * b = fragP->tc_frag_data;
+ expressionS * exp = & b->fixups[which].exp;
+
+ if (need_diff && exp->X_op != O_subtract)
+ return 1;
+
+ if (exp->X_add_symbol)
+ {
+ if (S_FORCE_RELOC (exp->X_add_symbol, 1))
+ return 1;
+ if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
+ return 1;
+ addr += S_GET_VALUE (exp->X_add_symbol);
+ }
+
+ if (exp->X_op_symbol)
+ {
+ if (exp->X_op != O_subtract)
+ return 1;
+ if (S_FORCE_RELOC (exp->X_op_symbol, 1))
+ return 1;
+ if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
+ return 1;
+ addr -= S_GET_VALUE (exp->X_op_symbol);
+ }
+ if (sym_addr)
+ * sym_addr = addr;
+ addr += exp->X_add_number;
+ * addrP = addr;
+ return 0;
}
-/* No relaxation just yet */
+/* Estimate how big the opcode is after this relax pass. The return
+ value is the difference between fr_fix and the actual size. We
+ compute the total size in rl78_relax_frag and store it in fr_subtype,
+ sowe only need to subtract fx_fix and return it. */
+
int
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
{
- return 0;
+ int opfixsize;
+ int delta;
+
+ /* This is the size of the opcode that's accounted for in fr_fix. */
+ opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
+ /* This is the size of the opcode that isn't. */
+ delta = (fragP->fr_subtype - opfixsize);
+
+ tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
+ return delta;
+}
+
+/* Given the new addresses for this relax pass, figure out how big
+ each opcode must be. We store the total number of bytes needed in
+ fr_subtype. The return value is the difference between the size
+ after the last pass and the size after this pass, so we use the old
+ fr_subtype to calculate the difference. */
+
+int
+rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
+{
+ addressT addr0, sym_addr;
+ addressT mypc;
+ int disp;
+ int oldsize = fragP->fr_subtype;
+ int newsize = oldsize;
+ op_type_T optype;
+ int ri;
+
+ mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
+
+ /* If we ever get more than one reloc per opcode, this is the one
+ we're relaxing. */
+ ri = 0;
+
+ optype = rl78_opcode_type (fragP->fr_opcode);
+ /* Try to get the target address. */
+ if (rl78_frag_fix_value (fragP, segment, ri, & addr0,
+ fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
+ & sym_addr))
+ {
+ /* If we don't, we must use the maximum size for the linker. */
+ switch (fragP->tc_frag_data->relax[ri].type)
+ {
+ case RL78_RELAX_BRANCH:
+ switch (optype)
+ {
+ case OT_bt:
+ newsize = 6;
+ break;
+ case OT_bt_sfr:
+ case OT_bt_es:
+ newsize = 7;
+ break;
+ case OT_bc:
+ newsize = 5;
+ break;
+ case OT_bh:
+ newsize = 6;
+ break;
+ case OT_other:
+ newsize = oldsize;
+ break;
+ }
+ break;
+
+ }
+ fragP->fr_subtype = newsize;
+ tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
+ return newsize - oldsize;
+ }
+
+ if (sym_addr > mypc)
+ addr0 += stretch;
+
+ switch (fragP->tc_frag_data->relax[ri].type)
+ {
+ case RL78_RELAX_BRANCH:
+ disp = (int) addr0 - (int) mypc;
+
+ switch (optype)
+ {
+ case OT_bt:
+ if (disp >= -128 && (disp - (oldsize-2)) <= 127)
+ newsize = 3;
+ else
+ newsize = 6;
+ break;
+ case OT_bt_sfr:
+ case OT_bt_es:
+ if (disp >= -128 && (disp - (oldsize-3)) <= 127)
+ newsize = 4;
+ else
+ newsize = 7;
+ break;
+ case OT_bc:
+ if (disp >= -128 && (disp - (oldsize-1)) <= 127)
+ newsize = 2;
+ else
+ newsize = 5;
+ break;
+ case OT_bh:
+ if (disp >= -128 && (disp - (oldsize-2)) <= 127)
+ newsize = 3;
+ else
+ newsize = 6;
+ break;
+ case OT_other:
+ newsize = oldsize;
+ break;
+ }
+ break;
+ }
+
+ /* This prevents infinite loops in align-heavy sources. */
+ if (newsize < oldsize)
+ {
+ if (fragP->tc_frag_data->times_shrank > 10
+ && fragP->tc_frag_data->times_grown > 10)
+ newsize = oldsize;
+ if (fragP->tc_frag_data->times_shrank < 20)
+ fragP->tc_frag_data->times_shrank ++;
+ }
+ else if (newsize > oldsize)
+ {
+ if (fragP->tc_frag_data->times_grown < 20)
+ fragP->tc_frag_data->times_grown ++;
+ }
+
+ fragP->fr_subtype = newsize;
+ tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
+ return newsize - oldsize;
+ }
+
+/* This lets us test for the opcode type and the desired size in a
+ switch statement. */
+#define OPCODE(type,size) ((type) * 16 + (size))
+
+/* Given the opcode stored in fr_opcode and the number of bytes we
+ think we need, encode a new opcode. We stored a pointer to the
+ fixup for this opcode in the tc_frag_data structure. If we can do
+ the fixup here, we change the relocation type to "none" (we test
+ for that in tc_gen_reloc) else we change it to the right type for
+ the new (biggest) opcode. */
+
+void
+md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+ segT segment ATTRIBUTE_UNUSED,
+ fragS * fragP ATTRIBUTE_UNUSED)
+{
+ rl78_bytesT * rl78b = fragP->tc_frag_data;
+ addressT addr0, mypc;
+ int disp;
+ int reloc_type, reloc_adjust;
+ char * op = fragP->fr_opcode;
+ int keep_reloc = 0;
+ int ri;
+ int fi = (rl78b->n_fixups > 1) ? 1 : 0;
+ fixS * fix = rl78b->fixups[fi].fixP;
+
+ /* If we ever get more than one reloc per opcode, this is the one
+ we're relaxing. */
+ ri = 0;
+
+ /* We used a new frag for this opcode, so the opcode address should
+ be the frag address. */
+ mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
+ tprintf("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
+
+ /* Try to get the target address. If we fail here, we just use the
+ largest format. */
+ if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
+ fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
+ {
+ /* We don't know the target address. */
+ keep_reloc = 1;
+ addr0 = 0;
+ disp = 0;
+ tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
+ }
+ else
+ {
+ /* We know the target address, and it's in addr0. */
+ disp = (int) addr0 - (int) mypc;
+ tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp);
+ }
+
+ if (linkrelax)
+ keep_reloc = 1;
+
+ reloc_type = BFD_RELOC_NONE;
+ reloc_adjust = 0;
+
+ switch (fragP->tc_frag_data->relax[ri].type)
+ {
+ case RL78_RELAX_BRANCH:
+ switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
+ {
+
+ case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
+ disp -= 3;
+ op[2] = disp;
+ break;
+
+ case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
+ disp -= 3;
+ op[1] ^= 0x06; /* toggle conditional. */
+ op[2] = 3; /* displacement over long branch. */
+ disp -= 3;
+ op[3] = 0xEE; /* BR $!addr20 */
+ op[4] = disp & 0xff;
+ op[5] = disp >> 8;
+ reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
+ reloc_adjust = 2;
+ break;
+
+ case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
+ disp -= 4;
+ op[3] = disp;
+ break;
+
+ case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
+ disp -= 4;
+ op[1] ^= 0x06; /* toggle conditional. */
+ op[3] = 3; /* displacement over long branch. */
+ disp -= 3;
+ op[4] = 0xEE; /* BR $!addr20 */
+ op[5] = disp & 0xff;
+ op[6] = disp >> 8;
+ reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
+ reloc_adjust = 2;
+ break;
+
+ case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
+ disp -= 4;
+ op[3] = disp;
+ break;
+
+ case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
+ disp -= 4;
+ op[2] ^= 0x06; /* toggle conditional. */
+ op[3] = 3; /* displacement over long branch. */
+ disp -= 3;
+ op[4] = 0xEE; /* BR $!addr20 */
+ op[5] = disp & 0xff;
+ op[6] = disp >> 8;
+ reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
+ reloc_adjust = 2;
+ break;
+
+ case OPCODE (OT_bc, 2): /* BC $ - no change. */
+ disp -= 2;
+ op[1] = disp;
+ break;
+
+ case OPCODE (OT_bc, 5): /* BC $ - long version. */
+ disp -= 2;
+ op[0] ^= 0x02; /* toggle conditional. */
+ op[1] = 3;
+ disp -= 3;
+ op[2] = 0xEE; /* BR $!addr20 */
+ op[3] = disp & 0xff;
+ op[4] = disp >> 8;
+ reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
+ reloc_adjust = 2;
+ break;
+
+ case OPCODE (OT_bh, 3): /* BH $ - no change. */
+ disp -= 3;
+ op[2] = disp;
+ break;
+
+ case OPCODE (OT_bh, 6): /* BC $ - long version. */
+ disp -= 3;
+ op[1] ^= 0x10; /* toggle conditional. */
+ op[2] = 3;
+ disp -= 3;
+ op[3] = 0xEE; /* BR $!addr20 */
+ op[4] = disp & 0xff;
+ op[5] = disp >> 8;
+ reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
+ reloc_adjust = 2;
+ break;
+
+ default:
+ fprintf(stderr, "Missed case %d %d at 0x%lx\n",
+ rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype, mypc);
+ abort ();
+
+ }
+ break;
+
+ default:
+ if (rl78b->n_fixups)
+ {
+ reloc_type = fix->fx_r_type;
+ reloc_adjust = 0;
+ }
+ break;
+ }
+
+ if (rl78b->n_fixups)
+ {
+
+ fix->fx_r_type = reloc_type;
+ fix->fx_where += reloc_adjust;
+ switch (reloc_type)
+ {
+ case BFD_RELOC_NONE:
+ fix->fx_size = 0;
+ break;
+ case BFD_RELOC_8:
+ fix->fx_size = 1;
+ break;
+ case BFD_RELOC_16_PCREL:
+ fix->fx_size = 2;
+ break;
+ }
+ }
+
+ fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
+ tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
+ fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
+ fragP->fr_var = 0;
+
+ tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
+ (long)fragP->fr_fix,
+ (long)fragP->fr_next->fr_address, (long)fragP->fr_address,
+ (long)(fragP->fr_next->fr_address - fragP->fr_address),
+ fragP->fr_next);
+
+ if (fragP->fr_next != NULL
+ && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
+ != fragP->fr_fix))
+ as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
+ (long) fragP->fr_fix,
+ (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
}
+/* End of relaxation code.
+ ----------------------------------------------------------------------*/
+
+
arelent **
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
{
@@ -688,8 +1229,8 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
break;
case BFD_RELOC_RL78_CODE:
- SYM0 ();
- OP (ABS16);
+ reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
+ reloc[1] = NULL;
break;
case BFD_RELOC_RL78_LO16:
@@ -791,13 +1332,23 @@ md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
f->fx_done = 1;
break;
- case BFD_RELOC_8:
case BFD_RELOC_8_PCREL:
+ if ((long)val < -128 || (long)val > 127)
+ as_bad_where (f->fx_file, f->fx_line,
+ _("value of %ld too large for 8-bit branch"),
+ val);
+ /* Fall through. */
+ case BFD_RELOC_8:
op[0] = val;
break;
- case BFD_RELOC_16:
case BFD_RELOC_16_PCREL:
+ if ((long)val < -32768 || (long)val > 32767)
+ as_bad_where (f->fx_file, f->fx_line,
+ _("value of %ld too large for 16-bit branch"),
+ val);
+ /* Fall through. */
+ case BFD_RELOC_16:
case BFD_RELOC_RL78_CODE:
op[0] = val;
op[1] = val >> 8;
@@ -810,13 +1361,38 @@ md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
break;
case BFD_RELOC_32:
- case BFD_RELOC_RL78_DIFF:
op[0] = val;
op[1] = val >> 8;
op[2] = val >> 16;
op[3] = val >> 24;
break;
+ case BFD_RELOC_RL78_DIFF:
+ op[0] = val;
+ if (f->fx_size > 1)
+ op[1] = val >> 8;
+ if (f->fx_size > 2)
+ op[2] = val >> 16;
+ if (f->fx_size > 3)
+ op[3] = val >> 24;
+ break;
+
+ case BFD_RELOC_RL78_HI8:
+ val = val >> 16;
+ op[0] = val;
+ break;
+
+ case BFD_RELOC_RL78_HI16:
+ val = val >> 16;
+ op[0] = val;
+ op[1] = val >> 8;
+ break;
+
+ case BFD_RELOC_RL78_LO16:
+ op[0] = val;
+ op[1] = val >> 8;
+ break;
+
default:
as_bad (_("Unknown reloc in md_apply_fix: %s"),
bfd_get_reloc_code_name (f->fx_r_type));
@@ -833,12 +1409,3 @@ md_section_align (segT segment, valueT size)
int align = bfd_get_section_alignment (stdoutput, segment);
return ((size + (1 << align) - 1) & (-1 << align));
}
-
-void
-md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
- segT segment ATTRIBUTE_UNUSED,
- fragS * fragP ATTRIBUTE_UNUSED)
-{
- /* No relaxation yet */
- fragP->fr_var = 0;
-}
diff --git a/binutils-2.25/gas/config/tc-rl78.h b/binutils-2.25/gas/config/tc-rl78.h
index 67f12c96..5b6a3125 100644
--- a/binutils-2.25/gas/config/tc-rl78.h
+++ b/binutils-2.25/gas/config/tc-rl78.h
@@ -1,5 +1,5 @@
/* tc-rl78.h - header file for Renesas RL78
- Copyright 2011-2013 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -49,6 +49,9 @@ extern int target_little_endian;
#define md_end rl78_md_end
extern void rl78_md_end (void);
+#define md_relax_frag rl78_relax_frag
+extern int rl78_relax_frag (segT, fragS *, long);
+
#define TC_FRAG_TYPE struct rl78_bytesT *
#define TC_FRAG_INIT rl78_frag_init
extern void rl78_frag_init (fragS *);
@@ -64,7 +67,7 @@ extern long md_pcrel_from_section (struct fix *, segT);
rl78_validate_fix_sub (FIX)
extern int rl78_validate_fix_sub (struct fix *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RET) \
rl78_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
extern void rl78_cons_fix_new (fragS *, int, int, expressionS *);
diff --git a/binutils-2.25/gas/config/tc-rx.c b/binutils-2.25/gas/config/tc-rx.c
index f15ed93c..0d7e1d56 100644
--- a/binutils-2.25/gas/config/tc-rx.c
+++ b/binutils-2.25/gas/config/tc-rx.c
@@ -1,5 +1,5 @@
/* tc-rx.c -- Assembler for the Renesas RX
- Copyright 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -20,7 +20,6 @@
#include "as.h"
#include "struc-symbol.h"
-#include "obstack.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
#include "libbfd.h"
@@ -244,7 +243,7 @@ rx_include (int ignore)
char * path;
char * filename;
char * current_filename;
- char * eof;
+ char * last_char;
char * p;
char * d;
char * f;
@@ -263,17 +262,17 @@ rx_include (int ignore)
/* Get the filename. Spaces are allowed, NUL characters are not. */
filename = input_line_pointer;
- eof = find_end_of_line (filename, FALSE);
- input_line_pointer = eof;
-
- while (eof >= filename && (* eof == ' ' || * eof == '\n'))
- -- eof;
- end_char = *(++ eof);
- * eof = 0;
- if (eof == filename)
+ last_char = find_end_of_line (filename, FALSE);
+ input_line_pointer = last_char;
+
+ while (last_char >= filename && (* last_char == ' ' || * last_char == '\n'))
+ -- last_char;
+ end_char = *(++ last_char);
+ * last_char = 0;
+ if (last_char == filename)
{
as_bad (_("no filename following .INCLUDE pseudo-op"));
- * eof = end_char;
+ * last_char = end_char;
return;
}
@@ -385,7 +384,7 @@ rx_include (int ignore)
input_scrub_insert_file (path);
}
- * eof = end_char;
+ * last_char = end_char;
}
static void
@@ -2170,10 +2169,9 @@ void
rx_cons_fix_new (fragS * frag,
int where,
int size,
- expressionS * exp)
+ expressionS * exp,
+ bfd_reloc_code_real_type type)
{
- bfd_reloc_code_real_type type;
-
switch (size)
{
case 1:
diff --git a/binutils-2.25/gas/config/tc-rx.h b/binutils-2.25/gas/config/tc-rx.h
index 6f2db1ca..b82812d6 100644
--- a/binutils-2.25/gas/config/tc-rx.h
+++ b/binutils-2.25/gas/config/tc-rx.h
@@ -1,6 +1,5 @@
/* tc-rx.h - header file for Renesas RX
- Copyright 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -69,9 +68,10 @@ extern long md_pcrel_from_section (struct fix *, segT);
rx_validate_fix_sub (FIX)
extern int rx_validate_fix_sub (struct fix *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
- rx_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
-extern void rx_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \
+ rx_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC)
+extern void rx_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
#define tc_fix_adjustable(x) 0
diff --git a/binutils-2.25/gas/config/tc-s390.c b/binutils-2.25/gas/config/tc-s390.c
index c504f18a..59f6ab6c 100644
--- a/binutils-2.25/gas/config/tc-s390.c
+++ b/binutils-2.25/gas/config/tc-s390.c
@@ -1,6 +1,5 @@
/* tc-s390.c -- Assemble for the S390
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-s390.h b/binutils-2.25/gas/config/tc-s390.h
index f896e447..88c857b0 100644
--- a/binutils-2.25/gas/config/tc-s390.h
+++ b/binutils-2.25/gas/config/tc-s390.h
@@ -1,6 +1,5 @@
/* tc-s390.h -- Header file for tc-s390.c.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
Written by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-score.c b/binutils-2.25/gas/config/tc-score.c
index 822b9cfd..72597a0f 100644
--- a/binutils-2.25/gas/config/tc-score.c
+++ b/binutils-2.25/gas/config/tc-score.c
@@ -1,5 +1,5 @@
/* tc-score.c -- Assembler for Score
- Copyright 2006, 2007, 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
Contributed by:
Brain.lin (brain.lin@sunplusct.com)
Mei Ligang (ligang@sunnorth.com.cn)
@@ -5363,7 +5363,7 @@ s3_parse_pce_inst (char *insnstr)
|| ((pec_part_1.size == s3_INSN16_SIZE) && (s3_inst.size == s3_INSN_SIZE)))
{
s3_inst.error = _("pce instruction error (16 bit || 16 bit)'");
- sprintf (s3_inst.str, insnstr);
+ sprintf (s3_inst.str, "%s", insnstr);
return;
}
@@ -6315,7 +6315,7 @@ s3_build_score_ops_hsh (void)
for (i = 0; i < sizeof (s3_score_insns) / sizeof (struct s3_asm_opcode); i++)
{
const struct s3_asm_opcode *insn = s3_score_insns + i;
- unsigned len = strlen (insn->template_name);
+ size_t len = strlen (insn->template_name);
struct s3_asm_opcode *new_opcode;
char *template_name;
new_opcode = (struct s3_asm_opcode *)
@@ -6344,7 +6344,7 @@ s3_build_dependency_insn_hsh (void)
for (i = 0; i < sizeof (s3_insn_to_dependency_table) / sizeof (s3_insn_to_dependency_table[0]); i++)
{
const struct s3_insn_to_dependency *tmp = s3_insn_to_dependency_table + i;
- unsigned len = strlen (tmp->insn_name);
+ size_t len = strlen (tmp->insn_name);
struct s3_insn_to_dependency *new_i2n;
new_i2n = (struct s3_insn_to_dependency *)
@@ -6854,8 +6854,8 @@ s3_relax_branch_inst16 (fragS * fragp)
frag_addr = 0;
else
{
- if (s->bsym != 0)
- symbol_address = (addressT) s->sy_frag->fr_address;
+ if (s->bsym != NULL)
+ symbol_address = (addressT) symbol_get_frag (s)->fr_address;
}
inst_value = s3_md_chars_to_number (fragp->fr_literal, s3_INSN16_SIZE);
@@ -6901,8 +6901,8 @@ s3_relax_cmpbranch_inst32 (fragS * fragp)
frag_addr = 0;
else
{
- if (s->bsym != 0)
- symbol_address = (addressT) s->sy_frag->fr_address;
+ if (s->bsym != NULL)
+ symbol_address = (addressT) symbol_get_frag (s)->fr_address;
}
inst_value = s3_md_chars_to_number (fragp->fr_literal, s3_INSN_SIZE);
diff --git a/binutils-2.25/gas/config/tc-score.h b/binutils-2.25/gas/config/tc-score.h
index b46ef798..5b11f301 100644
--- a/binutils-2.25/gas/config/tc-score.h
+++ b/binutils-2.25/gas/config/tc-score.h
@@ -1,5 +1,5 @@
/* tc-score.h -- Score specific file for assembler
- Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
Contributed by:
Brain.lin (brain.lin@sunplusct.com)
Mei Ligang (ligang@sunnorth.com.cn)
diff --git a/binutils-2.25/gas/config/tc-score7.c b/binutils-2.25/gas/config/tc-score7.c
index 520bd070..ae15a049 100644
--- a/binutils-2.25/gas/config/tc-score7.c
+++ b/binutils-2.25/gas/config/tc-score7.c
@@ -1,5 +1,5 @@
/* tc-score7.c -- Assembler for Score7
- Copyright 2009, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by:
Brain.lin (brain.lin@sunplusct.com)
Mei Ligang (ligang@sunnorth.com.cn)
@@ -2795,7 +2795,7 @@ s7_parse_16_32_inst (char *insnstr, bfd_boolean gen_frag_p)
*p = c;
memset (&s7_inst, '\0', sizeof (s7_inst));
- sprintf (s7_inst.str, "%s", insnstr);
+ strcpy (s7_inst.str, insnstr);
if (opcode)
{
s7_inst.instruction = opcode->value;
@@ -2804,7 +2804,7 @@ s7_parse_16_32_inst (char *insnstr, bfd_boolean gen_frag_p)
s7_inst.size = s7_GET_INSN_SIZE (s7_inst.type);
s7_inst.relax_size = 0;
s7_inst.bwarn = 0;
- sprintf (s7_inst.name, "%s", opcode->template_name);
+ strcpy (s7_inst.name, opcode->template_name);
strcpy (s7_inst.reg, "");
s7_inst.error = NULL;
s7_inst.reloc.type = BFD_RELOC_NONE;
@@ -5090,7 +5090,7 @@ s7_build_score_ops_hsh (void)
for (i = 0; i < sizeof (s7_score_insns) / sizeof (struct s7_asm_opcode); i++)
{
const struct s7_asm_opcode *insn = s7_score_insns + i;
- unsigned len = strlen (insn->template_name);
+ size_t len = strlen (insn->template_name);
struct s7_asm_opcode *new_opcode;
char *template_name;
new_opcode = (struct s7_asm_opcode *)
@@ -5119,7 +5119,7 @@ s7_build_dependency_insn_hsh (void)
for (i = 0; i < ARRAY_SIZE (s7_insn_to_dependency_table); i++)
{
const struct s7_insn_to_dependency *tmp = s7_insn_to_dependency_table + i;
- unsigned len = strlen (tmp->insn_name);
+ size_t len = strlen (tmp->insn_name);
struct s7_insn_to_dependency *new_i2d;
new_i2d = (struct s7_insn_to_dependency *)
@@ -5263,8 +5263,8 @@ s7_b32_relax_to_b16 (fragS * fragp)
frag_addr = 0;
else
{
- if (s->bsym != 0)
- symbol_address = (addressT) s->sy_frag->fr_address;
+ if (s->bsym != NULL)
+ symbol_address = (addressT) symbol_get_frag (s)->fr_address;
}
value = s7_md_chars_to_number (fragp->fr_literal, s7_INSN_SIZE);
@@ -5308,12 +5308,12 @@ s7_parse_pce_inst (char *insnstr)
p = strstr (insnstr, "||");
c = *p;
*p = '\0';
- sprintf (first, "%s", insnstr);
+ strcpy (first, insnstr);
/* Get second part string of PCE. */
*p = c;
p += 2;
- sprintf (second, "%s", p);
+ strcpy (second, p);
s7_parse_16_32_inst (first, FALSE);
if (s7_inst.error)
@@ -5337,7 +5337,7 @@ s7_parse_pce_inst (char *insnstr)
|| ((pec_part_1.size == s7_INSN16_SIZE) && (s7_inst.size == s7_INSN_SIZE)))
{
s7_inst.error = _("pce instruction error (16 bit || 16 bit)'");
- sprintf (s7_inst.str, insnstr);
+ strcpy (s7_inst.str, insnstr);
return;
}
diff --git a/binutils-2.25/gas/config/tc-sh.c b/binutils-2.25/gas/config/tc-sh.c
index 6b7bd5a3..6e9ae921 100644
--- a/binutils-2.25/gas/config/tc-sh.c
+++ b/binutils-2.25/gas/config/tc-sh.c
@@ -1,7 +1,5 @@
/* tc-sh.c -- Assemble code for the Renesas / SuperH SH
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -767,9 +765,10 @@ sh_check_fixup (expressionS *main_exp, bfd_reloc_code_real_type *r_type_p)
/* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
void
-sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
+sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp,
+ bfd_reloc_code_real_type r_type)
{
- bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED;
+ r_type = BFD_RELOC_UNUSED;
if (sh_check_fixup (exp, &r_type))
as_bad (_("Invalid PIC expression."));
@@ -4436,7 +4435,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
if (SWITCH_TABLE (fixp))
{
*rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
- rel->addend = 0;
+ rel->addend = rel->address - S_GET_VALUE(fixp->fx_subsy);
if (r_type == BFD_RELOC_16)
r_type = BFD_RELOC_SH_SWITCH16;
else if (r_type == BFD_RELOC_8)
diff --git a/binutils-2.25/gas/config/tc-sh.h b/binutils-2.25/gas/config/tc-sh.h
index 2a696272..97b6b6d5 100644
--- a/binutils-2.25/gas/config/tc-sh.h
+++ b/binutils-2.25/gas/config/tc-sh.h
@@ -1,6 +1,5 @@
/* This file is tc-sh.h
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -233,9 +232,10 @@ extern bfd_boolean sh_fix_adjustable (struct fix *);
int sh_parse_name (char const *, expressionS *,
enum expr_mode, char *);
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
- sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
-void sh_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+ sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP), (RELOC))
+void sh_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
/* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
symbols. The relocation type is stored in X_md. */
diff --git a/binutils-2.25/gas/config/tc-sh64.c b/binutils-2.25/gas/config/tc-sh64.c
index db698460..eba0a5be 100644
--- a/binutils-2.25/gas/config/tc-sh64.c
+++ b/binutils-2.25/gas/config/tc-sh64.c
@@ -1,6 +1,5 @@
/* tc-sh64.c -- Assemble code for the SuperH SH SHcompact and SHmedia.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-sh64.h b/binutils-2.25/gas/config/tc-sh64.h
index e01b3dea..35702a02 100644
--- a/binutils-2.25/gas/config/tc-sh64.h
+++ b/binutils-2.25/gas/config/tc-sh64.h
@@ -1,6 +1,5 @@
/* This file is tc-sh64.h
- Copyright 2000, 2001, 2002, 2003, 2005, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-sparc.c b/binutils-2.25/gas/config/tc-sparc.c
index bcb84642..758fcc81 100644
--- a/binutils-2.25/gas/config/tc-sparc.c
+++ b/binutils-2.25/gas/config/tc-sparc.c
@@ -1,5 +1,5 @@
/* tc-sparc.c -- Assemble for the SPARC
- Copyright 1989-2013 Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
@@ -77,11 +77,11 @@ static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO;
#ifndef TE_SOLARIS
/* Bitmask of instruction types seen so far, used to populate the
GNU attributes section with hwcap information. */
-static int hwcap_seen;
+static bfd_uint64_t hwcap_seen;
#endif
#endif
-static int hwcap_allowed;
+static bfd_uint64_t hwcap_allowed;
static int architecture_requested;
static int warn_on_bump;
@@ -221,6 +221,25 @@ static void output_insn (const struct sparc_opcode *, struct sparc_it *);
enum sparc_arch_types {v6, v7, v8, leon, sparclet, sparclite, sparc86x, v8plus,
v8plusa, v9, v9a, v9b, v9_64};
+/* Hardware capability sets, used to keep sparc_arch_table easy to
+ read. */
+#define HWS_V8 HWCAP_MUL32 | HWCAP_DIV32 | HWCAP_FSMULD
+#define HWS_V9 HWS_V8 | HWCAP_POPC
+#define HWS_VA HWS_V9 | HWCAP_VIS
+#define HWS_VB HWS_VA | HWCAP_VIS2
+#define HWS_VC HWS_VB | HWCAP_ASI_BLK_INIT
+#define HWS_VD HWS_VC | HWCAP_FMAF | HWCAP_VIS3 | HWCAP_HPC
+#define HWS_VE HWS_VD \
+ | HWCAP_AES | HWCAP_DES | HWCAP_KASUMI | HWCAP_CAMELLIA \
+ | HWCAP_MD5 | HWCAP_SHA1 | HWCAP_SHA256 |HWCAP_SHA512 | HWCAP_MPMUL \
+ | HWCAP_MONT | HWCAP_CRC32C | HWCAP_CBCOND | HWCAP_PAUSE
+#define HWS_VV HWS_VE | HWCAP_FJFMAU | HWCAP_IMA
+#define HWS_VM HWS_VV
+
+#define HWS2_VM \
+ HWCAP2_VIS3B | HWCAP2_ADP | HWCAP2_SPARC5 | HWCAP2_MWAIT \
+ | HWCAP2_XMPMUL | HWCAP2_XMONT
+
static struct sparc_arch {
char *name;
char *opcode_arch;
@@ -231,41 +250,50 @@ static struct sparc_arch {
/* Allowable arg to -A? */
int user_option_p;
int hwcap_allowed;
+ int hwcap2_allowed;
} sparc_arch_table[] = {
- { "v6", "v6", v6, 0, 1, 0 },
- { "v7", "v7", v7, 0, 1, 0 },
- { "v8", "v8", v8, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
- { "v8a", "v8", v8, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
- { "sparc", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS },
- { "sparcvis", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS },
- { "sparcvis2", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2 },
- { "sparcfmaf", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF },
- { "sparcima", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_IMA },
- { "sparcvis3", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC },
- { "sparcvis3r", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU },
- { "sparc4", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND|HWCAP_PAUSE },
- { "leon", "leon", leon, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
- { "sparclet", "sparclet", sparclet, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
- { "sparclite", "sparclite", sparclite, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
- { "sparc86x", "sparclite", sparc86x, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
- { "v8plus", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS },
- { "v8plusa", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS },
- { "v8plusb", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2 },
- { "v8plusc", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT },
- { "v8plusd", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC },
- { "v8pluse", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND|HWCAP_PAUSE },
- { "v8plusv", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND|HWCAP_PAUSE },
- { "v9", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC },
- { "v9a", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS },
- { "v9b", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2 },
- { "v9c", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT },
- { "v9d", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC },
- { "v9e", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND|HWCAP_PAUSE },
- { "v9v", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND|HWCAP_PAUSE },
- /* This exists to allow configure.in/Makefile.in to pass one
+ { "v6", "v6", v6, 0, 1, 0, 0 },
+ { "v7", "v7", v7, 0, 1, 0, 0 },
+ { "v8", "v8", v8, 32, 1, HWS_V8, 0 },
+ { "v8a", "v8", v8, 32, 1, HWS_V8, 0 },
+ { "sparc", "v9", v9, 0, 1, HWCAP_V8PLUS|HWS_V9, 0 },
+ { "sparcvis", "v9a", v9, 0, 1, HWS_VA, 0 },
+ { "sparcvis2", "v9b", v9, 0, 1, HWS_VB, 0 },
+ { "sparcfmaf", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF, 0 },
+ { "sparcima", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF|HWCAP_IMA, 0 },
+ { "sparcvis3", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC, 0 },
+ { "sparcvis3r", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_FJFMAU, 0 },
+
+ { "sparc4", "v9b", v9, 0, 1, HWS_VV, 0 },
+ { "sparc5", "v9b", v9, 0, 1, HWS_VM, HWS2_VM },
+
+ { "leon", "leon", leon, 32, 1, HWS_V8, 0 },
+ { "sparclet", "sparclet", sparclet, 32, 1, HWS_V8, 0 },
+ { "sparclite", "sparclite", sparclite, 32, 1, HWS_V8, 0 },
+ { "sparc86x", "sparclite", sparc86x, 32, 1, HWS_V8, 0 },
+
+ { "v8plus", "v9", v9, 0, 1, HWCAP_V8PLUS|HWS_V9, 0 },
+ { "v8plusa", "v9a", v9, 0, 1, HWCAP_V8PLUS|HWS_VA, 0 },
+ { "v8plusb", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VB, 0 },
+ { "v8plusc", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VC, 0 },
+ { "v8plusd", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VD, 0 },
+ { "v8pluse", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VE, 0 },
+ { "v8plusv", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VV, 0 },
+ { "v8plusm", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VM, 0 },
+
+ { "v9", "v9", v9, 0, 1, HWS_V9, 0 },
+ { "v9a", "v9a", v9, 0, 1, HWS_VA, 0 },
+ { "v9b", "v9b", v9, 0, 1, HWS_VB, 0 },
+ { "v9c", "v9b", v9, 0, 1, HWS_VC, 0 },
+ { "v9d", "v9b", v9, 0, 1, HWS_VD, 0 },
+ { "v9e", "v9b", v9, 0, 1, HWS_VE, 0 },
+ { "v9v", "v9b", v9, 0, 1, HWS_VV, 0 },
+ { "v9m", "v9b", v9, 0, 1, HWS_VM, HWS2_VM },
+
+ /* This exists to allow configure.tgt to pass one
value to specify both the default machine and default word size. */
- { "v9-64", "v9", v9, 64, 0, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC },
- { NULL, NULL, v8, 0, 0, 0 }
+ { "v9-64", "v9", v9, 64, 0, HWS_V9, 0 },
+ { NULL, NULL, v8, 0, 0, 0, 0 }
};
/* Variant of default_arch */
@@ -516,7 +544,8 @@ md_parse_option (int c, char *arg)
if (!architecture_requested
|| opcode_arch > max_architecture)
max_architecture = opcode_arch;
- hwcap_allowed |= sa->hwcap_allowed;
+ hwcap_allowed
+ |= (((bfd_uint64_t) sa->hwcap2_allowed) << 32) | sa->hwcap_allowed;
architecture_requested = 1;
}
break;
@@ -787,6 +816,8 @@ struct priv_reg_entry hpriv_reg_table[] =
{"hintp", 3},
{"htba", 5},
{"hver", 6},
+ {"hstick_offset", 28},
+ {"hstick_enable", 29},
{"hstick_cmpr", 31},
{"", -1}, /* End marker. */
};
@@ -808,9 +839,9 @@ struct priv_reg_entry v9a_asr_table[] =
{"pause", 27},
{"pic", 17},
{"pcr", 16},
+ {"mwait", 28},
{"gsr", 19},
{"dcr", 18},
- {"cps", 28},
{"cfr", 26},
{"clear_softint", 21},
{"", -1}, /* End marker. */
@@ -914,16 +945,24 @@ md_begin (void)
/* `max_architecture' records the requested architecture.
Issue warnings if we go above it. */
warn_after_architecture = max_architecture;
-
- /* Find the highest architecture level that doesn't conflict with
- the requested one. */
- for (max_architecture = SPARC_OPCODE_ARCH_MAX;
- max_architecture > warn_after_architecture;
- --max_architecture)
- if (! SPARC_OPCODE_CONFLICT_P (max_architecture,
- warn_after_architecture))
- break;
}
+
+ /* Find the highest architecture level that doesn't conflict with
+ the requested one. */
+
+ if (warn_on_bump
+ || !architecture_requested)
+ {
+ enum sparc_opcode_arch_val current_max_architecture
+ = max_architecture;
+
+ for (max_architecture = SPARC_OPCODE_ARCH_MAX;
+ max_architecture > warn_after_architecture;
+ --max_architecture)
+ if (! SPARC_OPCODE_CONFLICT_P (max_architecture,
+ current_max_architecture))
+ break;
+ }
}
/* Called after all assembly has been done. */
@@ -932,6 +971,9 @@ void
sparc_md_end (void)
{
unsigned long mach = bfd_mach_sparc;
+#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
+ int hwcaps, hwcaps2;
+#endif
if (sparc_arch_size == 64)
switch (current_architecture)
@@ -955,8 +997,13 @@ sparc_md_end (void)
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, mach);
#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
- if (hwcap_seen)
- bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS, hwcap_seen);
+ hwcaps = hwcap_seen & U0xffffffff;
+ hwcaps2 = hwcap_seen >> 32;
+
+ if (hwcaps)
+ bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS, hwcaps);
+ if (hwcaps2)
+ bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS2, hwcaps2);
#endif
}
@@ -1412,7 +1459,7 @@ md_assemble (char *str)
}
static const char *
-get_hwcap_name (int mask)
+get_hwcap_name (bfd_uint64_t mask)
{
if (mask & HWCAP_MUL32)
return "mul32";
@@ -1472,6 +1519,25 @@ get_hwcap_name (int mask)
return "cbcond";
if (mask & HWCAP_CRC32C)
return "crc32c";
+
+ mask = mask >> 32;
+ if (mask & HWCAP2_FJATHPLUS)
+ return "fjathplus";
+ if (mask & HWCAP2_VIS3B)
+ return "vis3b";
+ if (mask & HWCAP2_ADP)
+ return "adp";
+ if (mask & HWCAP2_SPARC5)
+ return "sparc5";
+ if (mask & HWCAP2_MWAIT)
+ return "mwait";
+ if (mask & HWCAP2_XMPMUL)
+ return "xmpmul";
+ if (mask & HWCAP2_XMONT)
+ return "xmont";
+ if (mask & HWCAP2_NSEC)
+ return "nsec";
+
return "UNKNOWN";
}
@@ -2296,6 +2362,7 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
case 'g':
case 'H':
case 'J':
+ case '}':
{
char format;
@@ -2358,6 +2425,13 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
break;
} /* if not an 'f' register. */
+ if (*args == '}' && mask != RS2 (opcode))
+ {
+ error_message
+ = _(": Instruction requires frs2 and frsd must be the same register");
+ goto error;
+ }
+
switch (*args)
{
case 'v':
@@ -2380,6 +2454,7 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
case 'g':
case 'H':
case 'J':
+ case '}':
opcode |= RD (mask);
continue;
} /* Pack it in. */
@@ -2833,6 +2908,12 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
s += 5;
continue;
+ case '{':
+ if (strncmp (s, "%mcdper",7) != 0)
+ break;
+ s += 7;
+ continue;
+
case 'E':
if (strncmp (s, "%ccr", 4) != 0)
break;
@@ -2923,7 +3004,8 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
{
/* We have a match. Now see if the architecture is OK. */
int needed_arch_mask = insn->architecture;
- int hwcaps = insn->hwcaps;
+ bfd_uint64_t hwcaps
+ = (((bfd_uint64_t) insn->hwcaps2) << 32) | insn->hwcaps;
#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
if (hwcaps)
@@ -2961,6 +3043,7 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
warn_after_architecture = needed_architecture;
}
current_architecture = needed_architecture;
+ hwcap_allowed |= hwcaps;
}
/* Conflict. */
/* ??? This seems to be a bit fragile. What if the next entry in
@@ -4266,11 +4349,6 @@ s_proc (int ignore ATTRIBUTE_UNUSED)
static int sparc_no_align_cons = 0;
-/* This static variable is set by sparc_cons to emit requested types
- of relocations in cons_fix_new_sparc. */
-
-static const char *sparc_cons_special_reloc;
-
/* This handles the unaligned space allocation pseudo-ops, such as
.uaword. .uaword is just like .word, but the value does not need
to be aligned. */
@@ -4538,13 +4616,13 @@ sparc_elf_final_processing (void)
elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1|EF_SPARC_SUN_US3;
}
-void
+const char *
sparc_cons (expressionS *exp, int size)
{
char *save;
+ const char *sparc_cons_special_reloc = NULL;
SKIP_WHITESPACE ();
- sparc_cons_special_reloc = NULL;
save = input_line_pointer;
if (input_line_pointer[0] == '%'
&& input_line_pointer[1] == 'r'
@@ -4671,6 +4749,7 @@ sparc_cons (expressionS *exp, int size)
}
if (sparc_cons_special_reloc == NULL)
expression (exp);
+ return sparc_cons_special_reloc;
}
#endif
@@ -4683,7 +4762,8 @@ void
cons_fix_new_sparc (fragS *frag,
int where,
unsigned int nbytes,
- expressionS *exp)
+ expressionS *exp,
+ const char *sparc_cons_special_reloc)
{
bfd_reloc_code_real_type r;
@@ -4732,7 +4812,6 @@ cons_fix_new_sparc (fragS *frag,
}
fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
- sparc_cons_special_reloc = NULL;
}
void
@@ -4786,9 +4865,7 @@ sparc_regname_to_dw2regnum (char *regname)
void
sparc_cfi_emit_pcrel_expr (expressionS *exp, unsigned int nbytes)
{
- sparc_cons_special_reloc = "disp";
sparc_no_align_cons = 1;
- emit_expr (exp, nbytes);
+ emit_expr_with_reloc (exp, nbytes, "disp");
sparc_no_align_cons = 0;
- sparc_cons_special_reloc = NULL;
}
diff --git a/binutils-2.25/gas/config/tc-sparc.h b/binutils-2.25/gas/config/tc-sparc.h
index 5671c140..ef76c0b9 100644
--- a/binutils-2.25/gas/config/tc-sparc.h
+++ b/binutils-2.25/gas/config/tc-sparc.h
@@ -1,7 +1,5 @@
/* tc-sparc.h - Macros and type defines for the sparc.
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -157,14 +155,17 @@ extern void sparc_md_end (void);
#endif
+#define TC_PARSE_CONS_RETURN_TYPE const char *
+#define TC_PARSE_CONS_RETURN_NONE NULL
+
#ifdef OBJ_ELF
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) sparc_cons (EXP, NBYTES)
-extern void sparc_cons (expressionS *, int);
+extern const char *sparc_cons (expressionS *, int);
#endif
#define TC_CONS_FIX_NEW cons_fix_new_sparc
extern void cons_fix_new_sparc
- (struct frag *, int, unsigned int, struct expressionS *);
+(struct frag *, int, unsigned int, struct expressionS *, const char *);
#define TC_FIX_TYPE valueT
diff --git a/binutils-2.25/gas/config/tc-spu.c b/binutils-2.25/gas/config/tc-spu.c
index d80c6217..717cc330 100644
--- a/binutils-2.25/gas/config/tc-spu.c
+++ b/binutils-2.25/gas/config/tc-spu.c
@@ -1,6 +1,6 @@
/* spu.c -- Assembler for the IBM Synergistic Processing Unit (SPU)
- Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-spu.h b/binutils-2.25/gas/config/tc-spu.h
index 5047d35e..08393448 100644
--- a/binutils-2.25/gas/config/tc-spu.h
+++ b/binutils-2.25/gas/config/tc-spu.h
@@ -1,6 +1,6 @@
/* spu.h -- Assembler for spu
- Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-tic30.c b/binutils-2.25/gas/config/tc-tic30.c
index 570c833d..dbcbf3c8 100644
--- a/binutils-2.25/gas/config/tc-tic30.c
+++ b/binutils-2.25/gas/config/tc-tic30.c
@@ -1,6 +1,5 @@
/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
This file is part of GAS, the GNU Assembler.
@@ -85,11 +84,11 @@ debug (const char *string, ...)
if (flag_debug)
{
char str[100];
+ va_list argptr;
- VA_OPEN (argptr, string);
- VA_FIXEDARG (argptr, const char *, string);
+ va_start (argptr, string);
vsprintf (str, string, argptr);
- VA_CLOSE (argptr);
+ va_end (argptr);
if (str[0] == '\0')
return (0);
fputs (str, USE_STDOUT ? stdout : stderr);
diff --git a/binutils-2.25/gas/config/tc-tic30.h b/binutils-2.25/gas/config/tc-tic30.h
index a5ec412a..e39d7b0e 100644
--- a/binutils-2.25/gas/config/tc-tic30.h
+++ b/binutils-2.25/gas/config/tc-tic30.h
@@ -1,5 +1,5 @@
/* tc-tic30.h -- Header file for tc-tic30.c
- Copyright 1998, 2000, 2002, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-tic4x.c b/binutils-2.25/gas/config/tc-tic4x.c
index dd21000b..dc821680 100644
--- a/binutils-2.25/gas/config/tc-tic4x.c
+++ b/binutils-2.25/gas/config/tc-tic4x.c
@@ -1,6 +1,5 @@
/* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
- Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010,
- 2012 Free Software Foundation. Inc.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
@@ -44,7 +43,6 @@
#include "safe-ctype.h"
#include "opcode/tic4x.h"
#include "subsegs.h"
-#include "obstack.h"
/* OK, we accept a syntax similar to the other well known C30
assembly tools. With TIC4X_ALT_SYNTAX defined we are more
@@ -82,7 +80,7 @@ static unsigned long tic4x_oplevel = 0; /* Opcode level */
#define OPTION_ENHANCED (OPTION_MD_BASE + 7)
#define OPTION_REV (OPTION_MD_BASE + 8)
-CONST char *md_shortopts = "bm:prs";
+const char *md_shortopts = "bm:prs";
struct option md_longopts[] =
{
{ "mcpu", required_argument, NULL, OPTION_CPU },
@@ -2458,7 +2456,7 @@ md_assemble (char *str)
if (*s) /* Null terminate for hash_find. */
*s++ = '\0'; /* and skip past null. */
strcat (insn->name, "_");
- strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
+ strncat (insn->name, str, TIC4X_NAME_MAX - 1 - strlen (insn->name));
insn->operands[insn->num_operands++].mode = M_PARALLEL;
diff --git a/binutils-2.25/gas/config/tc-tic4x.h b/binutils-2.25/gas/config/tc-tic4x.h
index b35eaa77..14b3511c 100644
--- a/binutils-2.25/gas/config/tc-tic4x.h
+++ b/binutils-2.25/gas/config/tc-tic4x.h
@@ -1,6 +1,5 @@
/* tc-tic4x.h -- Assemble for the Texas TMS320C[34]X.
- Copyright (C) 1997, 2002, 2003, 2005, 2007, 2008
- Free Software Foundation. Inc.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
diff --git a/binutils-2.25/gas/config/tc-tic54x.c b/binutils-2.25/gas/config/tc-tic54x.c
index d4bd75fd..c9972975 100644
--- a/binutils-2.25/gas/config/tc-tic54x.c
+++ b/binutils-2.25/gas/config/tc-tic54x.c
@@ -1,6 +1,5 @@
/* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Contributed by Timothy Wall (twall@cygnus.com)
This file is part of GAS, the GNU Assembler.
@@ -2369,13 +2368,13 @@ tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
FILE *ftmp;
/* We're not sure how big it is, but it will be smaller than "size". */
- bfd_bread (buf, size, mbfd);
+ size = bfd_bread (buf, size, mbfd);
/* Write to a temporary file, then use s_include to include it
a bit of a hack. */
ftmp = fopen (fname, "w+b");
fwrite ((void *) buf, size, 1, ftmp);
- if (buf[size - 1] != '\n')
+ if (size == 0 || buf[size - 1] != '\n')
fwrite ("\n", 1, 1, ftmp);
fclose (ftmp);
free (buf);
@@ -4778,7 +4777,7 @@ tic54x_start_line_hook (void)
line[endp - input_line_pointer] = 0;
/* Scan ahead for parallel insns. */
- parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
+ parallel_on_next_line_hint = next_line_shows_parallel (endp);
/* If within a macro, first process forced replacements. */
if (macro_level > 0)
@@ -5122,10 +5121,9 @@ tc_gen_reloc (asection *section, fixS *fixP)
/* Handle cons expressions. */
void
-tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn)
+tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
+ bfd_reloc_code_real_type r)
{
- bfd_reloc_code_real_type r;
-
switch (octets)
{
default:
diff --git a/binutils-2.25/gas/config/tc-tic54x.h b/binutils-2.25/gas/config/tc-tic54x.h
index 93342deb..3fe8be88 100644
--- a/binutils-2.25/gas/config/tc-tic54x.h
+++ b/binutils-2.25/gas/config/tc-tic54x.h
@@ -1,5 +1,5 @@
/* tc-tic54x.h -- Header file for tc-tic54x.c
- Copyright 1999, 2000, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Contributed by Timothy Wall (twall@alum.mit.edu)
This file is part of GAS, the GNU Assembler.
@@ -69,8 +69,10 @@ struct bit_info
extern int tic54x_start_label (int, char *);
/* custom handling for relocations in cons expressions */
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) tic54x_cons_fix_new(FRAG,OFF,LEN,EXP)
-extern void tic54x_cons_fix_new (fragS *,int,int,expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+ tic54x_cons_fix_new (FRAG, OFF, LEN, EXP, RELOC)
+extern void tic54x_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
/* Define md_number_to_chars as the appropriate standard big endian or
little endian function. Mostly littleendian, but longwords and floats are
diff --git a/binutils-2.25/gas/config/tc-tic6x.c b/binutils-2.25/gas/config/tc-tic6x.c
index 81f33f40..3f2912af 100644
--- a/binutils-2.25/gas/config/tc-tic6x.c
+++ b/binutils-2.25/gas/config/tc-tic6x.c
@@ -1,5 +1,5 @@
/* TI C6X assembler.
- Copyright 2010-2013 Free Software Foundation, Inc.
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
Contributed by Joseph Myers <joseph@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com>
@@ -536,6 +536,7 @@ s_tic6x_ehtype (int ignored ATTRIBUTE_UNUSED)
}
p = frag_more (4);
+ memset (p, 0, 4);
fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
&exp, 0, BFD_RELOC_C6000_EHTYPE);
@@ -2012,10 +2013,9 @@ tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp,
go through the error checking in tic6x_fix_new_exp. */
void
-tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp)
+tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp,
+ bfd_reloc_code_real_type r_type)
{
- bfd_reloc_code_real_type r_type;
-
switch (size)
{
case 1:
@@ -3824,7 +3824,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
if (value < -0x80 || value > 0xff)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("value too large for 1-byte field"));
- md_number_to_chars (buf, value, 1);
+ *buf = value;
}
break;
@@ -4836,6 +4836,7 @@ tic6x_output_exidx_entry (void)
record_alignment (now_seg, 2);
ptr = frag_more (8);
+ memset (ptr, 0, 8);
where = frag_now_fix () - 8;
/* Self relative offset of the function start. */
diff --git a/binutils-2.25/gas/config/tc-tic6x.h b/binutils-2.25/gas/config/tc-tic6x.h
index 12bdead0..dc110e89 100644
--- a/binutils-2.25/gas/config/tc-tic6x.h
+++ b/binutils-2.25/gas/config/tc-tic6x.h
@@ -1,6 +1,5 @@
/* Definitions for TI C6X assembler.
- Copyright 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -185,10 +184,10 @@ extern long tic6x_pcrel_from_section (struct fix *fixp, segT sec);
#define md_start_line_hook() tic6x_start_line_hook ()
extern void tic6x_start_line_hook (void);
-#define TC_CONS_FIX_NEW(frag, where, size, exp) \
- tic6x_cons_fix_new (frag, where, size, exp)
-extern void tic6x_cons_fix_new (fragS *frag, int where, int size,
- expressionS *exp);
+#define TC_CONS_FIX_NEW(frag, where, size, exp, reloc) \
+ tic6x_cons_fix_new (frag, where, size, exp, reloc)
+extern void tic6x_cons_fix_new (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
#define tc_fix_adjustable(FIX) tic6x_fix_adjustable (FIX)
extern bfd_boolean tic6x_fix_adjustable (struct fix *);
diff --git a/binutils-2.25/gas/config/tc-tilegx.c b/binutils-2.25/gas/config/tc-tilegx.c
index 19a04c27..3176d2f3 100644
--- a/binutils-2.25/gas/config/tc-tilegx.c
+++ b/binutils-2.25/gas/config/tc-tilegx.c
@@ -1,5 +1,5 @@
/* tc-tilegx.c -- Assemble for a Tile-Gx chip.
- Copyright 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-tilegx.h b/binutils-2.25/gas/config/tc-tilegx.h
index ec8a40d0..6de89da0 100644
--- a/binutils-2.25/gas/config/tc-tilegx.h
+++ b/binutils-2.25/gas/config/tc-tilegx.h
@@ -1,5 +1,5 @@
/* tc-tilegx.h - Macros and type defines for a TILE-Gx chip.
- Copyright 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -53,7 +53,7 @@ struct tilegx_operand;
extern void tilegx_cons_fix_new (struct frag *, int,
int, struct expressionS *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \
tilegx_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
extern int tilegx_parse_name (char *, expressionS *, char *);
diff --git a/binutils-2.25/gas/config/tc-tilepro.c b/binutils-2.25/gas/config/tc-tilepro.c
index 733a628f..8a378c0d 100644
--- a/binutils-2.25/gas/config/tc-tilepro.c
+++ b/binutils-2.25/gas/config/tc-tilepro.c
@@ -1,5 +1,5 @@
/* tc-tilepro.c -- Assemble for a TILEPro chip.
- Copyright 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-tilepro.h b/binutils-2.25/gas/config/tc-tilepro.h
index 5374d267..92d31b15 100644
--- a/binutils-2.25/gas/config/tc-tilepro.h
+++ b/binutils-2.25/gas/config/tc-tilepro.h
@@ -1,5 +1,5 @@
/* tc-tile.h - Macros and type defines for a TILEPro chip.
- Copyright 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -54,7 +54,7 @@ struct tilepro_operand;
extern void tilepro_cons_fix_new (struct frag *, int,
int, struct expressionS *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \
tilepro_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
extern int tilepro_parse_name (char *, expressionS *, char *);
diff --git a/binutils-2.25/gas/config/tc-v850.c b/binutils-2.25/gas/config/tc-v850.c
index a23387c1..91acec4e 100644
--- a/binutils-2.25/gas/config/tc-v850.c
+++ b/binutils-2.25/gas/config/tc-v850.c
@@ -1,5 +1,5 @@
/* tc-v850.c -- Assembler code for the NEC V850
- Copyright 1996-2013 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -27,9 +27,6 @@
/* Sign-extend a 16-bit number. */
#define SEXT16(x) ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)
-/* Temporarily holds the reloc in a cons expression. */
-static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED;
-
/* Set to TRUE if we want to be pedantic about signed overflows. */
static bfd_boolean warn_signed_overflows = FALSE;
static bfd_boolean warn_unsigned_overflows = FALSE;
@@ -2032,6 +2029,12 @@ handle_lo16 (const struct v850_operand *operand, const char **errmsg)
static bfd_reloc_code_real_type
handle_ctoff (const struct v850_operand *operand, const char **errmsg)
{
+ if (v850_target_arch == bfd_arch_v850_rh850)
+ {
+ *errmsg = _("ctoff() is not supported by the rh850 ABI. Use -mgcc-abi instead");
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
if (operand == NULL)
return BFD_RELOC_V850_CALLT_16_16_OFFSET;
@@ -2156,7 +2159,7 @@ v850_reloc_prefix (const struct v850_operand *operand, const char **errmsg)
if (paren_skipped)
--input_line_pointer;
- return BFD_RELOC_UNUSED;
+ return BFD_RELOC_NONE;
}
/* Insert an operand value into an instruction. */
@@ -2407,7 +2410,7 @@ md_assemble (char *str)
input_line_pointer = str;
/* lo(), hi(), hi0(), etc... */
- if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_UNUSED)
+ if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_NONE)
{
/* This is a fake reloc, used to indicate an error condition. */
if (reloc == BFD_RELOC_64)
@@ -2977,7 +2980,7 @@ md_assemble (char *str)
fixups[fc].exp = ex;
fixups[fc].opindex = *opindex_ptr;
- fixups[fc].reloc = BFD_RELOC_UNUSED;
+ fixups[fc].reloc = BFD_RELOC_NONE;
++fc;
break;
}
@@ -3239,7 +3242,7 @@ md_assemble (char *str)
reloc = fixups[i].reloc;
- if (reloc != BFD_RELOC_UNUSED)
+ if (reloc != BFD_RELOC_NONE)
{
reloc_howto_type *reloc_howto =
bfd_reloc_type_lookup (stdoutput, reloc);
@@ -3634,15 +3637,18 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
/* Parse a cons expression. We have to handle hi(), lo(), etc
on the v850. */
-void
+bfd_reloc_code_real_type
parse_cons_expression_v850 (expressionS *exp)
{
const char *errmsg;
+ bfd_reloc_code_real_type r;
+
/* See if there's a reloc prefix like hi() we have to handle. */
- hold_cons_reloc = v850_reloc_prefix (NULL, &errmsg);
+ r = v850_reloc_prefix (NULL, &errmsg);
/* Do normal expression parsing. */
expression (exp);
+ return r;
}
/* Create a fixup for a cons expression. If parse_cons_expression_v850
@@ -3653,24 +3659,23 @@ void
cons_fix_new_v850 (fragS *frag,
int where,
int size,
- expressionS *exp)
+ expressionS *exp,
+ bfd_reloc_code_real_type r)
{
- if (hold_cons_reloc == BFD_RELOC_UNUSED)
+ if (r == BFD_RELOC_NONE)
{
if (size == 4)
- hold_cons_reloc = BFD_RELOC_32;
+ r = BFD_RELOC_32;
if (size == 2)
- hold_cons_reloc = BFD_RELOC_16;
+ r = BFD_RELOC_16;
if (size == 1)
- hold_cons_reloc = BFD_RELOC_8;
+ r = BFD_RELOC_8;
}
if (exp != NULL)
- fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
+ fix_new_exp (frag, where, size, exp, 0, r);
else
- fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
-
- hold_cons_reloc = BFD_RELOC_UNUSED;
+ fix_new (frag, where, size, NULL, 0, 0, r);
}
bfd_boolean
diff --git a/binutils-2.25/gas/config/tc-v850.h b/binutils-2.25/gas/config/tc-v850.h
index 27627705..a0aeeb4f 100644
--- a/binutils-2.25/gas/config/tc-v850.h
+++ b/binutils-2.25/gas/config/tc-v850.h
@@ -1,6 +1,5 @@
/* tc-v850.h -- Header file for tc-v850.c.
- Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -59,10 +58,11 @@ extern int v850_force_relocation (struct fix *);
/* We need to handle lo(), hi(), etc etc in .hword, .word, etc
directives, so we have to parse "cons" expressions ourselves. */
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_v850 (EXP)
-extern void parse_cons_expression_v850 (expressionS *);
+extern bfd_reloc_code_real_type parse_cons_expression_v850 (expressionS *);
#define TC_CONS_FIX_NEW cons_fix_new_v850
-extern void cons_fix_new_v850 (fragS *, int, int, expressionS *);
+extern void cons_fix_new_v850 (fragS *, int, int, expressionS *,
+ bfd_reloc_code_real_type);
#define TC_GENERIC_RELAX_TABLE md_relax_table
extern const struct relax_type md_relax_table[];
diff --git a/binutils-2.25/gas/config/tc-vax.c b/binutils-2.25/gas/config/tc-vax.c
index 185a9a24..bccf596b 100644
--- a/binutils-2.25/gas/config/tc-vax.c
+++ b/binutils-2.25/gas/config/tc-vax.c
@@ -1,7 +1,5 @@
/* tc-vax.c - vax-specific -
- Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1998, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -280,15 +278,21 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
{
valueT value = * valueP;
- if (((fixP->fx_addsy == NULL && fixP->fx_subsy == NULL)
- && fixP->fx_r_type != BFD_RELOC_32_PLT_PCREL
- && fixP->fx_r_type != BFD_RELOC_32_GOT_PCREL)
- || fixP->fx_r_type == NO_RELOC)
- number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
- value, fixP->fx_size);
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
- if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
+
+ if (fixP->fx_done)
+ number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
+ value, fixP->fx_size);
+ else
+ /* Initialise the part of an instruction frag covered by the
+ relocation. (Many occurrences of frag_more followed by fix_new
+ lack any init of the frag.) Since VAX uses RELA relocs the
+ value we write into this field doesn't really matter. */
+ memset (fixP->fx_where + fixP->fx_frag->fr_literal, 0, fixP->fx_size);
}
/* Convert a number from VAX byte order (little endian)
@@ -2338,7 +2342,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
if (fixp->fx_tcbit)
abort ();
- if (fixp->fx_r_type != BFD_RELOC_NONE)
+ if (fixp->fx_r_type != NO_RELOC)
{
code = fixp->fx_r_type;
@@ -3266,12 +3270,11 @@ md_begin (void)
}
}
-static char *vax_cons_special_reloc;
-
-void
+bfd_reloc_code_real_type
vax_cons (expressionS *exp, int size)
{
char *save;
+ char *vax_cons_special_reloc;
SKIP_WHITESPACE ();
vax_cons_special_reloc = NULL;
@@ -3375,35 +3378,29 @@ vax_cons (expressionS *exp, int size)
}
if (vax_cons_special_reloc == NULL)
expression (exp);
+ else
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8_PCREL;
+ case 2: return BFD_RELOC_16_PCREL;
+ case 4: return BFD_RELOC_32_PCREL;
+ }
+ return NO_RELOC;
}
/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
reloc for a cons. */
void
-vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp)
+vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp,
+ bfd_reloc_code_real_type r)
{
- bfd_reloc_code_real_type r;
-
- r = (nbytes == 1 ? BFD_RELOC_8 :
- (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32));
-
- if (vax_cons_special_reloc)
- {
- if (*vax_cons_special_reloc == 'p')
- {
- switch (nbytes)
- {
- case 1: r = BFD_RELOC_8_PCREL; break;
- case 2: r = BFD_RELOC_16_PCREL; break;
- case 4: r = BFD_RELOC_32_PCREL; break;
- default: abort ();
- }
- }
- }
+ if (r == NO_RELOC)
+ r = (nbytes == 1 ? BFD_RELOC_8
+ : nbytes == 2 ? BFD_RELOC_16
+ : BFD_RELOC_32);
fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
- vax_cons_special_reloc = NULL;
}
char *
diff --git a/binutils-2.25/gas/config/tc-vax.h b/binutils-2.25/gas/config/tc-vax.h
index 84722ff1..cc94bb22 100644
--- a/binutils-2.25/gas/config/tc-vax.h
+++ b/binutils-2.25/gas/config/tc-vax.h
@@ -1,6 +1,5 @@
/* tc-vax.h -- Header file for tc-vax.c.
- Copyright 1987, 1991, 1992, 1993, 1995, 1996, 1997, 2000, 2002, 2005,
- 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -50,8 +49,9 @@
#ifdef OBJ_ELF
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) vax_cons (EXP, NBYTES)
#define TC_CONS_FIX_NEW vax_cons_fix_new
-void vax_cons (expressionS *, int);
-void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *);
+bfd_reloc_code_real_type vax_cons (expressionS *, int);
+void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *,
+ bfd_reloc_code_real_type);
#endif
extern const struct relax_type md_relax_table[];
diff --git a/binutils-2.25/gas/config/tc-xc16x.c b/binutils-2.25/gas/config/tc-xc16x.c
index c628d866..6073387b 100644
--- a/binutils-2.25/gas/config/tc-xc16x.c
+++ b/binutils-2.25/gas/config/tc-xc16x.c
@@ -1,5 +1,5 @@
/* tc-xc16x.c -- Assembler for the Infineon XC16X.
- Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
Contributed by KPIT Cummins Infosystems
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-xc16x.h b/binutils-2.25/gas/config/tc-xc16x.h
index 61230d19..03bfec99 100644
--- a/binutils-2.25/gas/config/tc-xc16x.h
+++ b/binutils-2.25/gas/config/tc-xc16x.h
@@ -1,5 +1,5 @@
/* This file is tc-xc16x.h
- Copyright 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
Contributed by KPIT Cummins Infosystems
This file is part of GAS, the GNU Assembler.
@@ -32,10 +32,8 @@
#define FAKE_LABEL_NAME ".L0\001"
#endif
-#if ANSI_PROTOTYPES
struct fix;
struct internal_reloc;
-#endif
#define WORKING_DOT_WORD
diff --git a/binutils-2.25/gas/config/tc-xgate.c b/binutils-2.25/gas/config/tc-xgate.c
index 7ed1ef62..f244c579 100644
--- a/binutils-2.25/gas/config/tc-xgate.c
+++ b/binutils-2.25/gas/config/tc-xgate.c
@@ -1,6 +1,5 @@
/* tc-xgate.c -- Assembler code for Freescale XGATE
- Copyright 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
Contributed by Sean Keys <skeys@ipdatasys.com>
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-xgate.h b/binutils-2.25/gas/config/tc-xgate.h
index 04349a7e..30cff98d 100644
--- a/binutils-2.25/gas/config/tc-xgate.h
+++ b/binutils-2.25/gas/config/tc-xgate.h
@@ -1,5 +1,5 @@
/* tc-xgate.h -- Header file for tc-xgate.c.
- Copyright 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-xstormy16.c b/binutils-2.25/gas/config/tc-xstormy16.c
index 74c5bcea..e8eba894 100644
--- a/binutils-2.25/gas/config/tc-xstormy16.c
+++ b/binutils-2.25/gas/config/tc-xstormy16.c
@@ -1,6 +1,5 @@
/* tc-xstormy16.c -- Assembler for the Sanyo XSTORMY16.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
- Free Software Foundation.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -194,10 +193,9 @@ void
xstormy16_cons_fix_new (fragS *f,
int where,
int nbytes,
- expressionS *exp)
+ expressionS *exp,
+ bfd_reloc_code_real_type code)
{
- bfd_reloc_code_real_type code;
-
if (exp->X_op == O_fptr_symbol)
{
switch (nbytes)
diff --git a/binutils-2.25/gas/config/tc-xstormy16.h b/binutils-2.25/gas/config/tc-xstormy16.h
index 5e1fb862..064a85cb 100644
--- a/binutils-2.25/gas/config/tc-xstormy16.h
+++ b/binutils-2.25/gas/config/tc-xstormy16.h
@@ -1,5 +1,5 @@
/* tc-xstormy16.h -- Header file for tc-xstormy16.c.
- Copyright 2000, 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -57,7 +57,8 @@ extern int xstormy16_force_relocation (struct fix *);
extern long md_pcrel_from_section (struct fix *, segT);
#define TC_CONS_FIX_NEW xstormy16_cons_fix_new
-extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *);
+extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *,
+ bfd_reloc_code_real_type);
#define md_cgen_record_fixup_exp xstormy16_cgen_record_fixup_exp
diff --git a/binutils-2.25/gas/config/tc-xtensa.c b/binutils-2.25/gas/config/tc-xtensa.c
index 70755310..d11b0c7f 100644
--- a/binutils-2.25/gas/config/tc-xtensa.c
+++ b/binutils-2.25/gas/config/tc-xtensa.c
@@ -1,6 +1,5 @@
/* tc-xtensa.c -- Assemble Xtensa instructions.
- Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -469,6 +468,12 @@ static void xtensa_set_frag_assembly_state (fragS *);
static void finish_vinsn (vliw_insn *);
static bfd_boolean emit_single_op (TInsn *);
static int total_frag_text_expansion (fragS *);
+static bfd_boolean use_trampolines = TRUE;
+static void xtensa_check_frag_count (void);
+static void xtensa_create_trampoline_frag (bfd_boolean);
+static void xtensa_maybe_create_trampoline_frag (void);
+struct trampoline_frag;
+static int init_trampoline_frag (struct trampoline_frag *);
/* Alignment Functions. */
@@ -521,6 +526,7 @@ static void tinsn_from_chars (TInsn *, char *, int);
static void tinsn_immed_from_frag (TInsn *, fragS *, int);
static int get_num_stack_text_bytes (IStack *);
static int get_num_stack_literal_bytes (IStack *);
+static bfd_boolean tinsn_to_slotbuf (xtensa_format, int, TInsn *, xtensa_insnbuf);
/* vliw_insn functions. */
@@ -688,7 +694,10 @@ enum
option_prefer_l32r,
option_prefer_const16,
- option_target_hardware
+ option_target_hardware,
+
+ option_trampolines,
+ option_no_trampolines,
};
const char *md_shortopts = "";
@@ -761,6 +770,9 @@ struct option md_longopts[] =
{ "target-hardware", required_argument, NULL, option_target_hardware },
+ { "trampolines", no_argument, NULL, option_trampolines },
+ { "no-trampolines", no_argument, NULL, option_no_trampolines },
+
{ NULL, no_argument, NULL, 0 }
};
@@ -941,6 +953,14 @@ md_parse_option (int c, char *arg)
directive_state[directive_transform] = FALSE;
return 1;
+ case option_trampolines:
+ use_trampolines = TRUE;
+ return 1;
+
+ case option_no_trampolines:
+ use_trampolines = FALSE;
+ return 1;
+
default:
return 0;
}
@@ -964,7 +984,9 @@ Xtensa options:\n\
flix bundles\n\
--no-allow-flix neither allow hand-written nor generate\n\
flix bundles\n\
- --rename-section old=new Rename section 'old' to 'new'\n", stream);
+ --rename-section old=new Rename section 'old' to 'new'\n\
+ --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\
+ when jumps do not reach their targets\n", stream);
}
@@ -5569,6 +5591,8 @@ md_assemble (char *str)
/* We've just emitted a new instruction so clear the list of labels. */
xtensa_clear_insn_labels ();
+
+ xtensa_check_frag_count ();
}
@@ -5585,7 +5609,6 @@ xtensa_handle_align (fragS *fragP)
&& ! fragP->tc_frag_data.is_literal
&& (fragP->fr_type == rs_align
|| fragP->fr_type == rs_align_code)
- && fragP->fr_address + fragP->fr_fix > 0
&& fragP->fr_offset > 0
&& now_seg != bss_section)
{
@@ -5844,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
{
case BFD_RELOC_8:
fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8;
+ fixP->fx_signed = 1;
break;
case BFD_RELOC_16:
fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
+ fixP->fx_signed = 1;
break;
case BFD_RELOC_32:
fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
+ fixP->fx_signed = 1;
break;
default:
break;
@@ -6373,6 +6399,8 @@ finish_vinsn (vliw_insn *vinsn)
xg_assemble_vliw_tokens (vinsn);
xg_clear_vinsn (vinsn);
+
+ xtensa_check_frag_count ();
}
@@ -6935,7 +6963,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
if (frag_now_fix () != 0
&& (! frag_now->tc_frag_data.is_insn
|| (vinsn_has_specific_opcodes (vinsn) && use_transform ())
- || !use_transform () != frag_now->tc_frag_data.is_no_transform
+ || (!use_transform ()) != frag_now->tc_frag_data.is_no_transform
|| (directive_state[directive_longcalls]
!= frag_now->tc_frag_data.use_longcalls)
|| (directive_state[directive_absolute_literals]
@@ -7141,6 +7169,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
RELAX_UNREACHABLE,
frag_now->fr_symbol, frag_now->fr_offset, NULL);
xtensa_set_frag_assembly_state (frag_now);
+ xtensa_maybe_create_trampoline_frag ();
}
else if (is_branch && do_align_targets ())
{
@@ -7223,9 +7252,164 @@ xtensa_end (void)
xtensa_sanity_check ();
xtensa_add_config_info ();
+
+ xtensa_check_frag_count ();
+}
+
+
+struct trampoline_frag
+{
+ struct trampoline_frag *next;
+ bfd_boolean needs_jump_around;
+ fragS *fragP;
+ fixS *fixP;
+};
+
+struct trampoline_seg
+{
+ struct trampoline_seg *next;
+ asection *seg;
+ struct trampoline_frag trampoline_list;
+};
+
+static struct trampoline_seg trampoline_seg_list;
+#define J_RANGE (128 * 1024)
+
+static int unreachable_count = 0;
+
+
+static void
+xtensa_maybe_create_trampoline_frag (void)
+{
+ if (!use_trampolines)
+ return;
+
+ /* We create an area for possible trampolines every 10 unreachable frags.
+ These are preferred over the ones not preceded by an unreachable frag,
+ because we don't have to jump around them. This function is called after
+ each RELAX_UNREACHABLE frag is created. */
+
+ if (++unreachable_count > 10)
+ {
+ xtensa_create_trampoline_frag (FALSE);
+ clear_frag_count ();
+ unreachable_count = 0;
+ }
+}
+
+static void
+xtensa_check_frag_count (void)
+{
+ if (!use_trampolines || frag_now->tc_frag_data.is_no_transform)
+ return;
+
+ /* We create an area for possible trampolines every 8000 frags or so. This
+ is an estimate based on the max range of a "j" insn (+/-128K) divided
+ by a typical frag byte count (16), minus a few for safety. This function
+ is called after each source line is processed. */
+
+ if (get_frag_count () > 8000)
+ {
+ xtensa_create_trampoline_frag (TRUE);
+ clear_frag_count ();
+ unreachable_count = 0;
+ }
+}
+
+static xtensa_insnbuf trampoline_buf = NULL;
+static xtensa_insnbuf trampoline_slotbuf = NULL;
+
+#define TRAMPOLINE_FRAG_SIZE 3000
+
+static void
+xtensa_create_trampoline_frag (bfd_boolean needs_jump_around)
+{
+ /* Emit a frag where we can place intermediate jump instructions,
+ in case we need to jump farther than 128K bytes.
+ Each jump instruction takes three bytes.
+ We allocate enough for 1000 trampolines in each frag.
+ If that's not enough, oh well. */
+
+ struct trampoline_seg *ts = trampoline_seg_list.next;
+ struct trampoline_frag *tf;
+ char *varP;
+ fragS *fragP;
+ int size = TRAMPOLINE_FRAG_SIZE;
+
+ for ( ; ts; ts = ts->next)
+ {
+ if (ts->seg == now_seg)
+ break;
+ }
+
+ if (ts == NULL)
+ {
+ ts = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1);
+ ts->next = trampoline_seg_list.next;
+ trampoline_seg_list.next = ts;
+ ts->seg = now_seg;
+ }
+
+ frag_wane (frag_now);
+ frag_new (0);
+ xtensa_set_frag_assembly_state (frag_now);
+ varP = frag_var (rs_machine_dependent, size, size, RELAX_TRAMPOLINE, NULL, 0, NULL);
+ fragP = (fragS *)(varP - SIZEOF_STRUCT_FRAG);
+ if (trampoline_buf == NULL)
+ {
+ trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa);
+ trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa);
+ }
+ tf = (struct trampoline_frag *)xmalloc(sizeof (struct trampoline_frag));
+ tf->next = ts->trampoline_list.next;
+ ts->trampoline_list.next = tf;
+ tf->needs_jump_around = needs_jump_around;
+ tf->fragP = fragP;
+ tf->fixP = NULL;
+}
+
+
+static struct trampoline_seg *
+find_trampoline_seg (asection *seg)
+{
+ struct trampoline_seg *ts = trampoline_seg_list.next;
+
+ for ( ; ts; ts = ts->next)
+ {
+ if (ts->seg == seg)
+ return ts;
+ }
+
+ return NULL;
}
+void dump_trampolines (void);
+
+void
+dump_trampolines (void)
+{
+ struct trampoline_seg *ts = trampoline_seg_list.next;
+
+ for ( ; ts; ts = ts->next)
+ {
+ asection *seg = ts->seg;
+
+ if (seg == NULL)
+ continue;
+ fprintf(stderr, "SECTION %s\n", seg->name);
+ struct trampoline_frag *tf = ts->trampoline_list.next;
+ for ( ; tf; tf = tf->next)
+ {
+ if (tf->fragP == NULL)
+ continue;
+ fprintf(stderr, " 0x%08x: fix=%d, jump_around=%s\n",
+ (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix,
+ tf->needs_jump_around ? "T" : "F");
+ }
+ }
+}
+
static void
xtensa_cleanup_align_frags (void)
{
@@ -8709,6 +8893,149 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
new_stretch += relax_frag_for_align (fragP, stretch);
break;
+ case RELAX_TRAMPOLINE:
+ if (fragP->tc_frag_data.relax_seen)
+ {
+ segment_info_type *seginfo = seg_info (now_seg);
+ fragS *fP; /* The out-of-range jump. */
+ fixS *fixP;
+
+ /* Scan for jumps that will not reach. */
+ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next)
+ {
+ symbolS *s = fixP->fx_addsy;
+ xtensa_opcode opcode;
+ int target;
+ int addr;
+ int delta;
+
+ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP ||
+ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP)
+ continue;
+ xtensa_insnbuf_from_chars (isa, trampoline_buf,
+ (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where,
+ 0);
+ fmt = xtensa_format_decode (isa, trampoline_buf);
+ gas_assert (fmt != XTENSA_UNDEFINED);
+ slot = fixP->tc_fix_data.slot;
+ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf);
+ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf);
+ if (opcode != xtensa_j_opcode)
+ continue;
+ target = S_GET_VALUE (s);
+ addr = fixP->fx_frag->fr_address;
+ delta = target - addr + stretch;
+ if (delta > J_RANGE || delta < -1 * J_RANGE)
+ { /* Found an out-of-range jump; scan the list of trampolines for the best match. */
+ struct trampoline_seg *ts = find_trampoline_seg (now_seg);
+ struct trampoline_frag *tf = ts->trampoline_list.next;
+ struct trampoline_frag *prev = &ts->trampoline_list;
+ int lower = (target < addr) ? target : addr;
+ int upper = (target > addr) ? target : addr;
+ int midpoint = lower + (upper - lower) / 2;
+
+ if ((upper - lower) > 2 * J_RANGE)
+ {
+ /* One trampoline won't suffice; we need multiple jumps.
+ Jump to the trampoline that's farthest, but still in
+ range relative to the original "j" instruction. */
+ for ( ; tf; prev = tf, tf = tf->next )
+ {
+ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
+ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ;
+
+ if (addr == lower)
+ {
+ /* Forward jump. */
+ if (this_addr - addr < J_RANGE)
+ break;
+ }
+ else
+ {
+ /* Backward jump. */
+ if (next_addr == 0 || addr - next_addr > J_RANGE)
+ break;
+ }
+ }
+ }
+ else
+ {
+ struct trampoline_frag *best_tf = NULL;
+ int best_delta = 0;
+
+ for ( ; tf; prev = tf, tf = tf->next )
+ {
+ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
+ int this_delta = abs (this_addr - midpoint);
+
+ if (!best_tf || this_delta < best_delta)
+ {
+ best_tf = tf;
+ best_delta = this_delta;
+ }
+ }
+ tf = best_tf;
+ }
+ if (tf->fragP == fragP)
+ {
+ int trampaddr = fragP->fr_address + fragP->fr_fix;
+
+ if (abs (addr - trampaddr) < J_RANGE)
+ { /* The trampoline is in range of original; fix it! */
+ fixS *newfixP;
+ int offset;
+ TInsn insn;
+ symbolS *lsym;
+
+ new_stretch += init_trampoline_frag (tf);
+ offset = fragP->fr_fix; /* Where to assemble the j insn. */
+ lsym = fragP->fr_symbol;
+ fP = fixP->fx_frag;
+ /* Assemble a jump to the target label here. */
+ tinsn_init (&insn);
+ insn.insn_type = ITYPE_INSN;
+ insn.opcode = xtensa_j_opcode;
+ insn.ntok = 1;
+ set_expr_symbol_offset (&insn.tok[0], lsym, offset);
+ fmt = xg_get_single_format (xtensa_j_opcode);
+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf);
+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf);
+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3);
+ fragP->fr_fix += 3;
+ fragP->fr_var -= 3;
+ /* Add a fix-up for the original j insn. */
+ newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type);
+ newfixP->fx_no_overflow = 1;
+ newfixP->tc_fix_data.X_add_symbol = lsym;
+ newfixP->tc_fix_data.X_add_number = offset;
+ newfixP->tc_fix_data.slot = slot;
+ /* Move the fix-up from the original j insn to this one. */
+ fixP->fx_frag = fragP;
+ fixP->fx_where = fragP->fr_fix - 3;
+ fixP->tc_fix_data.slot = 0;
+ /* Adjust the jump around this trampoline (if present). */
+ if (tf->fixP != NULL)
+ {
+ tf->fixP->fx_offset += 3;
+ }
+ new_stretch += 3;
+ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */
+ /* Do we have room for more? */
+ if (fragP->fr_var < 3)
+ { /* No, convert to fill. */
+ frag_wane (fragP);
+ fragP->fr_subtype = 0;
+ /* Remove from the trampoline_list. */
+ prev->next = tf->next;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
default:
as_bad (_("bad relaxation state"));
}
@@ -9147,6 +9474,200 @@ bytes_to_stretch (fragS *this_frag,
}
+static struct trampoline_frag *
+search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only)
+{
+ struct trampoline_seg *ts = find_trampoline_seg (now_seg);
+ struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL;
+ struct trampoline_frag *best_tf = NULL;
+ int best_delta = 0;
+ int best_addr = 0;
+ symbolS *sym = tinsn->tok[0].X_add_symbol;
+ offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number;
+ offsetT addr = fragP->fr_address;
+ offsetT lower = (addr < target) ? addr : target;
+ offsetT upper = (addr > target) ? addr : target;
+ int delta = upper - lower;
+ offsetT midpoint = lower + delta / 2;
+ int this_delta = -1;
+ int this_addr = -1;
+
+ if (delta > 2 * J_RANGE)
+ {
+ /* One trampoline won't do; we need multiple.
+ Choose the farthest trampoline that's still in range of the original
+ and let a later pass finish the job. */
+ for ( ; tf; tf = tf->next)
+ {
+ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0;
+
+ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
+ if (lower == addr)
+ {
+ /* Forward jump. */
+ if (this_addr - addr < J_RANGE)
+ break;
+ }
+ else
+ {
+ /* Backward jump. */
+ if (next_addr == 0 || addr - next_addr > J_RANGE)
+ break;
+ }
+ if (abs (addr - this_addr) < J_RANGE)
+ return tf;
+
+ return NULL;
+ }
+ }
+ for ( ; tf; tf = tf->next)
+ {
+ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix;
+ this_delta = abs (this_addr - midpoint);
+ if (unreachable_only && tf->needs_jump_around)
+ continue;
+ if (!best_tf || this_delta < best_delta)
+ {
+ best_tf = tf;
+ best_delta = this_delta;
+ best_addr = this_addr;
+ }
+ }
+
+ if (best_tf &&
+ best_delta < J_RANGE &&
+ abs(best_addr - lower) < J_RANGE &&
+ abs(best_addr - upper) < J_RANGE)
+ return best_tf;
+
+ return NULL; /* No suitable trampoline found. */
+}
+
+
+static struct trampoline_frag *
+get_best_trampoline (TInsn *tinsn, fragS *fragP)
+{
+ struct trampoline_frag *tf = NULL;
+
+ tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */
+
+ if (tf == NULL)
+ tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */
+
+ return tf;
+}
+
+
+static void
+check_and_update_trampolines (void)
+{
+ struct trampoline_seg *ts = find_trampoline_seg (now_seg);
+ struct trampoline_frag *tf = ts->trampoline_list.next;
+ struct trampoline_frag *prev = &ts->trampoline_list;
+
+ for ( ; tf; prev = tf, tf = tf->next)
+ {
+ if (tf->fragP->fr_var < 3)
+ {
+ frag_wane (tf->fragP);
+ prev->next = tf->next;
+ tf->fragP = NULL;
+ }
+ }
+}
+
+
+static int
+init_trampoline_frag (struct trampoline_frag *trampP)
+{
+ fragS *fp = trampP->fragP;
+ int growth = 0;
+
+ if (fp->fr_fix == 0)
+ {
+ symbolS *lsym;
+ char label[10 + 2 * sizeof(fp)];
+ sprintf (label, ".L0_TR_%p", fp);
+
+ lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp);
+ fp->fr_symbol = lsym;
+ if (trampP->needs_jump_around)
+ {
+ /* Add a jump around this block of jumps, in case
+ control flows into this block. */
+ fixS *fixP;
+ TInsn insn;
+ xtensa_format fmt;
+ xtensa_isa isa = xtensa_default_isa;
+
+ fp->tc_frag_data.is_insn = 1;
+ /* Assemble a jump insn. */
+ tinsn_init (&insn);
+ insn.insn_type = ITYPE_INSN;
+ insn.opcode = xtensa_j_opcode;
+ insn.ntok = 1;
+ set_expr_symbol_offset (&insn.tok[0], lsym, 3);
+ fmt = xg_get_single_format (xtensa_j_opcode);
+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf);
+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf);
+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3);
+ fp->fr_fix += 3;
+ fp->fr_var -= 3;
+ growth = 3;
+ fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP);
+ trampP->fixP = fixP;
+ }
+ }
+ return growth;
+}
+
+
+static int
+add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag)
+{
+ fragS *tramp = trampP->fragP;
+ fixS *fixP;
+ int offset = tramp->fr_fix; /* Where to assemble the j insn. */
+ TInsn insn;
+ symbolS *lsym;
+ symbolS *tsym;
+ int toffset;
+ xtensa_format fmt;
+ xtensa_isa isa = xtensa_default_isa;
+ int growth = 0;
+
+ lsym = tramp->fr_symbol;
+ /* Assemble a jump to the target label in the trampoline frag. */
+ tsym = origfrag->tc_frag_data.slot_symbols[0];
+ toffset = origfrag-> tc_frag_data.slot_offsets[0];
+ tinsn_init (&insn);
+ insn.insn_type = ITYPE_INSN;
+ insn.opcode = xtensa_j_opcode;
+ insn.ntok = 1;
+ set_expr_symbol_offset (&insn.tok[0], tsym, toffset);
+ fmt = xg_get_single_format (xtensa_j_opcode);
+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf);
+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf);
+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3);
+ tramp->fr_fix += 3;
+ tramp->fr_var -= 3;
+ growth = 3;
+ /* add a fix-up for the trampoline jump. */
+ fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP);
+ /* Modify the jump at the start of this trampoline to point past the newly-added jump. */
+ fixP = trampP->fixP;
+ if (fixP)
+ fixP->fx_offset += 3;
+ /* Modify the original j to point here. */
+ origfrag->tc_frag_data.slot_symbols[0] = lsym;
+ origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3;
+ /* If trampoline is full, remove it from the list. */
+ check_and_update_trampolines ();
+
+ return growth;
+}
+
+
static long
relax_frag_immed (segT segP,
fragS *fragP,
@@ -9285,6 +9806,37 @@ relax_frag_immed (segT segP,
if (negatable_branch && istack.ninsn > 1)
update_next_frag_state (fragP);
+ /* If last insn is a jump, and it cannot reach its target, try to find a trampoline. */
+ if (istack.ninsn > 2 &&
+ istack.insn[istack.ninsn - 1].insn_type == ITYPE_LABEL &&
+ istack.insn[istack.ninsn - 2].insn_type == ITYPE_INSN &&
+ istack.insn[istack.ninsn - 2].opcode == xtensa_j_opcode)
+ {
+ TInsn *jinsn = &istack.insn[istack.ninsn - 2];
+
+ if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff))
+ {
+ struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP);
+
+ if (tf)
+ {
+ this_text_diff += init_trampoline_frag (tf);
+ this_text_diff += add_jump_to_trampoline (tf, fragP);
+ }
+ else
+ {
+ /* If target symbol is undefined, assume it will reach once linked. */
+ expressionS *exp = &istack.insn[istack.ninsn - 2].tok[0];
+
+ if (exp->X_op == O_symbol && S_IS_DEFINED (exp->X_add_symbol))
+ {
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _("jump target out of range; no usable trampoline found"));
+ }
+ }
+ }
+ }
+
return this_text_diff;
}
@@ -9405,6 +9957,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp)
else
as_bad (_("invalid relaxation fragment result"));
break;
+
+ case RELAX_TRAMPOLINE:
+ break;
}
fragp->fr_var = 0;
diff --git a/binutils-2.25/gas/config/tc-xtensa.h b/binutils-2.25/gas/config/tc-xtensa.h
index 969f24c2..4672bc60 100644
--- a/binutils-2.25/gas/config/tc-xtensa.h
+++ b/binutils-2.25/gas/config/tc-xtensa.h
@@ -1,6 +1,5 @@
/* tc-xtensa.h -- Header file for tc-xtensa.c.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -181,6 +180,11 @@ enum xtensa_relax_statesE
prevent the linker from changing the size of any frag between the
section start and the org frag. */
+ RELAX_TRAMPOLINE,
+ /* Every few thousand frags, we insert one of these, just in case we may
+ need some space for a trampoline (jump to a jump) because the function
+ has gotten too big. If not needed, it disappears. */
+
RELAX_NONE
};
diff --git a/binutils-2.25/gas/config/tc-z80.c b/binutils-2.25/gas/config/tc-z80.c
index 6d5b6210..54fa322c 100644
--- a/binutils-2.25/gas/config/tc-z80.c
+++ b/binutils-2.25/gas/config/tc-z80.c
@@ -1,5 +1,5 @@
/* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800
- Copyright 2005, 2006, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by Arnold Metselaar <arnold_m@operamail.com>
This file is part of GAS, the GNU Assembler.
@@ -467,7 +467,7 @@ wrong_mach (int ins_type)
if (ins_type & ins_err)
error (_(p));
else
- as_warn (_(p));
+ as_warn ("%s", _(p));
}
static void
@@ -544,12 +544,11 @@ parse_exp_not_indexed (const char *s, expressionS *op)
{
const char *p;
int indir;
- segT dummy;
p = skip_space (s);
op->X_md = indir = is_indir (p);
input_line_pointer = (char*) s ;
- dummy = expression (op);
+ expression (op);
switch (op->X_op)
{
case O_absent:
@@ -705,7 +704,6 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
{
char *p;
int lo, hi;
- fixS * fixp;
p = frag_more (1);
*p = val->X_add_number;
@@ -732,8 +730,8 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
}
else
{
- fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
- (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
+ (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
/* FIXME : Process constant offsets immediately. */
}
}
diff --git a/binutils-2.25/gas/config/tc-z80.h b/binutils-2.25/gas/config/tc-z80.h
index 48428a97..74098718 100644
--- a/binutils-2.25/gas/config/tc-z80.h
+++ b/binutils-2.25/gas/config/tc-z80.h
@@ -1,5 +1,5 @@
/* this is tc-z80.h
- Copyright 2005, 2006, 2007, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by Arnold Metselaar <arnold_m@operamail.com>
@@ -55,7 +55,7 @@
/* Define some functions to be called by generic code. */
#define md_end z80_md_end
#define md_start_line_hook() { if (z80_start_line_hook ()) continue; }
-#define TC_CONS_FIX_NEW z80_cons_fix_new
+#define TC_CONS_FIX_NEW(f,w,s,e,r) z80_cons_fix_new ((f), (w), (s), (e))
extern void z80_md_end (void);
extern int z80_start_line_hook (void);
diff --git a/binutils-2.25/gas/config/tc-z8k.c b/binutils-2.25/gas/config/tc-z8k.c
index 2442032e..3b5f0b80 100644
--- a/binutils-2.25/gas/config/tc-z8k.c
+++ b/binutils-2.25/gas/config/tc-z8k.c
@@ -1,6 +1,5 @@
/* tc-z8k.c -- Assemble code for the Zilog Z800n
- Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003,
- 2005, 2006, 2007, 2009, 2013 Free Software Foundation, Inc.
+ Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/tc-z8k.h b/binutils-2.25/gas/config/tc-z8k.h
index 454547ea..be5f6514 100644
--- a/binutils-2.25/gas/config/tc-z8k.h
+++ b/binutils-2.25/gas/config/tc-z8k.h
@@ -1,7 +1,5 @@
/* This file is tc-z8k.h
- Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1997, 1998,
- 2000, 2002, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-386bsd.h b/binutils-2.25/gas/config/te-386bsd.h
index d5bb1655..7228d9a5 100644
--- a/binutils-2.25/gas/config/te-386bsd.h
+++ b/binutils-2.25/gas/config/te-386bsd.h
@@ -1,6 +1,5 @@
/* te-386bsd.h -- 386BSD target environment declarations.
- Copyright 1987, 1990, 1991, 1992, 1993, 2000, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-aix5.h b/binutils-2.25/gas/config/te-aix5.h
index 1b1f33c0..91ba577c 100644
--- a/binutils-2.25/gas/config/te-aix5.h
+++ b/binutils-2.25/gas/config/te-aix5.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-armeabi.h b/binutils-2.25/gas/config/te-armeabi.h
index b6f1e36f..fdd78abe 100644
--- a/binutils-2.25/gas/config/te-armeabi.h
+++ b/binutils-2.25/gas/config/te-armeabi.h
@@ -1,4 +1,4 @@
-/* Copyright 2005, 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-armfbsdeabi.h b/binutils-2.25/gas/config/te-armfbsdeabi.h
new file mode 100644
index 00000000..8a72e21b
--- /dev/null
+++ b/binutils-2.25/gas/config/te-armfbsdeabi.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004-2014 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 3,
+ 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, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "te-freebsd.h"
+
+#define EABI_DEFAULT EF_ARM_EABI_VER5
diff --git a/binutils-2.25/gas/config/te-armfbsdvfp.h b/binutils-2.25/gas/config/te-armfbsdvfp.h
new file mode 100644
index 00000000..945ac7c4
--- /dev/null
+++ b/binutils-2.25/gas/config/te-armfbsdvfp.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 2004-2014 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 3,
+ 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, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "te-armfbsdeabi.h"
+
+#define FPU_DEFAULT FPU_ARCH_VFP
diff --git a/binutils-2.25/gas/config/te-armlinuxeabi.h b/binutils-2.25/gas/config/te-armlinuxeabi.h
index bcb20625..9147f772 100644
--- a/binutils-2.25/gas/config/te-armlinuxeabi.h
+++ b/binutils-2.25/gas/config/te-armlinuxeabi.h
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-dragonfly.h b/binutils-2.25/gas/config/te-dragonfly.h
index 45da36fe..9db1b390 100644
--- a/binutils-2.25/gas/config/te-dragonfly.h
+++ b/binutils-2.25/gas/config/te-dragonfly.h
@@ -1,5 +1,5 @@
/* te-dragonfly.h -- DragonFlyBSD target environment declarations.
- Copyright 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-dynix.h b/binutils-2.25/gas/config/te-dynix.h
index 1f84967c..05a497e4 100644
--- a/binutils-2.25/gas/config/te-dynix.h
+++ b/binutils-2.25/gas/config/te-dynix.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-epoc-pe.h b/binutils-2.25/gas/config/te-epoc-pe.h
index f2864a17..50dbd684 100644
--- a/binutils-2.25/gas/config/te-epoc-pe.h
+++ b/binutils-2.25/gas/config/te-epoc-pe.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-freebsd.h b/binutils-2.25/gas/config/te-freebsd.h
index 44f02584..37442941 100644
--- a/binutils-2.25/gas/config/te-freebsd.h
+++ b/binutils-2.25/gas/config/te-freebsd.h
@@ -1,5 +1,5 @@
/* te-freebsd.h -- FreeBSD target environment declarations.
- Copyright 2000, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-generic.h b/binutils-2.25/gas/config/te-generic.h
index 0f561995..9427d585 100644
--- a/binutils-2.25/gas/config/te-generic.h
+++ b/binutils-2.25/gas/config/te-generic.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-gnu.h b/binutils-2.25/gas/config/te-gnu.h
index 8f41d260..0ea31fa8 100644
--- a/binutils-2.25/gas/config/te-gnu.h
+++ b/binutils-2.25/gas/config/te-gnu.h
@@ -1,4 +1,4 @@
-/* Copyright 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-go32.h b/binutils-2.25/gas/config/te-go32.h
index 58553b5d..70a59fc4 100644
--- a/binutils-2.25/gas/config/te-go32.h
+++ b/binutils-2.25/gas/config/te-go32.h
@@ -1,4 +1,4 @@
-/* Copyright 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-hppa.h b/binutils-2.25/gas/config/te-hppa.h
index 279b855f..5c789782 100644
--- a/binutils-2.25/gas/config/te-hppa.h
+++ b/binutils-2.25/gas/config/te-hppa.h
@@ -1,6 +1,5 @@
/* Machine specific defines for the PA machine
- Copyright 1987, 1991, 1992, 1993, 1995, 2000, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-hppa64.h b/binutils-2.25/gas/config/te-hppa64.h
index 372909fd..519b01aa 100644
--- a/binutils-2.25/gas/config/te-hppa64.h
+++ b/binutils-2.25/gas/config/te-hppa64.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-hppalinux64.h b/binutils-2.25/gas/config/te-hppalinux64.h
index 233263f1..a98b041f 100644
--- a/binutils-2.25/gas/config/te-hppalinux64.h
+++ b/binutils-2.25/gas/config/te-hppalinux64.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-hpux.h b/binutils-2.25/gas/config/te-hpux.h
index f228ba2e..67cd30b4 100644
--- a/binutils-2.25/gas/config/te-hpux.h
+++ b/binutils-2.25/gas/config/te-hpux.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-i386aix.h b/binutils-2.25/gas/config/te-i386aix.h
index 2b174a90..79e3cc8d 100644
--- a/binutils-2.25/gas/config/te-i386aix.h
+++ b/binutils-2.25/gas/config/te-i386aix.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-ia64aix.h b/binutils-2.25/gas/config/te-ia64aix.h
index ebff4601..63768a3c 100644
--- a/binutils-2.25/gas/config/te-ia64aix.h
+++ b/binutils-2.25/gas/config/te-ia64aix.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-interix.h b/binutils-2.25/gas/config/te-interix.h
index 3f552215..a3489215 100644
--- a/binutils-2.25/gas/config/te-interix.h
+++ b/binutils-2.25/gas/config/te-interix.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-irix.h b/binutils-2.25/gas/config/te-irix.h
index c6942167..ed81905a 100644
--- a/binutils-2.25/gas/config/te-irix.h
+++ b/binutils-2.25/gas/config/te-irix.h
@@ -1,5 +1,5 @@
/* IRIX targets
- Copyright 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-linux.h b/binutils-2.25/gas/config/te-linux.h
index 9a83aab9..466f664f 100644
--- a/binutils-2.25/gas/config/te-linux.h
+++ b/binutils-2.25/gas/config/te-linux.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-lynx.h b/binutils-2.25/gas/config/te-lynx.h
index 4c2c7471..336d1b0c 100644
--- a/binutils-2.25/gas/config/te-lynx.h
+++ b/binutils-2.25/gas/config/te-lynx.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-mach.h b/binutils-2.25/gas/config/te-mach.h
index f76f8843..77f873d8 100644
--- a/binutils-2.25/gas/config/te-mach.h
+++ b/binutils-2.25/gas/config/te-mach.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-macos.h b/binutils-2.25/gas/config/te-macos.h
index 51b25c45..336444cd 100644
--- a/binutils-2.25/gas/config/te-macos.h
+++ b/binutils-2.25/gas/config/te-macos.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-nacl.h b/binutils-2.25/gas/config/te-nacl.h
index d64a44d1..2547f9f9 100644
--- a/binutils-2.25/gas/config/te-nacl.h
+++ b/binutils-2.25/gas/config/te-nacl.h
@@ -1,4 +1,4 @@
-/* Copyright 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2012-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-nbsd.h b/binutils-2.25/gas/config/te-nbsd.h
index ce291014..42492912 100644
--- a/binutils-2.25/gas/config/te-nbsd.h
+++ b/binutils-2.25/gas/config/te-nbsd.h
@@ -1,6 +1,5 @@
/* te-nbsd.h -- NetBSD target environment declarations.
- Copyright 1987, 1990, 1991, 1992, 1994, 1998, 2000, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-nbsd532.h b/binutils-2.25/gas/config/te-nbsd532.h
index e22b6a77..79524836 100644
--- a/binutils-2.25/gas/config/te-nbsd532.h
+++ b/binutils-2.25/gas/config/te-nbsd532.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-netware.h b/binutils-2.25/gas/config/te-netware.h
index 61c9bd5e..9fc5928f 100644
--- a/binutils-2.25/gas/config/te-netware.h
+++ b/binutils-2.25/gas/config/te-netware.h
@@ -1,5 +1,5 @@
/* te-netware.h -- NetWare target environment declarations.
- Copyright 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-pc532mach.h b/binutils-2.25/gas/config/te-pc532mach.h
index 0639defc..4241c5ab 100644
--- a/binutils-2.25/gas/config/te-pc532mach.h
+++ b/binutils-2.25/gas/config/te-pc532mach.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-pe.h b/binutils-2.25/gas/config/te-pe.h
index 1ac632cb..a6b857de 100644
--- a/binutils-2.25/gas/config/te-pe.h
+++ b/binutils-2.25/gas/config/te-pe.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-pep.h b/binutils-2.25/gas/config/te-pep.h
index abc305ed..2995761e 100644
--- a/binutils-2.25/gas/config/te-pep.h
+++ b/binutils-2.25/gas/config/te-pep.h
@@ -1,4 +1,4 @@
-/* Copyright 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-psos.h b/binutils-2.25/gas/config/te-psos.h
index a61e261a..e6e2d971 100644
--- a/binutils-2.25/gas/config/te-psos.h
+++ b/binutils-2.25/gas/config/te-psos.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-riscix.h b/binutils-2.25/gas/config/te-riscix.h
index dcd87e51..9fa9f85d 100644
--- a/binutils-2.25/gas/config/te-riscix.h
+++ b/binutils-2.25/gas/config/te-riscix.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-solaris.h b/binutils-2.25/gas/config/te-solaris.h
index 9c628c2f..38659993 100644
--- a/binutils-2.25/gas/config/te-solaris.h
+++ b/binutils-2.25/gas/config/te-solaris.h
@@ -1,4 +1,4 @@
-/* Copyright 2008, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-sparcaout.h b/binutils-2.25/gas/config/te-sparcaout.h
index 3c6c76fe..55026506 100644
--- a/binutils-2.25/gas/config/te-sparcaout.h
+++ b/binutils-2.25/gas/config/te-sparcaout.h
@@ -1,5 +1,5 @@
/* te-sparcaout.h -- embedded sparc-aout target environment declarations.
- Copyright 1996, 2000, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-sun3.h b/binutils-2.25/gas/config/te-sun3.h
index d7dd6371..7138e224 100644
--- a/binutils-2.25/gas/config/te-sun3.h
+++ b/binutils-2.25/gas/config/te-sun3.h
@@ -1,6 +1,5 @@
/* te-sun3.h -- Sun-3 target environment declarations.
- Copyright 1987, 1990, 1991, 1992, 2000, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-svr4.h b/binutils-2.25/gas/config/te-svr4.h
index a33304ae..f989a9d5 100644
--- a/binutils-2.25/gas/config/te-svr4.h
+++ b/binutils-2.25/gas/config/te-svr4.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-symbian.h b/binutils-2.25/gas/config/te-symbian.h
index 02a4e102..4b52b227 100644
--- a/binutils-2.25/gas/config/te-symbian.h
+++ b/binutils-2.25/gas/config/te-symbian.h
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-tmips.h b/binutils-2.25/gas/config/te-tmips.h
index e7ab8cc7..ce5dbda5 100644
--- a/binutils-2.25/gas/config/te-tmips.h
+++ b/binutils-2.25/gas/config/te-tmips.h
@@ -1,5 +1,5 @@
/* Traditional MIPS targets
- Copyright 2000, 2003, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-uclinux.h b/binutils-2.25/gas/config/te-uclinux.h
index 4a5d879e..bb0ead0a 100644
--- a/binutils-2.25/gas/config/te-uclinux.h
+++ b/binutils-2.25/gas/config/te-uclinux.h
@@ -1,4 +1,4 @@
-/* Copyright 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-vms.c b/binutils-2.25/gas/config/te-vms.c
index 42f965ae..8bb15c5d 100644
--- a/binutils-2.25/gas/config/te-vms.c
+++ b/binutils-2.25/gas/config/te-vms.c
@@ -1,5 +1,5 @@
/* te-vms.c -- Utilities for VMS.
- Copyright 2009 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Written by Douglas B Rupp <rupp@gnat.com>
diff --git a/binutils-2.25/gas/config/te-vms.h b/binutils-2.25/gas/config/te-vms.h
index 0c3a1940..34012e1b 100644
--- a/binutils-2.25/gas/config/te-vms.h
+++ b/binutils-2.25/gas/config/te-vms.h
@@ -1,4 +1,4 @@
-/* Copyright 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-vxworks.h b/binutils-2.25/gas/config/te-vxworks.h
index 8c7d505a..e22b1a3b 100644
--- a/binutils-2.25/gas/config/te-vxworks.h
+++ b/binutils-2.25/gas/config/te-vxworks.h
@@ -1,6 +1,5 @@
/* te-vxworks.h -- VxWorks target environment declarations.
- Copyright 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/te-wince-pe.h b/binutils-2.25/gas/config/te-wince-pe.h
index fc41c008..a2049ba0 100644
--- a/binutils-2.25/gas/config/te-wince-pe.h
+++ b/binutils-2.25/gas/config/te-wince-pe.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/vax-inst.h b/binutils-2.25/gas/config/vax-inst.h
index 4f4f961a..c6ce1023 100644
--- a/binutils-2.25/gas/config/vax-inst.h
+++ b/binutils-2.25/gas/config/vax-inst.h
@@ -1,6 +1,5 @@
/* vax-inst.h - GNU - Part of vax.c
- Copyright 1987, 1992, 1995, 2000, 2002, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/xtensa-istack.h b/binutils-2.25/gas/config/xtensa-istack.h
index 75b56b2d..d9aee8f2 100644
--- a/binutils-2.25/gas/config/xtensa-istack.h
+++ b/binutils-2.25/gas/config/xtensa-istack.h
@@ -1,6 +1,5 @@
/* Declarations for stacks of tokenized Xtensa instructions.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/xtensa-relax.c b/binutils-2.25/gas/config/xtensa-relax.c
index 681369e5..df8a55af 100644
--- a/binutils-2.25/gas/config/xtensa-relax.c
+++ b/binutils-2.25/gas/config/xtensa-relax.c
@@ -1,6 +1,5 @@
/* Table of relaxations for Xtensa assembly.
- Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
diff --git a/binutils-2.25/gas/config/xtensa-relax.h b/binutils-2.25/gas/config/xtensa-relax.h
index 4c56166c..ba079394 100644
--- a/binutils-2.25/gas/config/xtensa-relax.h
+++ b/binutils-2.25/gas/config/xtensa-relax.h
@@ -1,5 +1,5 @@
/* Table of relaxations for Xtensa assembly.
- Copyright 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.